QQ登录

只需要一步,快速开始

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

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

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

45

主题

3

听众

282

积分

升级  91%

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

    [LV.1]初来乍到

    跳转到指定楼层
    #
    发表于 2011-10-23 09:37 |只看该作者 |正序浏览
    |招呼Ta 关注Ta
        本例中,我们将基于系统内置实数数组创建矩阵(matrix)类型,即:基本类型为luDynData_realarray(标识实数数组),扩展类型为matrix(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。7 w; I+ W1 s& \+ N2 Q; y

    8 v6 l& q  s! _8 ]' G, o( B% m$ A    基本要点:& w% @; |7 G: v3 K! N

    : x9 y- `- r) {3 {    (1)为扩展类型matrix编写运算符重载函数OpMatrix。
    * f) H1 Q( k+ \- s6 e# [% q; z, I4 b6 E: l5 e9 [! w
        (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。
    , r4 i0 g. y& o1 I% t+ x
    + C9 c% U9 m$ C9 g    (3)为扩展类型matrix编写其他操作函数(本例未提供)。0 ]1 o- H  [* I& w5 \- `& i
    * I  Z2 `$ Y3 _& u- V4 S
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>5 ^7 D2 N: k# [2 w
    2. #include <iostream>' I5 X# s! c0 P6 `- |
    3. #include <math.h>
    4. $ b3 v' S5 `* {! N2 S6 v1 I
    5. #include "lu32.h"
    6. 4 ~& C, j) s- D6 L

    7. ( C7 C' L; }\\" x; \2 Q* u0 ?
    8. #pragma comment( lib, "lu32.lib" )5 {  O2 I1 \+ G: j! c+ Z! }
    9. 6 g' |- C& A4 G3 O1 d- Z
    10. using namespace std;* e0 Z\\" o6 A7 \2 K

    11. : n0 _, U9 O0 C, l. r) w8 y6 y
    12. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定
    13. 0 Q. W. ]\\" N: s4 B7 `3 {9 M
    14. 6 I, V% O! g, z
    15. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用 5 A2 X\\" _2 F, L6 N1 q
    16. {\\" U. G$ r5 V/ Y0 Z
    17.         wcout<<pch;0 s8 c& r4 d( i
    18. }
    19. 9 d# W3 E3 J: E; G( ?8 R+ o) b
    20. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做
    21. % K# m7 o2 H& V: a
    22. {
    23. 3 i! a& H3 H5 v
    24. }
    25. / s/ N0 L3 @6 D6 g& l% z  A+ q% `
    26. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数
    27. ! s3 w+ c1 `; x0 W% e1 E5 A5 ?3 P
    28. {( s4 w- v6 d/ a; U- O+ ?1 S7 o  ]) `
    29.         LuData a;
    30. ' f) j, d3 g8 C9 C  \1 }6 Y4 s$ Z
    31.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;
    32. 0 |% T8 l5 J, {8 U! V6 i% j
    33.         luVOID i,j,k,m,n,u,v;
    34. 0 k; |: M7 `3 z9 ~+ S0 N
    35.         double *pa,*pb,*pc;6 K5 P) {% G$ Z+ y. s
    36.         luMessage pMessage;' K' p- q3 n7 D4 k
    37.         wchar_t wchNum[32];
    38. $ D+ y: N5 [& i8 x1 h' g# k, t
    39.         char chNum[32];
    40. , p% C; W7 N, [! N! |. J
    41.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;
    42. ! e3 p/ l+ H/ @; }- X& U, K
    43.         switch(theOperator)3 h! w- V5 {* _3 o) {; m2 T
    44.         {
    45. $ o% Y+ k) A2 T  L
    46.         case 2:        //重载运算符*\\" f# H& ]8 b; w2 k% k3 o% y' V+ k
    47.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);! @8 m! q2 D3 `0 H
    48.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    49. / m) ~! Y/ {8 P2 m! V4 s
    50.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组, G# p& k  H+ M/ a: ?: v) Z
    51.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    52. / B( X8 x4 y2 v. `
    53.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配\\" |! }5 i# z7 z/ n) G
    54.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象! I' g6 M& j. @8 t7 R: |7 x
    55.                 if(!pRealArray3) break;
    56. . L0 Y  k/ L8 r, {5 V. M
    57.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小$ S2 I: q\\" o7 S) u  D
    58.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;
    59. , ~% }# X4 A  j& D# Q7 L# u
    60.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];# t3 Q4 W' F7 L# J
    61.                 for(i=0; i<m; i++)        //矩阵乘! |+ m. N* N/ f6 w
    62.                 {
    63. 6 H9 ]9 V$ V! P( N2 M) {) g
    64.                         for(j=0; j<k; j++)
    65. 4 J1 J5 y) `# |% d' s; Y& m
    66.                         {& r& t5 c. ]+ B\\" i# w
    67.                                 u=i*k+j; pc[u]=0.0;
    68. ( y; F1 Z  q- Y* q
    69.                                 for (v=0; v<n; v++)/ S. \6 Y- `3 R  e
    70.                                 {( A$ f( `/ V: k* Y
    71.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];) a# L* y8 W/ s  f0 v; w+ e
    72.                                 }
    73. ( k. t8 i0 x4 P6 }- Z7 J0 G: K
    74.                         }0 j+ P* _5 y# \8 U6 y0 f
    75.                 }
    76. - M1 N$ ~4 e* h- w) g$ p8 v
    77.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    78. % f4 L: T( {; Z
    79.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;/ z$ \! ~- b* j( b0 L; C
    80.                 break;$ g5 G+ I5 b- p/ d% m
    81.         case 25:        //重载运算符.*
    82. 7 E) J$ C$ Z; n8 u
    83.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);: N0 R) x( @5 n$ X+ r9 ]( ^
    84.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);+ A1 x2 r' r5 ^4 x9 C0 U
    85.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组
    86. 9 O0 ~9 k% f, R! W
    87.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)% }! H1 V* q+ T  S: z
    88.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同
    89. 5 E. i4 U+ P6 V+ _* U- }. P
    90.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象
    91. $ I/ A\\" R5 S: e( q
    92.                 if(!pRealArray3) break;
    93. 7 |1 I, F' ^8 U$ U- H
    94.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小' ~0 q6 C1 x0 P, L+ P
    95.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘
    96. % v9 w2 v* M9 ~
    97.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    98. 4 g. G. H  O# Y4 U2 f3 K
    99.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    100. # `, o( F, l! a7 |/ i, H( h
    101.                 break;1 v\\" L, d4 y8 Y9 R/ P
    102.         case 46:        //重载函数new# o; u) y\\" |3 B6 Y
    103.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数
    104. * M5 ?+ G, ^2 k; K9 Z; t5 r
    105.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型
    106. % c1 [- M5 p6 c; z/ Z; {2 I
    107.                 break;, T- [) q, o& B& ?
    108.         case 49:        //重载函数o- |  N( P9 s/ ?3 _' r0 [0 s' W
    109.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);
    110. $ L: ?# J* E2 H7 r2 v$ }
    111.                 if(!pMessage) break;$ I( l4 L5 x) F% A
    112.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    113. 7 M1 j/ l$ s4 [5 F2 p
    114.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组( d( l4 t; o  S) x7 |
    115.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)3 F6 O( ]  k' C* U; h& s# r& E* K
    116.                 pa=pRealArray1->Array;
    117. : p: z+ e$ k2 g0 a/ i3 u. |
    118.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;
    119. 7 r1 O$ Q+ _/ m* E$ p
    120.                 for(i=0; i<m; i++)        //输出矩阵
    121. 1 a* ^% S: @+ h0 g3 T. V  N  }3 a
    122.                 {, G6 k6 Z% d$ Q) Y) u
    123.                         pMessage(L"\r\n"); k+=2;
    124. - s, s, F. m5 L5 g- K
    125.                         for(j=0; j<n; j++)
    126. ' \' v. ?5 O; S4 M
    127.                         {/ q$ j6 m8 S, i7 f* a
    128.                                 _gcvt_s(chNum,pa[i*n+j],16);( d5 L) L$ F% u/ A' p\\" @) S7 {: P\\" V0 G
    129.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}
    130. 5 a\\" y$ t2 G' E! ?
    131.                                 wchNum[u]='\0';+ b\\" U0 H% s: a! D4 a
    132.                                 pMessage(wchNum); pMessage(L"  "); k+=2;% a* g' `. R$ [
    133.                         }. l8 n! t) K9 X8 b) b! W- ~
    134.                 }2 O/ H4 m4 @3 i/ U9 }) m& c- |4 O7 k
    135.                 pMessage(L"\r\n"); k+=2;& ~( v0 @+ A' A3 E\\" e% D* V
    136.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数6 }\\" W' M0 s9 e
    137.                 break;! w; F5 |9 \\\" c1 P4 H) e4 ~
    138.         default:
    139. * k1 C* |\\" \7 _* _9 I& _$ L7 W
    140.                 break;
    141. 4 I% n1 K2 }/ ]8 @  Z
    142.         }
    143. 8 N( U! a+ Y3 ?\\" e; O& P. f; i
    144.         return a;
    145.   \7 m; C# R) \1 v
    146. }
    147. 8 l8 O; D4 p$ k# _
    148. void main(void)
    149. % c% T) j8 u4 c1 i* S' m, s6 h
    150. {
    151. 6 {\\" j2 d* y) d5 ?6 C$ V
    152.         void *hFor;                //表达式句柄0 \7 \; O3 ]. {2 z: a% n, s
    153.         luINT nPara;                //存放表达式的自变量个数
    154. ' Y8 B: F5 {0 S8 F- E
    155.         LuData *pPara;                //存放输入自变量的数组指针5 k: g% h- C% a- X\\" C
    156.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    157. 9 m+ t1 L1 i0 {$ N\\" [, W3 m6 j
    158.         int ErrCode;                //错误代码% d& |/ Y; H! g) p0 x) B
    159.         void *v;
    160. : A9 _  Z. b5 |* ]( h+ t' Z1 _5 ~
    161.         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.]}";//字符串表达式,矩阵乘/ `* _$ p& ?5 f! N3 }1 z
    162.         //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.]}";//字符串表达式,矩阵点乘
    163. ! |+ M6 U/ l8 ~$ {
    164.         LuData Val;
    165. ( a% c' }/ C* c' A3 ]
    166.         if(!InitLu()) return;        //初始化Lu
    167. % P- [% T/ B2 F) \# b/ Q
    168.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型
    169. 6 C3 y7 |6 @# }( C5 P% @9 E; Z

    170. ) m/ Y* t% o( C' C2 y/ h6 I
    171.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量
    172. ; H5 N. I  `9 V! Y' f* S\\" @
    173.         SetConst(L"matrix",&Val);        //设置整数常量, k$ S+ N7 [* @# \
    174.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息$ @) ]2 @! R7 V
    175.         wcout.imbue(locale("chs"));        //设置输出的locale为中文
    176. % j' ?8 e- _. C! ^! p% d
    177.   
    178. ' g/ K. F6 E. D/ x$ P
    179.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式: k\\" I# y4 k+ J8 @( w; X\\" z; K
    180.         if(ErrCode)9 s' y: f( B2 f7 x- y0 A! S
    181.         {
    182. ) N% F6 d- S' q: v0 @* t- v
    183.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;* C8 S- |7 ]# x' \5 ?; i0 d
    184.         }
    185. 1 N; h- }% `* o  ]( Y, }
    186.         else8 C/ O# j: Z7 c
    187.         {' z, T% ]4 b) N2 u. y/ p
    188.                 LuCal(hFor,pPara);        //计算表达式的值; Z/ n, g* p/ [\\" {- `
    189.         }! u! b+ g6 U3 C, l
    190.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用
    191. 3 B0 ]7 Z, A' c8 m7 S
    192.         FreeLu();                        //释放Lu$ ?& f8 u% i3 F0 U
    193. }
    习题:
    3 y! S% U* c9 C1 C& \, J
    . N1 ~% L* F5 c; q- h    (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。
    ; _( [5 A  c' j! v2 r# d4 k' t# ^" W  j
        (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=
      4 B. J( V+ D( f+ x, C
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],) r; u3 C, W4 N! v6 J) @- a& A% |$ x
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],4 A' C9 z; \3 Z' Y6 q7 `
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],# X3 w5 z  a, ?& g8 ~
    5.     t=clock(),
      # h& M+ V: X( |) b: c
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},
      ( t4 x3 k. b  X. J3 _6 P
    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.- F4 Z4 `# E. z5 L) D/ J) [
    2. 5. 4.
      * ?/ ~  D' @. r7 g9 ?5 d: [$ l: x
    3. time=0.875 seconds.
      6 c4 `8 B( |! X  N8 n7 T+ ]. ^1 c! u
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];3 p9 b4 J7 k# j9 I\" I3 @
    2. b=[2.,1.;1.,2.];2 P% a4 q! k  q8 ~, K
    3. c=[2/3.,-1/3.;-1/3.,2/3.];
      9 r3 e& @: g1 g$ n7 h9 |8 F
    4. tic,
      6 e. O+ `9 |8 t& H- ]1 [
    5. d=a*b;
      . q. V4 o% f0 ^
    6. for i=1:1000000, J7 w9 \2 Q/ `$ }& N8 ~1 h
    7.     d=d*c*b;6 T' W' ~0 q' O* f7 T+ o
    8. end
      1 `$ Q5 }! a9 Q* j' ~- j& Q
    9. d,
      1 i5 @; _2 |; ~, T/ N
    10. toc
    复制代码
    结果:
    1. d =& w$ G8 ]9 o: e7 C+ O  e6 f- N# x
    2.      4     5
      ( j$ B* A\" l& ^& h. P0 E
    3.      5     4
      5 l- ?: u  S' V$ w, G$ Y
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。  w/ @7 E$ Z# ~1 L6 s& F1 \# w
    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, 2024-5-16 03:12 , Processed in 0.311133 second(s), 55 queries .

    回顶部