QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8669|回复: 0
打印 上一主题 下一主题

Lu基于系统内置对象创建扩展数据类型,小矩阵乘效率测试

[复制链接]
字体大小: 正常 放大
forcal 实名认证       

45

主题

3

听众

282

积分

升级  91%

  • TA的每日心情
    难过
    2012-8-27 18:22
  • 签到天数: 1 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
    发表于 2011-10-23 09:37 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
        本例中,我们将基于系统内置实数数组创建矩阵(matrix)类型,即:基本类型为luDynData_realarray(标识实数数组),扩展类型为matrix(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。
    4 `, {% j2 g% O4 O2 j4 ]6 L5 w
        基本要点:
    # Z) o+ S8 d' |( k- m3 u# }" b% [" `( t" q( B
        (1)为扩展类型matrix编写运算符重载函数OpMatrix。+ l6 U+ \! r! C

    / a0 U4 t9 j5 X; N* {* X    (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。8 p  Y6 v  l+ P5 g1 a

    0 \, r9 k: B: B) ^1 D- n" E    (3)为扩展类型matrix编写其他操作函数(本例未提供)。& W7 O/ G1 `" {4 K; s
    ! n8 V$ I% H. n  B* H+ [& ^6 y+ s
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>. u8 t% w; Z: F2 }* q7 \: H
    2. #include <iostream>6 c3 H* p/ _* U0 d2 L+ ~
    3. #include <math.h>8 i/ J7 w! k# [3 E$ ]: P$ V
    4. #include "lu32.h"4 M7 T6 F6 R- ?+ X
    5. ) v% T/ z7 p# F
    6. #pragma comment( lib, "lu32.lib" )& o/ l  b$ G6 X! l0 }- O1 _
    7. ( \& E1 E0 w1 l/ D* n
    8. using namespace std;) u; ^- M6 P8 E) W
    9.   P( P$ a; {+ V7 B
    10. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定: Y; [2 m2 x+ Q

    11. 7 B/ j3 k. V4 ~: u* D
    12. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用
    13. - h. e4 S7 ?% a3 M- Y0 @\\" v7 m
    14. {
    15. ( Y5 p/ p  Z' Y# q( e5 i( ?
    16.         wcout<<pch;
    17. / v' V9 r. E1 H' i% i
    18. }
    19. ( D' r9 s8 h7 n% M) G
    20. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做; g+ g! s* l6 M  A; b
    21. {9 V' F/ i# e! o) J\\" |
    22. }
    23. ' ^. t$ f% {0 m8 M/ I% D
    24. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数
    25. 2 C' W! k  f4 L4 F
    26. {
    27. ) j- K, b% M3 r* z: G1 U  r
    28.         LuData a;
    29. ' ?  w  C, Q) }. b
    30.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;0 `. @3 E, \  ?4 B
    31.         luVOID i,j,k,m,n,u,v;# {' |5 `7 k$ {; h8 s0 g/ S7 U6 g
    32.         double *pa,*pb,*pc;' m+ t: K/ O' s  t/ J, J* a
    33.         luMessage pMessage;4 a, `6 Q* T& X7 R
    34.         wchar_t wchNum[32];
    35. 0 S7 f1 H  C* Q6 j) D
    36.         char chNum[32];+ D9 }# U$ [$ ^7 b2 U0 F( L: e
    37.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;
    38. 0 ?3 B9 \& e; }/ \5 D( r
    39.         switch(theOperator)
    40. ) N$ J* L& |, Y9 O( D, j% i. D
    41.         {
    42. 7 ~0 c/ @. F0 E9 p# Q5 {1 t! M\\" H
    43.         case 2:        //重载运算符*
    44. : T, j  F3 ]: n: s6 v3 d) x
    45.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    46. & k7 D$ J2 c0 Y7 V
    47.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    48. 6 ]' j1 B4 C4 X& y& ^# S
    49.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组) i$ D5 T6 i: h+ d* d8 l
    50.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵): h6 q( y! i1 P3 f
    51.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配
    52. - t$ [! J, }3 ^* D7 Q\\" e5 V, g* e
    53.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象7 o, g6 d; @- E
    54.                 if(!pRealArray3) break;: b# }* Y+ x5 r# q, }, `
    55.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小\\" w# t2 J0 \2 L$ }! Q0 X
    56.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;, b, e# M7 h1 z2 D+ y/ }
    57.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];. U7 r! |: U) n
    58.                 for(i=0; i<m; i++)        //矩阵乘
    59. ( Z6 ]2 ~! u% C: X
    60.                 {+ z' b7 T8 f, N
    61.                         for(j=0; j<k; j++)
    62. # t. S8 f# \% p2 t1 e5 t2 f
    63.                         {
    64. 2 n# x# _: m! Q
    65.                                 u=i*k+j; pc[u]=0.0;: I  C9 C! \) J& k- k& @
    66.                                 for (v=0; v<n; v++)
    67. 5 `* [. f% S4 S3 w: D
    68.                                 {
    69. 2 T' H1 R8 \6 S# Q$ @! m
    70.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];
    71.   }0 Z1 o) H  \$ Z/ v+ C* d
    72.                                 }
    73. 2 V& _- g. U9 ^; P  ?. r: Z0 Y  L( M
    74.                         }: Y* K6 g0 f: `\\" ~# I- C
    75.                 }
    76. 0 v$ H# S6 o# p7 `\\" g/ R/ R( i
    77.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象, y2 T/ a/ K  C* t; ~/ V\\" _) i
    78.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    79. 1 C. W\\" }! p\\" Z: w
    80.                 break;
    81. 7 ^2 E5 R  r% L) b0 {4 [9 a
    82.         case 25:        //重载运算符.*1 Q: z$ }9 C$ e9 g8 y# U. Z\\" r% x, Q
    83.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);+ H9 ]) ?\\" I7 A9 e( D0 D
    84.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);) n: ]8 L* ?* \) V) m4 n
    85.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组: ?6 g7 J* S$ e/ W
    86.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵). e& F, H; o+ N! h# N
    87.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同
    88. # ~/ X# v3 j3 o
    89.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象
    90. ' L5 @0 p& ~: p
    91.                 if(!pRealArray3) break;; J) [: }2 x6 P! j+ {1 j
    92.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小# M6 l' a- Y5 S3 Y- e2 s
    93.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘; |0 a9 }9 z9 P. x+ E7 W\\" j3 G
    94.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    95. # v0 c: z# _0 V% }5 v$ D
    96.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    97. 3 P, L! v( W# S+ P) v3 W- M
    98.                 break;
    99. 6 d) X& Y5 {( E* t  o
    100.         case 46:        //重载函数new8 I1 m' J1 K* L# }
    101.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数
    102. 9 k* p5 G. T2 Z' j( \
    103.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型
    104. 6 W8 d) x6 r% {+ ~$ C6 U
    105.                 break;
    106. , {% V8 c( N( J: v& c
    107.         case 49:        //重载函数o
    108. ) s9 {! j# @4 ^6 r3 i
    109.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);+ P: h7 {3 z+ A, x: }
    110.                 if(!pMessage) break;
    111. % p2 N/ [+ v! T1 P\\" P% i, p$ x2 R$ p
    112.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);3 n; T* ?  p! f( P  q/ v9 ?7 v
    113.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组) m+ a) b$ P, E
    114.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)* `1 A+ U% a, k( g
    115.                 pa=pRealArray1->Array;
    116. ( _* T: y5 b7 r
    117.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;& w/ @/ u! y. Z9 C+ [2 J$ r2 `
    118.                 for(i=0; i<m; i++)        //输出矩阵
    119. * S0 g3 A  h$ q' g/ ]& [; ~
    120.                 {
    121. ; B, l4 U8 q* X- L7 F+ W\\" a
    122.                         pMessage(L"\r\n"); k+=2;5 r& Q, w1 n4 m; `
    123.                         for(j=0; j<n; j++)
    124. * N1 A! T* `) B  t
    125.                         {
    126. + R% d: B7 t) H, ~
    127.                                 _gcvt_s(chNum,pa[i*n+j],16);
    128. & B4 r+ j% L$ L* i1 Y\\" R1 Q8 s/ z
    129.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}. x+ z3 o/ q: S+ W2 X' `; U3 Y; C+ g
    130.                                 wchNum[u]='\0';
    131. 7 Y' J  ?: ?- T  b* X
    132.                                 pMessage(wchNum); pMessage(L"  "); k+=2;
    133. + d5 a3 M9 p  Q. [0 Q
    134.                         }# J/ l( L1 N* i, w) _2 b
    135.                 }
    136. 6 D# y: v/ ]5 y% k1 u0 e6 i& ?/ `% P
    137.                 pMessage(L"\r\n"); k+=2;
    138. & ?3 H\\" v4 @) h' t% m
    139.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数
    140. : ?! [4 [% h) l5 T# A
    141.                 break;. K2 q$ N2 z. ?/ @5 k/ Q3 D
    142.         default:1 h+ f1 n4 ^5 \! [) v
    143.                 break;+ j  Q; t9 _2 ?- h
    144.         }
    145. 0 K* v- q7 ^' P# o! w
    146.         return a;
    147. , c; ?) h2 g4 I) H
    148. }- z& v: u; v9 p0 R
    149. void main(void)# c: t/ `% [9 F
    150. {
    151. . D2 q( J+ B& s+ Q/ u7 l
    152.         void *hFor;                //表达式句柄
    153. 8 ?+ {/ C$ C. r8 n: j) g# l. N5 g, v
    154.         luINT nPara;                //存放表达式的自变量个数
    155. 0 g# O; k/ h6 ?6 }3 b
    156.         LuData *pPara;                //存放输入自变量的数组指针3 {& b' o& X9 x' B2 w
    157.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    158. # y& n1 o1 ^0 \
    159.         int ErrCode;                //错误代码
    160. 7 J3 f* P2 z# v- w. r
    161.         void *v;9 Q& c% P( Z9 ?
    162.         wchar_t ForStr[]=L"o{new[matrix,2,3,data: 0.,1.,2.;3.,4.,5.]*new[matrix,3,2,data: 1.,2.;3.,4.;5.,6.]}";//字符串表达式,矩阵乘7 J6 ~% X; C8 W) _
    163.         //wchar_t ForStr[]=L"o{new[matrix,2,3,data: 0.,1.,2.;3.,4.,5.].*new[matrix,2,3,data: 1.,2.,3.;4.,5.,6.]}";//字符串表达式,矩阵点乘
    164. 9 Z/ H0 M' _7 N\\" O1 c
    165.         LuData Val;3 Q' ^8 ?, ]% q
    166.         if(!InitLu()) return;        //初始化Lu
    167. 3 W8 ~$ W\\" U- O8 C) p* C( d& A1 @
    168.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型
    169. * w8 f. R5 \0 h  W

    170. 3 U# p& t& l$ e9 T
    171.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量
    172. ! x  B. x* T' F0 r7 u
    173.         SetConst(L"matrix",&Val);        //设置整数常量
    174. ; \8 \( p5 ~+ ^3 [
    175.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息
    176. ( F' F# B) V, i
    177.         wcout.imbue(locale("chs"));        //设置输出的locale为中文% n4 ~' _% U4 o4 g5 [! o\\" s\\" K
    178.   ' Q  s& ^# {6 Y
    179.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式4 C; i6 ^7 E8 L3 V- r
    180.         if(ErrCode)
    181. 9 }) M3 r7 }. ~6 A  ?: d7 C
    182.         {
    183. - M) Q1 m9 O) m( v4 b; N, w
    184.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;
    185. 0 y) |2 K8 O2 A2 w
    186.         }
    187. 8 J' I0 F. N; G3 F: w
    188.         else8 x* t4 X' W, U5 h. V
    189.         {
    190. & o- o/ _9 M& X
    191.                 LuCal(hFor,pPara);        //计算表达式的值
    192. . L& ]( L7 Y5 L9 x- \
    193.         }
    194. 0 i. Y8 p; C% q9 E( [) t1 V
    195.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用& D2 r2 \8 `* e: Q& |1 s! [! ^) _
    196.         FreeLu();                        //释放Lu
    197. * ^$ K7 f! Y. W, u\\" _
    198. }
    习题:& Z) i$ m4 R  a& {
    " m- ~5 Y; b" r# M0 Z6 U
        (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。 ; |% e7 V' \4 h5 w3 R6 z2 w
    % Z* |0 k, l! {# ]* D
        (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=0 e4 H/ m4 T# O\" n, U
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],
      ( a: ]8 G( Y. ?3 }, M0 O# T# v
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],9 j( ?/ _2 j% p/ l
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],
      + ]. L% e7 q: I( y1 E9 H, Q
    5.     t=clock(),$ p% o9 `  b! B1 G# w( @: r
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},/ p( ~8 g. ]% }* {
    7.     o{d, "time=",[clock()-t]/1000.," seconds.\r\n"}
    复制代码
    C/C++中的字符串定义为:
    1. wchar_t ForStr[]=L"main(:a,b,c,d,t,i)= a=new[matrix,2,2,data:1.1,2.,2.,1.], b=new[matrix,2,2,data:2.,1.,1.,2.], c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.], t=clock(), d=a*b, i=0, while{i<1000000, d=d*c*b, i++}, o{d, \"time=\",[clock()-t]/1000.,\" seconds.\r\n\"}";//字符串表达式
    复制代码
    结果:
    1. 4. 5.
      $ D7 l3 {2 \  [* N. U1 T8 F
    2. 5. 4.
      8 q# D: e1 H; R& u7 B
    3. time=0.875 seconds.& T\" g% [. a( Q+ q\" @
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];
      ' ?9 G. x6 Y  |& Z8 u( G\" V% S
    2. b=[2.,1.;1.,2.];
      0 {! s. F) F$ R- X
    3. c=[2/3.,-1/3.;-1/3.,2/3.];7 U\" }& j2 G* z( f2 Z
    4. tic,. X! V\" c- d1 G1 V; }8 C
    5. d=a*b;
      ! w. S4 z0 r- q; w; l
    6. for i=1:10000004 ]& `6 s: h1 e6 G$ B
    7.     d=d*c*b;' F9 b; @: b; L5 Q% m- `) F) ^7 m
    8. end
      9 O) W\" T( d' [  j$ d
    9. d,$ I& N# @% J& x8 l* N\" F5 h4 E' j
    10. toc
    复制代码
    结果:
    1. d =- }- Z3 W6 z) L  _
    2.      4     50 o' Y9 m# |& Y. t\" K
    3.      5     4
      1 ]' _* D+ V; V& Z
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。- k) n- ^: w# e( K5 u
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-9 20:28 , Processed in 0.549568 second(s), 51 queries .

    回顶部