QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8819|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。) C/ e8 h+ J. Z2 v

    6 W9 {- O4 C# B: d' k7 A3 L5 m    基本要点:
    $ {" ~: O5 g: q: O( u( _) n/ u2 ?& E" k# a
        (1)为扩展类型matrix编写运算符重载函数OpMatrix。. }1 E0 d8 j  ], ^( d; I
    # a" J- a8 b# G2 h$ a
        (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。) M1 i2 C+ d/ Z0 v; p* F8 [

    ! X2 J# W  L) z* r- i! {    (3)为扩展类型matrix编写其他操作函数(本例未提供)。
    ! E% N% v- H$ r. v- f. D; U2 s. N. [0 _) Z4 I1 {% h
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>% M1 X! W; N# n& f' {
    2. #include <iostream>, W* Z, X; n3 R6 i' n1 k9 I
    3. #include <math.h>
    4. ! y, |1 h! L' Z$ D. f- J6 m0 l
    5. #include "lu32.h"8 A, z/ B( ~* u8 \% p

    6. / I, [' n2 F% X  Q
    7. #pragma comment( lib, "lu32.lib" )
    8. 5 V0 ]7 B0 ]7 }$ I8 a9 a
    9. 9 l* J) J. w/ k6 B& j
    10. using namespace std;
    11. 3 _. n# P6 {1 y! ?4 w

    12.   m5 {# U  U0 A9 d9 d
    13. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定& w5 F) A+ w- j# f/ X+ Z5 b  o
    14. % V% Y; N* a% d
    15. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用
    16. # z5 T8 p8 P+ k9 U) R. M& ]
    17. {8 a3 |0 k/ N6 g# }8 }5 U* Q
    18.         wcout<<pch;
    19. $ ?- H% K! {! o* A8 v
    20. }
    21. , O7 d, R2 d9 w8 ~2 B7 u  }7 `
    22. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做
    23. . D, p+ k( u% Y3 M% x
    24. {) u* {: T/ _1 h7 }3 }, l% h, }! [
    25. }1 T2 V  O8 \; N* t: Y\\" g
    26. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数- |1 H\\" n2 W; o$ s1 d9 _+ I
    27. {# v7 Z: O# E- K, i& j
    28.         LuData a;
    29. - e$ g' j9 E8 ~6 z: [0 u9 ]* t. \
    30.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;
    31. % ~9 g4 T4 F' d6 I
    32.         luVOID i,j,k,m,n,u,v;, D9 Q7 P4 \+ e  t. k# J0 V
    33.         double *pa,*pb,*pc;
    34. / O1 C5 p/ t: v; ~! O$ E
    35.         luMessage pMessage;
    36. 8 f# V, y( ^5 J( n) ^: i! I5 V
    37.         wchar_t wchNum[32];/ k, W7 p3 }2 I
    38.         char chNum[32];
    39. 8 M& g- E( p# _) P; u+ r
    40.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;
    41. + _+ O& ?. u0 D3 C2 W4 O
    42.         switch(theOperator)7 G- N5 K+ x% y. u, ^' k1 k# H  C7 _
    43.         {2 J3 g% |) C- Q. A
    44.         case 2:        //重载运算符*' u+ Z2 \# ^+ ^3 p3 }' r$ a
    45.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    46. - d' R/ @6 n% E3 G
    47.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);) Q4 u1 v$ U\\" V; @  B
    48.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组3 @* q\\" ]$ i9 [
    49.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)4 ~$ m4 h, W# H4 r4 w8 K: h5 `
    50.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配  ^% B; |, W1 c' N5 x
    51.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象
    52. * b* ]: l( |( c, A, C' v
    53.                 if(!pRealArray3) break;; h. |8 L/ Z% b' k
    54.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小
    55. % A: T$ C* `: z. X4 V
    56.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;
    57. 8 r) Y1 }+ K4 ]6 T) ?# H
    58.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];
    59. 6 M' A. d7 W  }. @( F. @
    60.                 for(i=0; i<m; i++)        //矩阵乘
    61. ' O/ u\\" g8 G- V' X# a% ?
    62.                 {) v. \$ V! g9 u
    63.                         for(j=0; j<k; j++)\\" y& G2 r6 }; ?2 Q\\" b
    64.                         {$ f; P4 {( X7 r8 B% c6 z
    65.                                 u=i*k+j; pc[u]=0.0;, A- {' [- x, f2 j
    66.                                 for (v=0; v<n; v++)
    67. , m3 q$ _8 @, E, W4 S! E
    68.                                 {# M1 W5 g) p# H0 Z; O4 L$ w
    69.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];& Z1 w8 |5 @6 y
    70.                                 }
    71. . U# L4 m2 }8 x
    72.                         }7 L2 _; {  `1 B, h6 \  F
    73.                 }
    74. 5 S% I# B1 S) \+ o2 P) a2 U\\" F
    75.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    76. . @  V7 Q/ ]; [6 M/ t3 E  M
    77.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;/ v  L4 b/ L% t' _; X
    78.                 break;
    79. ; U! P* ~. S% H5 C
    80.         case 25:        //重载运算符.*$ b9 Z; r3 D$ y+ j. F  z( f
    81.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);/ Y( ~9 H4 k- V\\" g
    82.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);3 Z3 G\\" B\\" P\\" T) s
    83.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组
    84. ( z! ^( L3 {/ k& J& R1 B
    85.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    86. % q8 C0 ~! W+ x7 g6 B\\" c0 b
    87.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同/ F# \/ j/ O( z0 e6 A1 G% l
    88.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象; r7 }& l! H8 p' U5 g+ i
    89.                 if(!pRealArray3) break;# |. ^! E! L% c, C; i' y. ^; ?. ]3 |
    90.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小# ^& g7 G4 t! c, e, y' e
    91.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘# _# ^: E\\" e- p2 `8 I) m& k
    92.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    93. 2 c4 `4 u4 D& A; q
    94.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;1 O- ^( G0 p1 l# E+ }, F
    95.                 break;5 v) Z& F2 Q% q  D* @( a
    96.         case 46:        //重载函数new
    97. 4 s3 n8 w9 q* R1 q+ W0 x4 y
    98.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数
    99. 5 p: `5 Z, ]( n2 m9 h2 [4 y
    100.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型/ y8 Z( b( Z: T  c) k) h
    101.                 break;5 H# f% J; E: B$ V, `
    102.         case 49:        //重载函数o
    103. , J: M$ l3 p9 u. `$ w; r' L
    104.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);$ ~, `3 V4 b$ j' t
    105.                 if(!pMessage) break;
    106. \\" j* `7 Y8 s4 f: U1 w  _
    107.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);0 ^6 d2 e# L* s7 ]! Y0 Q2 V( _) `* t+ l8 t
    108.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组
    109. . V4 F3 }. T* x* t; d
    110.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)- K, G8 a! y' D2 l
    111.                 pa=pRealArray1->Array;
    112. 5 G: D* K3 t$ S( r. w& S5 d# o
    113.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;: A4 B. T* t; q6 M; g
    114.                 for(i=0; i<m; i++)        //输出矩阵9 \$ O- z0 E. I: ]7 Y/ J: q, g/ w0 R
    115.                 {! a1 o' b  _* d6 }+ C* E5 q
    116.                         pMessage(L"\r\n"); k+=2;' S' T5 R) h& {4 Z
    117.                         for(j=0; j<n; j++)% [- O( s0 e. K6 T* f
    118.                         {
    119. 2 u$ j, l7 r8 u\\" W8 i/ t4 z
    120.                                 _gcvt_s(chNum,pa[i*n+j],16);
    121. ' a\\" a# v/ {% P1 b
    122.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}
    123. / u8 u2 f; m5 L1 F. W! v' N
    124.                                 wchNum[u]='\0';2 [* D6 A4 G, A
    125.                                 pMessage(wchNum); pMessage(L"  "); k+=2;
    126. - M3 J: V: v& l; d6 s0 @+ R
    127.                         }2 t1 H! u. [! X& s- v
    128.                 }& \3 i# i9 Q/ m$ c( |0 N6 n
    129.                 pMessage(L"\r\n"); k+=2;
    130. 4 A9 |\\" c/ O9 r1 |) P6 |\\" M9 i
    131.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数+ b7 x: p4 b7 p; L, i
    132.                 break;
    133. \\" ?8 n2 j- ]' ?) ]( O
    134.         default:
    135. 2 [; a7 F  T\\" A7 s4 M. J8 e4 s\\" |
    136.                 break;7 [% Y. M; ?\\" f4 c. Q, {
    137.         }
    138. - d# V) Q# v; l/ N+ Q2 L3 p
    139.         return a;
    140. : L! Z7 w8 O\\" U3 c# P
    141. }
    142. 2 W6 E1 O1 w* h8 z$ E
    143. void main(void)
    144.   k/ a, H1 t6 r- K/ Y& ]8 a/ i  _
    145. {
    146. ; {+ M' X$ Y$ Z# E: V
    147.         void *hFor;                //表达式句柄
    148. - ]4 u- @2 E* a
    149.         luINT nPara;                //存放表达式的自变量个数
    150. / {: \: [/ ~6 P+ [6 w: Z1 m
    151.         LuData *pPara;                //存放输入自变量的数组指针6 |# d0 L3 `3 ^2 q( C
    152.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    153. 7 j8 {& U6 @( {7 S7 y$ b
    154.         int ErrCode;                //错误代码9 N\\" J9 x: c7 S2 J. s
    155.         void *v;
    156. 0 @. b8 z4 L# f5 W* w& X. T
    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.]}";//字符串表达式,矩阵乘- s' h6 D+ {2 r8 [
    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.]}";//字符串表达式,矩阵点乘4 d; Z! ?3 c4 S# k( B% S
    159.         LuData Val;* W5 r4 b% k8 C) \( [) d
    160.         if(!InitLu()) return;        //初始化Lu
    161. % L. Q& G; I- j( d9 c% V6 f0 s
    162.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型- C! U$ x: M/ s5 \\\" y/ B. Z* {

    163. # E: L2 `# ?2 {) @1 P% I; w
    164.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量
    165. 6 r) r& t4 A( D# q! S2 A  p8 h) J
    166.         SetConst(L"matrix",&Val);        //设置整数常量9 d; W8 S. U  ~) P: J
    167.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息
    168. 2 G4 I% B6 K1 z8 N
    169.         wcout.imbue(locale("chs"));        //设置输出的locale为中文% N# O  b0 a4 P6 z9 D+ M% T( M1 `+ r& F
    170.   
    171. ! E' ]4 L2 a  H# n
    172.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式. _, W- d2 [( S\\" B\\" [
    173.         if(ErrCode)% Q, k6 o6 i$ J
    174.         {! V% ]0 y! m( a; t8 f+ b
    175.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;
    176. ! s5 c, d, ^  e9 V+ q3 ~: I
    177.         }
    178. 7 M3 s% m5 j3 G: B& X
    179.         else$ @& a! B9 S$ B$ Q! w
    180.         {
    181. + d! F6 y3 Y6 d: J
    182.                 LuCal(hFor,pPara);        //计算表达式的值  L4 O+ u& e# \6 r
    183.         }2 n! j& N$ C) f$ |; V1 h6 y
    184.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用
    185. : Z0 ?- C/ V8 F
    186.         FreeLu();                        //释放Lu
    187. ( @  M. Q* _: O; P
    188. }
    习题:
    & {  V+ @5 |; v& j1 r5 m
    7 L( S4 @4 p9 k    (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。 # k' k: U$ w2 M
    + d' q  h- g& g: e8 w
        (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=8 C0 }4 r' M: a7 l5 x4 E, g4 a
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],) Y7 ^) T2 F( a* i4 L6 j1 h
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],8 h4 y  `4 O' L
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],* w0 @. _6 ?8 ]\" N( h% F
    5.     t=clock(),
      1 ?4 A, g6 j- Y' E\" Z8 r2 l: x
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},
      , i7 b( o! r, S( X: M  }
    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.4 ?0 t2 v\" _9 z
    2. 5. 4.
      - F7 o: V6 z' }3 w5 `* K) B
    3. time=0.875 seconds.5 B, i+ s9 c- D5 L5 y- W
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];
      . S( |) T# C$ P; \\" p( r4 N
    2. b=[2.,1.;1.,2.];
      ; A& p5 b: p  i! L0 X
    3. c=[2/3.,-1/3.;-1/3.,2/3.];
      * }7 Y6 p4 t4 ?( {1 |
    4. tic,& T: z' c7 C( l3 s5 s7 O
    5. d=a*b;7 B* i7 V$ Y: ]( ^
    6. for i=1:1000000' z; d3 v) J/ m6 ^5 ~
    7.     d=d*c*b;
      3 w! q3 m# L0 ^! J- C; I' d1 b* F
    8. end' s; z. i# M3 D
    9. d,. O- A- u0 ?. S& T
    10. toc
    复制代码
    结果:
    1. d =
      3 Q8 O1 Z0 g% J7 t3 S+ M6 g3 G  i
    2.      4     5
      + [1 |. e* R# G( Y* q- b8 B
    3.      5     49 W3 ], P+ r2 I3 m3 L0 E
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。0 I$ q" L% \1 t8 ?# {
    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-7-17 17:34 , Processed in 0.380844 second(s), 52 queries .

    回顶部