QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8312|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。/ {& ]" l4 a# _3 p% e

    $ k, A9 n* y- u% Z    基本要点:6 x! g1 K& I& t0 \: P& p# V
    * w$ g, ?: _1 P2 }+ u
        (1)为扩展类型matrix编写运算符重载函数OpMatrix。
    ' M, ~& E- }  `/ a) F' E/ d* j" ~" {$ S% j$ U! T8 u& B/ U
        (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。* n7 b3 ~. Z3 N6 J8 z

    : o5 L9 B/ s9 r. k6 @    (3)为扩展类型matrix编写其他操作函数(本例未提供)。+ h! j) L; Z  X# Z1 t8 e& g+ l
    # D$ ]( T+ N1 c& C( j5 g
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>! b% k' w\\" D  I4 D9 B
    2. #include <iostream>+ j\\" I6 D4 {\\" J# Q2 Q: u3 G
    3. #include <math.h>) x6 s2 P; |9 E- x8 c3 z3 L/ }
    4. #include "lu32.h"
    5. / l: w& f* O! C. F

    6. ' t+ e\\" l. j3 d& |
    7. #pragma comment( lib, "lu32.lib" )$ @9 W1 b# T2 `7 V

    8. 5 R: b2 D9 F/ w* Z* j3 B, ?
    9. using namespace std;( @3 m5 R8 y  I* v

    10. . W, Q$ [  Q( V
    11. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定
    12. 8 g8 O9 K, ]9 I6 A8 x3 A

    13. : Q) F& G& E7 J' R' a
    14. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用
    15. / A4 ?8 b$ }, t5 h* v% n, K
    16. {
    17. , j  j3 i9 |* j$ S
    18.         wcout<<pch;$ z) K7 A\\" P9 I+ u* w% F: M
    19. }
    20.   K* o\\" F# P$ m* q( @, x
    21. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做  ^6 m, r6 W$ d  z: }8 n
    22. {2 d( u- I( \( W( ^! D
    23. }
    24. 3 E2 q- s/ J4 ~, s' k' H
    25. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数
    26. 4 M7 A: ~\\" o* \& e) B
    27. {
    28. ; a% m- m% W  F0 T* ]- I
    29.         LuData a;& D) F3 a% T; X2 U5 D9 i% B
    30.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;( w/ d2 g- \, S- ]5 Y
    31.         luVOID i,j,k,m,n,u,v;; N. ^' F\\" L( L5 u
    32.         double *pa,*pb,*pc;
    33. / i' e( D( z/ l\\" ~8 @
    34.         luMessage pMessage;
    35. 5 j; P; k+ P' r+ y: V9 J
    36.         wchar_t wchNum[32];
    37. + r5 Y, c2 e) F( @- Q( W/ E) L
    38.         char chNum[32];
    39. ! z/ D: ]* N% K7 J: W+ W, t
    40.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;
    41. 1 [5 G  Z2 m$ ]7 N+ K0 J. P
    42.         switch(theOperator)
    43. ; L0 ^! j2 `4 g: R$ S$ k! X
    44.         {
    45. ! y  k0 V; P5 ]7 H* g$ }! o6 z& K
    46.         case 2:        //重载运算符*- L9 j$ v+ H2 l7 t; A
    47.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);1 _. q1 u& Z' Y
    48.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);& Q; l; e/ |' c
    49.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组* L! c$ y/ O3 ?+ Z
    50.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵). Q- v* T& l0 J; @+ V3 i  I- J  n
    51.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配
    52. % ]: V% o: L- x* H& j$ b
    53.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象
    54. \\" u) t% E4 f1 w
    55.                 if(!pRealArray3) break;2 ], X  h, G# W+ A- b: O$ b
    56.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小& [# }4 J) `0 j
    57.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;
    58. - v) ?& Z7 g3 b/ C+ L: y2 p* }5 T
    59.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];
    60. ; v0 P2 V& ~7 |3 s7 M3 q% I
    61.                 for(i=0; i<m; i++)        //矩阵乘  x, o* \) H8 \& E: N) u% w/ e
    62.                 {
    63. ; M( }0 t\\" f, \( O  \
    64.                         for(j=0; j<k; j++)
    65.   ?! l\\" V* i# e& j) p6 ]) Y4 x
    66.                         {
    67. $ k9 a8 C% ~' d/ `+ A1 i
    68.                                 u=i*k+j; pc[u]=0.0;
    69. + r2 ]8 y/ v5 ]( i\\" D5 k
    70.                                 for (v=0; v<n; v++)4 e4 g  y+ V7 m8 R  X3 _8 q9 c
    71.                                 {& N) K$ Q; d+ x* m! b+ O8 W* w
    72.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];
    73. 2 v5 s: U) P* C. e& e
    74.                                 }
    75. # U  }9 U- S- r$ P2 B0 G\\" k
    76.                         }
    77. 4 N) T5 Y# S$ }+ |8 {
    78.                 }2 v9 q* H/ j9 ~4 k6 D6 |
    79.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象# O' ]. I/ O  G2 h% q' b/ i
    80.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    81. 4 T+ F1 B$ g0 {# O, J
    82.                 break;& L! d9 j) w1 k\\" ^$ I$ `
    83.         case 25:        //重载运算符.*
    84. ' Z1 T9 `7 x2 |
    85.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);0 x8 k5 K& B/ c6 ]) ]
    86.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    87. - v# N$ X+ d6 L5 A) z
    88.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组0 P+ y6 u% Y: m! n+ g
    89.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵), E/ c. L9 h5 A
    90.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同9 F4 O1 O( G3 `9 t, q5 o1 V
    91.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象6 w, l+ Q+ u4 E2 y; O+ e+ P5 z$ C
    92.                 if(!pRealArray3) break;
    93. 3 W! D. B3 [% F0 D2 ~
    94.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小
    95. 8 y# X6 w5 }7 j5 y6 O
    96.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘
    97. 6 G6 o' X' W+ x. n0 M
    98.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    99. ) [& U; s4 C+ _; r* }* P) i3 r
    100.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;  h! v0 v% o1 e# i! K; g3 X. p: b
    101.                 break;
    102. / I5 ^0 Y! ~; p: X: g% d; W; z
    103.         case 46:        //重载函数new% R7 w5 }1 r: G7 B( O
    104.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数+ b% m. W. |$ K. i1 o! R
    105.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型
    106. 6 I% |# ^$ Y! r' c
    107.                 break;7 w/ r  C, x2 G# `2 K- C
    108.         case 49:        //重载函数o, ^3 e( r5 F. J
    109.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);. X4 F; p3 E- [9 [# p8 P0 w9 @7 i
    110.                 if(!pMessage) break;; W3 {7 }. D4 R) K- K
    111.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    112. ) [# i4 W5 S! t+ v/ f
    113.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组; f2 m; p2 f# E0 @' ]& m; K0 b, x
    114.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)
    115. 0 `4 g8 `  g! |/ r! Y\\" D
    116.                 pa=pRealArray1->Array;$ W  J& W, M8 ?
    117.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;$ F' E1 G9 D- t, {- x/ `  Y+ U
    118.                 for(i=0; i<m; i++)        //输出矩阵
    119.   T+ y2 }/ P5 v$ h
    120.                 {
    121. 0 @+ r& b. A2 A9 _, X
    122.                         pMessage(L"\r\n"); k+=2;; |* M7 ^7 j3 d* Y- h
    123.                         for(j=0; j<n; j++)& s( u; J7 T3 D
    124.                         {9 u  H' [0 Y7 R% C- E8 l\\" ^3 _& r' T: o# ]
    125.                                 _gcvt_s(chNum,pa[i*n+j],16);
    126. / G/ P4 t: ?& _& o
    127.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}
    128. + b\\" x( a4 K1 f8 r- s  H
    129.                                 wchNum[u]='\0';
    130. \\" Y0 w* K% _( U, L1 d# V9 H
    131.                                 pMessage(wchNum); pMessage(L"  "); k+=2;\\" z7 o: Y9 F5 t
    132.                         }
    133. ( a% _# a% _+ B* c7 W3 K
    134.                 }) h8 f8 a3 @, Y  N; v1 V! ^0 `$ U- _
    135.                 pMessage(L"\r\n"); k+=2;4 Z  S/ f' {6 O  K
    136.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数- _0 K6 O3 \6 o0 q
    137.                 break;
    138. , J* b/ w* S6 K& Q: z6 q
    139.         default:/ x% F, o. `9 l* M  K+ A
    140.                 break;\\" n+ x# |& V- M\\" U8 ~: X4 k
    141.         }; I5 j# O4 Y( ~4 A) g
    142.         return a;# [0 p, ^' `3 ]; V
    143. }& x2 [- l/ P4 F, t8 C
    144. void main(void), s. [( \) g5 d. w4 C8 I
    145. {  I7 p; W. e5 r' \! a
    146.         void *hFor;                //表达式句柄, x( M; M: D2 A$ z) ^4 {* x* S\\" W5 o
    147.         luINT nPara;                //存放表达式的自变量个数
    148. ' I1 E9 j5 C7 S# K% C: I
    149.         LuData *pPara;                //存放输入自变量的数组指针0 u4 X; y; E8 T\\" S, k* J
    150.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    151. ; [  P  |' k' r8 I1 q) p
    152.         int ErrCode;                //错误代码
    153. 8 q3 t- Y7 w* I6 h/ \( h
    154.         void *v;
    155.   U7 ?1 B2 W- V/ o
    156.         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.]}";//字符串表达式,矩阵乘
    157. 2 t& H) ^0 U. P! w) ?. U
    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.]}";//字符串表达式,矩阵点乘/ H# A( ]5 L3 [$ ^( S
    159.         LuData Val;
    160. $ y+ q8 x9 B) K/ Y
    161.         if(!InitLu()) return;        //初始化Lu
    162. * q& i  a: a. H
    163.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型% c\\" W; ^4 _! E; h5 k\\" P5 |
    164. 7 ~4 K0 {+ q  g0 q1 H& @- @
    165.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量# Q- X4 |8 W$ ]- Y9 U( \7 j' q
    166.         SetConst(L"matrix",&Val);        //设置整数常量
    167. 4 S0 n! K9 M+ P! h* ?/ m
    168.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息/ l6 o: q% Q9 l+ t
    169.         wcout.imbue(locale("chs"));        //设置输出的locale为中文
    170. 3 O\\" J1 h7 J  O, X7 N
    171.   
    172. 1 a/ _+ P\\" \9 Q* t: c
    173.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式7 \: Y$ s) A% F8 V- C' w2 E- a6 e
    174.         if(ErrCode)! A; ~/ O5 e* i5 r6 _$ g6 F' P  r
    175.         {
    176. 0 @$ ~/ ]\\" x$ X* Y6 O; l
    177.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;! `, A' U$ V1 q) k
    178.         }
    179. 5 W8 U/ O. r1 u3 A
    180.         else% s5 y/ B* o  n8 O
    181.         {
    182. % a9 f\\" h# v: O
    183.                 LuCal(hFor,pPara);        //计算表达式的值( R4 r/ ~, m: [* L; ]. |9 _8 P
    184.         }
    185. ' O& J8 ]! i& Q( a, s% g
    186.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用: `6 y: t$ T- `; D) T/ ?
    187.         FreeLu();                        //释放Lu8 @0 C& U2 F, S7 g; ^
    188. }
    习题:
    # M) d9 j. T4 n8 |& H0 {' b% I% b4 I. }+ s  [3 ^+ u7 B% r
        (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。   |% n* k( m7 T2 c1 @6 c8 Y

    & o, g8 ?2 b* j/ T& d! [6 A    (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=0 O) i0 p/ Y$ ]; A\" `( E0 ~9 m
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],: H5 G% ]3 B; B
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],: h8 s8 P3 @; n0 p
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],# U, n4 F9 ^7 S5 |5 q
    5.     t=clock(),0 `9 w6 {1 z0 n* t  L$ \. P
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},
      ) A- b5 {# {; i
    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.
      8 w% `5 m: @( k9 b0 [
    2. 5. 4.) F# G, y* E0 f( i
    3. time=0.875 seconds.) G, n+ o. E0 b  _8 ]
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];, c' L+ V9 }4 r8 y/ }
    2. b=[2.,1.;1.,2.];1 j' |: r- W8 s9 z( K\" \$ e/ g
    3. c=[2/3.,-1/3.;-1/3.,2/3.];
      2 e* ?' {: G5 X6 a' a3 O
    4. tic,+ t4 d' l2 O2 X: D! t; k/ l\" ^
    5. d=a*b;
      ' I- b0 N8 l) h3 z+ q' k
    6. for i=1:1000000
      + w$ I' e1 Y9 _. N- b3 ?( P( X  f& _) J
    7.     d=d*c*b;
      5 X) l7 D- b- [5 g! m- h4 `
    8. end# r! Y( \+ C& w+ `# G' W' X, u
    9. d,5 p7 ], B( Z9 F' r
    10. toc
    复制代码
    结果:
    1. d =
      / H. \* W& m, C9 D9 d
    2.      4     5
        g. ?7 j8 z1 C
    3.      5     4
      ) R! z7 }$ {7 z2 a+ R$ n
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。, y" `0 b) i2 G. S2 V! q1 S
    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-7-7 18:55 , Processed in 0.328766 second(s), 52 queries .

    回顶部