QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8905|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。
    - }/ \  _  A1 T+ l4 p2 o5 X8 Z/ q% K0 {# b! m: T
        基本要点:9 G1 e( ~9 g/ d; I
    % S0 Q) d, S* H% H1 ?
        (1)为扩展类型matrix编写运算符重载函数OpMatrix。8 d  r, l" L+ H2 M

    - {+ _" L- N3 M; A8 ]    (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。  j6 H5 g$ s7 D+ h# f
    1 I+ n( u$ {/ {( T0 M/ P
        (3)为扩展类型matrix编写其他操作函数(本例未提供)。
    : [; y  Z2 V3 h; E  Q& @) _9 ]  J3 r" L! W9 [
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>. |8 N5 M+ H% f! N+ T) a
    2. #include <iostream>
    3. 6 }) z4 I: d. J7 [\\" T
    4. #include <math.h>
    5. 0 f+ P2 l7 a: \- F2 I
    6. #include "lu32.h"8 F! I: e9 P+ u) Z# Q  B2 z

    7. 2 ?1 Q* P6 S/ m  b6 Y7 H
    8. #pragma comment( lib, "lu32.lib" )
    9. $ H4 O\\" b# N! s7 T- S\\" m9 e: a

    10. 5 h. c, N0 _* @' W& V# T) B
    11. using namespace std;6 ^+ h( s) o7 C; j& a

    12. ' y  M7 f. O2 x- W\\" D
    13. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定; G% G$ V/ g/ j* J: ?0 l
    14. & m2 B, m\\" o\\" f& Z, b9 ]9 f' X0 J
    15. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用
    16. % n+ }: {6 b6 e& p* c
    17. {+ Q. v) [' x/ ^, s# y\\" }
    18.         wcout<<pch;# f/ [! E: H/ o$ u
    19. }2 U7 W7 {9 ]8 O2 }
    20. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做
    21. , h+ y4 o$ O6 W, E' z9 u
    22. {
    23. 5 u! L8 \* p6 ^# i
    24. }
    25. 4 [% P& e/ a\\" F! O7 P
    26. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数2 X3 ]0 X% t$ P; K
    27. {3 k+ C6 p\\" S8 r& i4 }
    28.         LuData a;# {- F+ D1 a5 \, R8 [8 H5 g3 t8 {
    29.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;
    30. + U; V! p& {. ]! X% g
    31.         luVOID i,j,k,m,n,u,v;
    32. 5 M# ~* r6 b( s/ Q) _
    33.         double *pa,*pb,*pc;5 o. _& w$ B$ q\\" p) u3 Z) Y/ ~
    34.         luMessage pMessage;
    35. 2 O# m: `4 i0 ^
    36.         wchar_t wchNum[32];
    37. + @7 Y( L1 j  h# `6 J
    38.         char chNum[32];6 N( \, P0 i; B' T
    39.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;8 v5 `9 D+ W3 y, H\\" y2 A- W
    40.         switch(theOperator)7 N: V. X3 _- o/ j) s
    41.         {
    42. 3 _& C+ r) y* j: w\\" @
    43.         case 2:        //重载运算符*% A% w3 X3 e1 p' Z6 _
    44.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);\\" F* {' ?( V3 z  n
    45.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    46. 2 {. }# H8 N8 B8 P/ t7 J, z& A  D
    47.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组9 f. c' `\\" D) B\\" v
    48.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    49.   |/ j: `, h0 x
    50.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配
    51. ; `* ?4 p% L! N
    52.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象
    53. $ [, c; x! q  d& M
    54.                 if(!pRealArray3) break;# D7 P. ~6 M- Y' p! b5 D
    55.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小
    56.   h3 @5 w\\" c- X' C& t' a7 H0 p0 n
    57.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;
    58. ( V1 _+ c; T& ^! d, V( h
    59.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];
    60. & R' N, S  K( [4 G1 m: O' c9 W' B
    61.                 for(i=0; i<m; i++)        //矩阵乘. x. d& h1 Q8 R- M
    62.                 {8 e% v( |, e) j- Z2 ?$ Q
    63.                         for(j=0; j<k; j++)3 M# L6 w1 J' n( I) w1 M- L. u
    64.                         {
    65. 5 ~1 ^1 l2 U, v
    66.                                 u=i*k+j; pc[u]=0.0;
    67. 0 h5 E, h( R: W8 |& g5 a: Y7 b
    68.                                 for (v=0; v<n; v++)
    69. / e& y4 O- R$ w3 q0 H& ]7 S
    70.                                 {
    71. 7 x, |+ |' d3 n3 s
    72.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];
    73. $ g6 Q* y\\" B! U- z
    74.                                 }
    75. 9 ?! g2 V\\" e& C
    76.                         }
    77. 0 @, {& |$ K/ k: G  z8 M
    78.                 }1 Y( R/ I; R- A% D+ p5 z! y4 N
    79.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    80.   z' `/ \2 V9 c6 P8 z/ @( i- S
    81.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;9 V\\" V- r\\" B7 k7 \8 u. P
    82.                 break;* C  R0 m! C2 I
    83.         case 25:        //重载运算符.*: t5 n+ p3 t2 [) e
    84.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    85. ; D9 l* v1 O% \* i8 l
    86.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    87. , J& x6 a5 B5 Q/ e  j
    88.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组* f7 B1 [\\" Y' D! d8 p% o( j
    89.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    90. , `# f* ~\\" p* a' @: s
    91.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同
    92. 2 V: Q8 U1 T6 Q/ M6 g& F* k
    93.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象( {4 i7 h! e' ?; t$ w' b. r
    94.                 if(!pRealArray3) break;0 p4 E& Z, c, W: a( b; r7 C+ k
    95.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小% p3 C- o& n) b  N
    96.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘3 ^2 \& A/ w$ C! d& w0 @
    97.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象; K( ?4 x( Z0 a
    98.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;, j, f7 }# n9 A
    99.                 break;
    100. 9 O0 S1 n, \) i. N, c) F
    101.         case 46:        //重载函数new\\" P\\" k0 `  Z5 r! F: O$ n% L
    102.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数- x\\" q/ Q2 B- D. N
    103.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型1 F8 B0 m, p0 F
    104.                 break;
    105.   a9 u) c, k/ u3 D: E+ c  k
    106.         case 49:        //重载函数o
    107. 0 z) S  E3 L7 {5 r# Y
    108.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);
    109. 9 P0 U. m: k9 Z' U
    110.                 if(!pMessage) break;& A' S4 c- d* o/ J; E! Q
    111.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    112. 4 H1 k* N- w+ e& t7 c
    113.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组) P5 b& e: s3 q, V
    114.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)
    115. ; ~7 {2 C% s3 w$ U1 r+ n\\" E: Q
    116.                 pa=pRealArray1->Array;! Q0 `4 ^\\" I- g+ Z
    117.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;; K: U$ B2 Y2 |
    118.                 for(i=0; i<m; i++)        //输出矩阵
    119. 6 \0 A* \: u- d5 B
    120.                 {
    121. \\" ]: Q\\" A  w' z6 u# Z
    122.                         pMessage(L"\r\n"); k+=2;, j( L) _1 a  }  X4 z% C\\" E, x+ I
    123.                         for(j=0; j<n; j++)
    124. 5 `8 ^/ i* T0 F6 P8 I, s3 v( r
    125.                         {- `) {) H7 _* H1 W& Z( O+ V9 b
    126.                                 _gcvt_s(chNum,pa[i*n+j],16);
    127. , ?. @7 j+ H: ~1 |' I
    128.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}0 }1 {+ W4 E+ ?8 o2 h! H
    129.                                 wchNum[u]='\0';) K7 P( P; e! I, m! ?
    130.                                 pMessage(wchNum); pMessage(L"  "); k+=2;
    131. ' l  X& m\\" W7 A; I# K. O) @
    132.                         }
    133. % Q3 m+ Z+ @; U% S3 p) b
    134.                 }
    135. 2 C/ ?0 P; I7 h) _5 o0 ?. T
    136.                 pMessage(L"\r\n"); k+=2;5 |* c8 Q+ f5 d3 F# c
    137.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数
    138. # W4 B* a# |\\" R# I9 @
    139.                 break;
    140. - t: k; u* z0 f+ D% m/ D) X
    141.         default:5 p; W8 E& r$ I1 F3 V
    142.                 break;1 u% f8 N( j, {% ]$ `5 M/ Q
    143.         }
    144. 2 [) M3 P2 W0 c( R+ P
    145.         return a;) o8 }9 d. j/ ?7 p& R7 |( r2 s
    146. }
    147. / @2 w- D) I, x  o9 j4 m, {
    148. void main(void)+ |8 Z5 z0 s# f  M0 |' g6 D* V
    149. {
    150. 7 z. c. X$ K& o: _# t% F
    151.         void *hFor;                //表达式句柄  r0 U1 {3 E/ {% F  _) v
    152.         luINT nPara;                //存放表达式的自变量个数# k# s\\" [4 W8 Q, M' H  Y2 o; c0 O
    153.         LuData *pPara;                //存放输入自变量的数组指针
    154. 1 w, y& J/ @5 o7 ]# g; I
    155.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    156. ' T% `) R) A/ [; f& i4 ^4 X
    157.         int ErrCode;                //错误代码
    158. . g$ @1 `: F  }+ n. @) c& R6 F
    159.         void *v;
    160. 1 }6 p9 D6 G3 C
    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.]}";//字符串表达式,矩阵乘
    162.   v  r1 p1 m& h! M2 ~7 n
    163.         //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.]}";//字符串表达式,矩阵点乘. u; n  k/ i9 Z6 U  a! j% i4 U
    164.         LuData Val;
    165. 1 ^% R# _% t) w' [- T8 W6 q: v
    166.         if(!InitLu()) return;        //初始化Lu& C  A  L' M- t2 F1 M5 }
    167.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型9 o; Q# S& ^& l+ e# u6 }

    168. ) E) I. n: ?' b
    169.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量
    170. % k! s, c, e, k( ?
    171.         SetConst(L"matrix",&Val);        //设置整数常量
    172. - g8 A. |* Y- E2 X, j! O, O* f
    173.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息
    174. % n6 P\\" q7 j, v
    175.         wcout.imbue(locale("chs"));        //设置输出的locale为中文' A/ _! }, U; c0 _- I\\" |  t
    176.   
    177. & O5 B' U! }5 H9 T9 {7 Z7 o
    178.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式5 [4 e& h3 G' w; Z, A8 K5 ~
    179.         if(ErrCode): v' n5 i+ e# b0 {! e5 y, m0 d
    180.         {3 J) Z8 ~$ W5 `: x
    181.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;
    182. ; x6 X0 Z1 k$ S& H% g
    183.         }& q8 l$ k+ A6 y! U4 u. H3 u7 b
    184.         else; P' }; v; L$ U* x; U
    185.         {  Z* P) n9 X+ f/ D$ o
    186.                 LuCal(hFor,pPara);        //计算表达式的值1 t' S3 M1 Y$ a
    187.         }( _' q6 I6 t% a3 M
    188.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用
    189. / S- E$ z+ X! d/ t; C3 b
    190.         FreeLu();                        //释放Lu$ C  W: O5 }& X4 i% \
    191. }
    习题:& ~, }- |. B% s% w7 C, t6 ]
    3 S+ c/ e/ E& K: G, e
        (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。
    8 }1 o! i; v5 I5 m3 U- v" z. }* C
    . `& l4 q+ r7 s1 e' D7 W  f, m9 G    (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=
      \" {0 W- k# ]* c
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],3 l. T- e' g$ l) o/ F' Z' j
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],8 _1 c5 D; Q. L4 g
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],: u; a% A; C; J' o5 Z( M# S4 A
    5.     t=clock(),0 @; ~6 |/ s$ w# G
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},
      1 W1 B$ B4 {- \, X' Q& h
    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.
      9 L' Y0 q: H( g: k  D& ^
    2. 5. 4.
      9 J6 s4 @: x) z
    3. time=0.875 seconds.
      * j  `. j) t- G  ]- k' `6 s
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];
      6 v0 E# e4 N$ _2 J' R/ n. |, t\" \
    2. b=[2.,1.;1.,2.];
      2 I/ n. N9 d7 D/ H7 y- D5 `% J1 L% u
    3. c=[2/3.,-1/3.;-1/3.,2/3.];0 n- z  X. D\" X' X* |$ u
    4. tic,
      - f, o* L. e+ z  t
    5. d=a*b;
      \" u0 s% b$ r2 G/ L5 c
    6. for i=1:1000000
      & U* Z8 [9 B' [6 k# M$ k' E. ?
    7.     d=d*c*b;
      - @4 j0 f3 X% S% V  H* A' \
    8. end0 O' t0 Y/ n# p* q9 \# k, g( M! m\" r
    9. d,
      2 x/ X; A% o) @8 N
    10. toc
    复制代码
    结果:
    1. d =* ?8 N7 j. }7 ^  q/ y
    2.      4     51 ^& X: l4 _+ N* A2 w
    3.      5     4
      3 B9 p0 e7 O9 D- b* K) _- U
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。6 N) \3 G' Y( e# M- z/ u' F2 _
    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-9-1 19:10 , Processed in 0.569273 second(s), 53 queries .

    回顶部