QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8383|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。
    $ j3 A% f7 m# B2 ~) j$ p% z* h! L" z: |: B$ ^; u; |- p
        基本要点:
    . _% G! u6 [; r2 A7 t& B0 X. J" O6 l) N4 A
        (1)为扩展类型matrix编写运算符重载函数OpMatrix。5 r: P1 J! B  J3 d9 S7 F6 W" a4 J
    . v# l5 G6 R. v5 e2 _6 {' n
        (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。
    ( m0 \  b, {, f4 j# s- j5 U: d- Y, h* U3 H) b: ?' a; B
        (3)为扩展类型matrix编写其他操作函数(本例未提供)。
    : G' |' f0 R& t7 B- k/ O; q6 B6 g- k3 C- L& E
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>\\" O, [6 A5 B% T/ x
    2. #include <iostream>
    3. ; T8 d1 L* |* S. [. f, [* l8 D) A. V
    4. #include <math.h>
    5. * `/ L4 H6 U% w8 s; V
    6. #include "lu32.h"$ |. v5 H+ e% |5 Z! D6 n6 f
    7. , L( `- d/ N: i$ V7 w
    8. #pragma comment( lib, "lu32.lib" )
    9. , `' m( A! Z! @( V# p. Q/ l

    10. . _+ I$ P8 g( y' |0 t
    11. using namespace std;
    12. 8 K5 N+ `4 c$ X2 ~( z

    13. 2 Z# F9 F$ C\\" s6 q& A- e7 \- `
    14. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定
    15. 8 M* b9 _0 h, l( g8 a, u/ P
    16. ( w1 K7 H. o( E' @$ }! y$ `
    17. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用
    18. 6 C/ L' v5 g4 G
    19. {
    20. ; B! @8 g/ V. g: E) q
    21.         wcout<<pch;. B. i$ w# `- [  a
    22. }
    23. 7 z3 D. D5 ]& U\\" y3 s3 f4 Q\\" Y+ R
    24. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做\\" c7 q8 k) D8 a9 h- r( h+ F
    25. {
    26. % Y( g8 X2 Q9 U  l
    27. }4 C6 C' ^3 a) w, \, ]
    28. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数
    29. 1 A, X' |8 m( E
    30. {' i5 L3 Q% D6 w* n; b
    31.         LuData a;% o5 f  Z! H, M5 |
    32.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;! N7 Q/ N. C3 O8 i$ W; r  k3 ?6 p: e
    33.         luVOID i,j,k,m,n,u,v;4 F0 U2 A2 F* v) Q- Q8 d
    34.         double *pa,*pb,*pc;: z, F7 O  I' ~' W. \# o/ w
    35.         luMessage pMessage;
    36.   |  D' p3 I1 d0 u; Y
    37.         wchar_t wchNum[32];
    38. , F* L6 D. o! M, G2 @: W
    39.         char chNum[32];
    40. ! m\\" U7 ~* v. O\\" @9 X7 w
    41.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;6 }* [$ }& r  k. V, k% g
    42.         switch(theOperator)
    43. 8 z\\" _1 ^7 m* d0 P
    44.         {4 E2 B3 H! k% v5 z# X. O, n
    45.         case 2:        //重载运算符*3 e) Z- m/ ^7 _
    46.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);4 v7 [- W3 A3 K% P/ T% X
    47.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);& W; s0 [6 a& ~8 G: Z
    48.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组3 d8 B\\" W' M  p& n/ q7 `! ]+ }
    49.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)7 a5 T6 V; ^3 [8 F0 h! Q  N2 [$ J
    50.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配# j0 n; [\\" V- }3 ]$ H/ F
    51.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象
    52. - \. J% o/ b+ C( m2 L
    53.                 if(!pRealArray3) break;
    54. # T9 l8 g! R; o
    55.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小: \$ E; y* c3 Y( t% V
    56.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;
    57.   |, L/ G. x/ |5 M( Q6 L
    58.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];5 E! G9 n$ i* M' S
    59.                 for(i=0; i<m; i++)        //矩阵乘
    60. & M: Z' [# p6 t& x- _5 v8 h8 q
    61.                 {
    62. 5 y! a$ @; S& M7 }
    63.                         for(j=0; j<k; j++)
    64. & U+ `\\" X0 \' @& I0 m
    65.                         {, ?/ [1 s, s2 ~# e0 y5 i
    66.                                 u=i*k+j; pc[u]=0.0;& u& w5 d2 B$ R6 U6 {1 k, q2 F
    67.                                 for (v=0; v<n; v++)
    68. ; x5 i! V0 z- t& _3 F2 V- U
    69.                                 {- ^, L. J8 f9 T9 |6 s
    70.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];
    71. 3 |- S# Y$ q1 b
    72.                                 }! O; g\\" D, l2 I9 Y: B' ]
    73.                         }- }3 T8 r9 B$ P4 M5 j
    74.                 }
    75. 2 L- w4 ~2 ^0 N
    76.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    77. 0 b. n  X1 Z! ]# l. C! X+ z
    78.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    79. . R* {8 e# E. R* a
    80.                 break;) f0 v7 `/ l9 p
    81.         case 25:        //重载运算符.*8 h$ F* M) \( G- Z& m. m& }
    82.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);$ r; t' x) X1 T
    83.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    84. ; i- y& F9 ]; \$ N' @& d
    85.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组) L$ j) k1 Y3 k- J
    86.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    87. 0 b9 M; D8 o  ]5 L- G  K
    88.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同) e. B  Q5 R; g) K
    89.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象- w( T. R* |# C5 L5 t9 N
    90.                 if(!pRealArray3) break;\\" W% G$ Q$ |! j- z; K; ]
    91.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小
    92. - t' y# h2 ?4 E  [8 {4 J
    93.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘
    94. 7 S) S: p! y# o8 c4 k
    95.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象9 x8 ?9 z; B1 f# X) M
    96.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;6 @/ H' {5 T8 i7 I: h& U5 Z
    97.                 break;
    98. \\" T\\" U- k- }& K' L/ Q
    99.         case 46:        //重载函数new4 C) x# w& Z\\" L0 U0 ]3 t
    100.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数4 q9 ~2 L, u* @! `' O2 S$ y3 ]* g
    101.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型8 o3 \, b$ c0 C  W8 K  P# D- D; G
    102.                 break;
    103. , e% @% x) P. w0 `) ^3 v
    104.         case 49:        //重载函数o% g& y2 N0 J/ s9 v
    105.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);
    106.   ?% p0 v7 [. @2 c% ^5 j7 l4 K' y
    107.                 if(!pMessage) break;$ j3 R* }7 j7 b5 B- g\\" `
    108.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    109. / c2 I+ B$ ?% t! k6 M/ v- W
    110.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组
    111. 4 t3 m* n) T! a9 s) ]; |: ]
    112.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)! L+ h/ m1 ~/ ~% ~  g\\" u3 k0 q
    113.                 pa=pRealArray1->Array;5 T6 K$ A4 @: b7 ~7 l
    114.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;
    115. $ V, D- `+ _1 D
    116.                 for(i=0; i<m; i++)        //输出矩阵
    117. ) r- o2 g2 }4 t3 W, C2 [
    118.                 {
    119. 5 s9 f6 J( B6 a, x& W
    120.                         pMessage(L"\r\n"); k+=2;
    121. 9 Y7 |; p- @3 B\\" v! v- W4 ^3 k/ `
    122.                         for(j=0; j<n; j++)
    123. * y! G, A# V- T) \; w! R( d! J
    124.                         {) ?6 l. \- Y9 X3 s' ^$ |
    125.                                 _gcvt_s(chNum,pa[i*n+j],16);
    126. 7 J- s5 V* b# {$ b2 g6 i
    127.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}
    128. ! z/ W\\" m& b9 ?+ P# ]4 w' b& e/ |
    129.                                 wchNum[u]='\0';
    130. 2 ~7 a! w; T' b7 }; h+ k- u
    131.                                 pMessage(wchNum); pMessage(L"  "); k+=2;0 n* |4 `  {+ g$ t! I2 w0 v
    132.                         }6 y7 ~; w* v. c8 l8 Z3 r
    133.                 }
    134.   K. |8 y  e: R! `, a\\" u# K2 [' b6 I
    135.                 pMessage(L"\r\n"); k+=2;) C+ [# _! H8 Y9 R- d% I) O$ \9 N2 E
    136.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数
    137. 4 z, }2 L% p9 }: L3 w3 R# k# F
    138.                 break;& y9 v- e5 G, F1 v\\" g
    139.         default:5 \- F& i% [, J. m$ y# w
    140.                 break;5 f/ i% y0 w+ w- v. q+ G3 A
    141.         }
    142. 3 ?% w7 a0 ]$ b6 c) s# j( B\\" x* V
    143.         return a;( }! G5 c6 x6 h6 z3 t
    144. }
    145. 6 W\\" d) a5 W+ h
    146. void main(void)/ M  i5 o' D, y* D
    147. {4 r8 ~! Y\\" j. x2 r$ V
    148.         void *hFor;                //表达式句柄2 f, u% ~9 V5 W' l, I
    149.         luINT nPara;                //存放表达式的自变量个数
    150. # |( H3 v7 g, Y9 W
    151.         LuData *pPara;                //存放输入自变量的数组指针. z, ]8 Y. q9 \; {# C. ?% t7 T
    152.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置& y& v) d6 y* \' q0 Z* ]
    153.         int ErrCode;                //错误代码
    154. ' S5 _) N\\" _- t' K; T
    155.         void *v;
    156. 7 N, n6 @4 O& A) J
    157.         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.]}";//字符串表达式,矩阵乘0 }' O/ B; \( D\\" \
    158.         //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.]}";//字符串表达式,矩阵点乘
    159. 8 m6 W6 F% x4 {8 O# Y
    160.         LuData Val;+ ^0 I, R$ J6 H# m4 W% C! V& ?6 ~\\" D# I
    161.         if(!InitLu()) return;        //初始化Lu
    162. ; ]5 O7 K4 n) M& E& i2 |
    163.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型- j5 ?0 D) ]* A2 z  S) i
    164. & d8 x: `6 `0 s1 @
    165.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量
    166. \\" y( Y2 }* m% g$ ^3 E9 D
    167.         SetConst(L"matrix",&Val);        //设置整数常量
    168. ; H  o. s/ P7 X
    169.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息
    170. / P' k' h8 O\\" C
    171.         wcout.imbue(locale("chs"));        //设置输出的locale为中文
    172. * H7 ~' _1 o- v  |
    173.   
    174. $ N, o: k, L) t2 _
    175.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式8 ^/ j* H: l2 X7 c
    176.         if(ErrCode)4 \+ _! M  }3 P4 b
    177.         {6 g& ]$ |/ N5 O6 b1 ^1 D1 u3 m
    178.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;6 {2 d' y' K6 b
    179.         }6 ]+ s: _4 \& M, Q4 G- T
    180.         else% q# [) o! r( ?$ U8 K- A
    181.         {, n) W6 f9 e; L: E+ [
    182.                 LuCal(hFor,pPara);        //计算表达式的值\\" H: z5 I( H; @1 S% v8 l
    183.         }
    184. 1 O8 v: i5 H+ v/ t0 f- z
    185.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用  X8 D5 p6 f! k& k\\" Y+ ~) V5 T; A5 _
    186.         FreeLu();                        //释放Lu4 U; |6 p! K% Z4 H$ o; [6 C
    187. }
    习题:
    4 Q, q/ h$ M4 |: E+ y% C4 {1 l2 f! E- f) C4 H# s* m& }% v+ A& r% X
        (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。 5 M7 J% L8 \7 _1 l, F

    3 X0 G* Q7 K# r# `9 ]5 X    (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=
      ! o/ N7 F0 N  q- I
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],
      & {9 j% h# B6 ]9 u7 ]' c9 ~* o7 t
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],% Q/ L- h. v1 U8 h
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],6 J2 v; r3 Z1 C2 u( t' `! a9 \
    5.     t=clock(),
      ; H+ k3 B* o$ s; @
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},
      / G' f! Q' r$ }
    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./ p% m8 ]# l% u/ m# V4 m
    2. 5. 4.
      9 b! h4 c$ P2 ^7 h% T) N
    3. time=0.875 seconds.  h. H* o5 I$ I& ^
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];
      3 L% I4 S' o5 O/ e5 b
    2. b=[2.,1.;1.,2.];* p. R3 [. b! e
    3. c=[2/3.,-1/3.;-1/3.,2/3.];
      8 ~, z# P, G5 }\" e( S7 Y
    4. tic,
      # u, d5 W9 J$ l5 |6 A  ^8 K7 F
    5. d=a*b;3 `& {3 r) q: P- I% L
    6. for i=1:1000000' I+ i0 O\" t0 Z2 y6 |1 J\" \\" A6 N
    7.     d=d*c*b;
      & G; z, _& g/ i/ k4 D- z\" O5 w
    8. end
      / B( e6 V) V: L\" T* x
    9. d,1 C( N- ~$ ]) N2 S\" G( E7 `
    10. toc
    复制代码
    结果:
    1. d =
      / ?3 ^\" P$ W( S) G* o$ C
    2.      4     5
        I  h0 y% w4 M6 ^( j9 ~( l\" p
    3.      5     4
      & t7 F' ~! d7 q
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。
    6 b' [; W3 q- x. Q& U( K8 D
    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, 2025-8-3 04:10 , Processed in 0.416962 second(s), 52 queries .

    回顶部