QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8523|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。2 P" k) F* D# V; V. r+ j7 Z
      h8 R" o" }. x7 W/ A$ h" o. s
        基本要点:
    3 t$ k% d, J) W; T& q: J
    6 O( N1 Q- s, K( g    (1)为扩展类型matrix编写运算符重载函数OpMatrix。
    $ i( P- t7 G- A$ z7 z* ?2 ^7 P3 _( W
    " k0 ~# C5 a4 @4 O& T1 w# B    (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。
    0 X$ n! B5 {9 o3 q  G. C4 r( I& X" A: r8 X) x# ^/ H
        (3)为扩展类型matrix编写其他操作函数(本例未提供)。
    5 q! K4 x: q8 ?: z0 q' S$ W; g8 t/ B+ W! V4 a; R
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>$ `* @6 q0 W, O( i3 l# T. p$ }
    2. #include <iostream>
    3. 7 g6 |6 f& _+ N+ D2 Z
    4. #include <math.h>$ Q! n* f, Y; U1 T/ |
    5. #include "lu32.h"
    6. ' [% ^- P4 u9 \\\" ]* ]  `

    7. 6 K( t/ |9 ?$ n. r7 D6 _
    8. #pragma comment( lib, "lu32.lib" ). z4 m+ c8 m, g; q/ Z\\" [

    9. 8 H0 k3 n% H; L9 h$ R: d
    10. using namespace std;
    11. % G0 [5 V1 Z  _9 `

    12. % R) |) L* q4 m' m
    13. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定
    14. ( W- v) |! M: e7 c( L7 X. r! B2 q5 J
    15. - V\\" [3 D* p7 x' G: a* t$ P
    16. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用 . n. i  E  P6 U- L0 h. [
    17. {4 L1 M- F$ d- s+ M
    18.         wcout<<pch;
    19. # \( \7 W& a\\" M& F9 b4 m* ]
    20. }
    21. 6 Y: i' ~  [. s2 ~6 N* W2 s( `/ _
    22. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做
    23. 1 b/ {; c% w. j7 h  Y3 f
    24. {- q\\" P1 z1 T  L
    25. }
    26. 4 s; k2 n+ w  t* p' A
    27. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数9 ^# \( r( b5 u/ P3 {- a
    28. {9 o8 G7 j8 ?7 ^& P; d  O* K0 n7 H$ M
    29.         LuData a;
    30. 1 U, y4 v( R% L/ |' p
    31.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;\\" o( n/ ?- L0 n) }% g. n
    32.         luVOID i,j,k,m,n,u,v;4 g6 P: Q( l* Q: l0 B4 W2 R
    33.         double *pa,*pb,*pc;
    34.   B: X0 p' c9 J9 O
    35.         luMessage pMessage;2 i2 ^: _8 C4 C8 O2 A
    36.         wchar_t wchNum[32];\\" g% i; j( ?: n- {% _* D/ s
    37.         char chNum[32];
    38. , I4 c$ i, w9 ^- }+ U
    39.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;
    40. % x( x0 c4 W* y\\" e+ X8 E, N
    41.         switch(theOperator)
    42. 3 x' l; s9 z- @* d: @. F7 u
    43.         {
    44. $ s; A* m$ Y; k* x. S6 ]( V! O+ J2 @, }
    45.         case 2:        //重载运算符*
    46. # p7 M) [- K9 r0 Q7 h! F
    47.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    48. 3 }9 x6 N6 Q  C- e# r0 s
    49.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    50. 7 L% b( t7 g2 f* X/ ?9 @+ Q
    51.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组
    52. + C! a4 V1 P0 U\\" _
    53.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵): b8 r. j- Y* }# P
    54.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配$ a1 I4 f, t% Y1 F' v/ Z! r
    55.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象) F8 ^5 z: N0 a
    56.                 if(!pRealArray3) break;
    57. 6 u6 x+ ~* k3 w\\" L9 h( G7 J
    58.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小- B' z! a3 S, e) s' M0 H6 [* v
    59.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;0 {  O, e6 Q4 g
    60.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];8 e; I3 m/ T. ^( r0 J
    61.                 for(i=0; i<m; i++)        //矩阵乘5 h7 Z& E5 p; ~) v' ^1 s
    62.                 {* @1 U5 F2 \' @
    63.                         for(j=0; j<k; j++)
    64. 1 S; c. ~$ C4 }8 Z2 ~) m
    65.                         {
    66. * W6 y/ Z! G' s) ^+ K
    67.                                 u=i*k+j; pc[u]=0.0;# g\\" Y6 Y3 W! a1 F! b6 ^' x0 P; n
    68.                                 for (v=0; v<n; v++)* J( |. c' ]: E; x: }) D7 o! r5 w% T
    69.                                 {: M; u9 D1 ?2 o* \4 U0 h! o' r
    70.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];
    71. 4 u# B; O  s, y- _; Q+ S( x$ o
    72.                                 }' b# ~; j3 J6 b1 c' m2 y
    73.                         }
    74. 2 g3 J% C+ c9 r' N
    75.                 }
    76. 0 Z3 p- [3 z) @\\" W+ R; t
    77.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    78. , Y# M; Z- e: g% E$ Q- L. V
    79.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    80. 7 y( h3 `, t; O' j3 Z
    81.                 break;; p) _/ O- l- s- {8 g/ B
    82.         case 25:        //重载运算符.*4 S! R2 b- Z& T6 w6 D1 P
    83.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    84. ' l; i2 p2 ]: A/ I
    85.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);! Y: ^: J: K, z6 l6 R
    86.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组. _2 s! B, \* ?
    87.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)6 R, |) l% a: S3 f7 i& T
    88.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同% G8 f& l% q. l  l$ m; b, t
    89.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象. L! z! Q( S) T6 _
    90.                 if(!pRealArray3) break;* i$ L% {* w  M3 D
    91.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小
    92. % b6 N% W7 z5 }# v& s0 |, v) ]- j, x
    93.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘
    94. \\" P1 d' h* P$ H! S: J' F6 I- n3 R
    95.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象0 N$ K; f; B5 b- r( c/ I
    96.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    97. 9 y0 L% K) z0 J, v) S
    98.                 break;5 B  R6 E4 K, b* C  |4 @* g. P
    99.         case 46:        //重载函数new/ P8 m  l6 C, T8 D\\" T
    100.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数; \2 B1 n# D6 \( [
    101.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型3 d7 P+ h\\" m, d( S! c! w( n! N+ X9 T6 O( W
    102.                 break;
    103. ) H  A; m; k: ~
    104.         case 49:        //重载函数o
    105. 8 ]. [0 m5 b2 P3 A* V* K
    106.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);0 ?5 d7 P  ^! H7 x  M/ f8 w( W
    107.                 if(!pMessage) break;
    108. 8 W$ I: R% @3 d3 @
    109.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);5 E& W( x; B  ]8 h5 Y
    110.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组
    111. 7 |$ q7 p8 z  a3 v, A- Y( s9 |  f- y
    112.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)2 C9 \& g. \) c' `
    113.                 pa=pRealArray1->Array;3 [& H, S0 V& G\\" n6 A  P
    114.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;6 ~$ S  c# m6 S7 M# M
    115.                 for(i=0; i<m; i++)        //输出矩阵( E( N- L4 g  k6 N
    116.                 {
    117. & U( q# k* m. C9 K
    118.                         pMessage(L"\r\n"); k+=2;
    119. ' h0 X& L9 {  ^
    120.                         for(j=0; j<n; j++): ^; v/ M, h: }6 h! U
    121.                         {- Z* K8 g( V\\" }8 S2 W$ H& x
    122.                                 _gcvt_s(chNum,pa[i*n+j],16);. T( r- Z' W( X8 k% {. G' A
    123.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}% `! I/ ^, w( O2 {1 L9 \4 `
    124.                                 wchNum[u]='\0';
    125. , ^7 g' j; L0 z
    126.                                 pMessage(wchNum); pMessage(L"  "); k+=2;
    127.   D1 `6 d' Q+ \9 D
    128.                         }
    129. % \\\" }8 y6 F7 V3 e9 r3 o* ~
    130.                 }# i  H5 B\\" J; N5 K+ v
    131.                 pMessage(L"\r\n"); k+=2;+ a8 w; n1 v# J, @6 J, M- y7 |
    132.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数
    133. , [% Z, D1 {( w* M& U
    134.                 break;+ [5 j1 h( u1 m0 p, o/ u# G5 o9 B
    135.         default:
    136. 6 ^) s1 ]8 Z( h' N
    137.                 break;
    138. * [- G& D' N  }
    139.         }
    140.   X- i; c3 M  ]5 u
    141.         return a;7 L( F2 _, c% C0 b! e
    142. }
    143. / b5 N# N- ?& [) R2 O
    144. void main(void)  W+ s. n; V6 ~) W  x5 {
    145. {
    146. / n- r! E7 m8 X+ R$ T5 Y
    147.         void *hFor;                //表达式句柄
    148. 5 m2 N9 }! n0 L
    149.         luINT nPara;                //存放表达式的自变量个数( b0 N) |% e1 @9 C7 f
    150.         LuData *pPara;                //存放输入自变量的数组指针6 N3 v4 _6 U  l& Z% Z* B
    151.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    152. 4 L% O4 o: A  S. `# |
    153.         int ErrCode;                //错误代码% @) {: y+ v: ~; e& ]6 S. E( [
    154.         void *v;+ j# ~' E- u, b3 v3 v2 C
    155.         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! j- t1 ~! m\\" }1 P1 I! O
    156.         //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.]}";//字符串表达式,矩阵点乘
    157.   r& U4 `; D) n% W3 p
    158.         LuData Val;* G! D/ P1 c6 o
    159.         if(!InitLu()) return;        //初始化Lu
    160. 8 j; X: A8 {- s3 ?
    161.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型( p- l0 W9 H3 T; f+ N' I! m6 M& w

    162. # {' C& e* [& m, D' X: x
    163.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量* E2 N; y3 L: o2 [+ Y- |
    164.         SetConst(L"matrix",&Val);        //设置整数常量
    165. - M  Y9 G! q+ v$ F
    166.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息% P7 k, B% |\\" y
    167.         wcout.imbue(locale("chs"));        //设置输出的locale为中文
    168. * U7 J% X5 K: h\\" }) d6 P/ x8 C
    169.   ( T6 Y1 @* Q# ^- c/ `
    170.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式2 b. A: q  j/ V
    171.         if(ErrCode)
    172.   r- G( D8 O) {; z
    173.         {
    174. , W, d% O' O) l6 |' Z0 [+ @
    175.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;8 o& ]$ h1 n' L8 B: ^2 E
    176.         }
    177.   w+ ?4 M1 l  q
    178.         else; Z\\" B5 s' q5 T
    179.         {
    180. % G$ D1 d3 R/ q7 Y* L
    181.                 LuCal(hFor,pPara);        //计算表达式的值& w1 j  s4 d+ y5 z
    182.         }
    183. , d' |3 f7 m/ S+ K: R
    184.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用
    185. $ [. d! _6 d% V& t! o8 d: }0 x% G
    186.         FreeLu();                        //释放Lu( X% |% u/ l; {1 f
    187. }
    习题:& b. W' W3 T4 \) \0 f9 W1 f8 H

    # i5 v6 n+ h: @" z- y" h! J2 A    (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。 , C( [3 P' g4 n. F, h" u) D9 H' g
    . C2 Z- v! c8 V! v3 a  k) ~% ?
        (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=
      0 Y+ ]. U. i9 p$ l\" H, y
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],, Y+ }; j. ~( T. ^8 |9 K1 I
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],
      , k8 R\" k; z. e0 q% j% x
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],
      ' H3 ^0 @3 N& Q  U
    5.     t=clock(),6 D\" l9 P: i/ G% c
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},: C1 X# e0 X- p7 ?
    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 U# ^% W) I8 Y4 }2 N8 ~# b
    2. 5. 4.
      \" ^/ d  d- b/ s- A; d7 l
    3. time=0.875 seconds.; \5 P: u& o. M! T: e  [
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];
      8 Y/ O! Q# e5 v! c. o
    2. b=[2.,1.;1.,2.];
      : M. c3 \  n2 e# [! E$ U4 C$ x
    3. c=[2/3.,-1/3.;-1/3.,2/3.];\" Y: L1 t4 g: S
    4. tic,
      ! X$ `+ d/ Z# K, i' ]& m- h
    5. d=a*b;
      / N+ }; g  j! O$ M* [
    6. for i=1:1000000
      ' \; W. }/ h: {: T
    7.     d=d*c*b;
      ; M0 |. @& Q* u' h% H$ V\" ]# ]
    8. end3 }. E6 V5 e3 V* j3 H0 |
    9. d,2 x) u* n& b) f- y7 G; u' ?
    10. toc
    复制代码
    结果:
    1. d =
      # N) e2 O, `/ h6 C* {+ h
    2.      4     5* ~- Q- w- o7 g: I! a\" O7 f
    3.      5     4: s: r1 F7 Q# C% q* \( W
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。, X. V8 \& y2 F% o: R
    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-11-15 22:15 , Processed in 2.542182 second(s), 52 queries .

    回顶部