QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8524|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。5 K2 @& g6 |" r0 [
    % z. I  j6 O' u( s6 x
        基本要点:+ a+ R: A  p) P. B; E# f. J9 q
    & y/ j8 f4 f& q* a
        (1)为扩展类型matrix编写运算符重载函数OpMatrix。
    - J: K1 l& `8 u' ?" ]8 g) m  u& I- }9 W: S$ n2 X6 S; g" P
        (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。0 W' R$ n8 }8 X. s/ R, O

    0 m3 ?7 N1 i& S8 `    (3)为扩展类型matrix编写其他操作函数(本例未提供)。
    / P, a6 R4 y) A" S9 i$ N
    1 g* a' t0 \  O# e: [4 P. g    (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>' }6 V' E. d! P- f/ Q
    2. #include <iostream>$ `+ X9 L3 L- v+ N$ y2 b- q
    3. #include <math.h>
    4. \\" N% M1 v- u* l0 b% P\\" m
    5. #include "lu32.h"4 o) X7 |( z+ t, a% `/ \# V5 _, ]
    6. + t% c6 B3 ^5 ~0 m7 U\\" Y9 G
    7. #pragma comment( lib, "lu32.lib" ). x6 W+ Z7 }$ A9 h$ t% D

    8. ) N$ l& a  H$ b6 b+ k. G! @
    9. using namespace std;9 x8 |3 i6 m  c3 R0 l7 {, O7 e: j
    10. . H: k9 P! ~9 J0 D- d0 s. \
    11. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定9 ^8 ^4 j# n* k+ n2 }
    12. 7 K0 Q9 }8 a; V  b$ E
    13. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用
    14. / ]/ r- z  v  I
    15. {8 Q$ w9 ?* d3 S
    16.         wcout<<pch;& R$ D7 q: e1 l& G1 r
    17. }* X$ V# f2 }( e2 a+ a7 A
    18. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做
    19. . `2 s0 d0 f% ]4 `* [: |! @! y
    20. {
    21. + X& F0 x- J; j& G. E! e- g
    22. }
    23. 5 u8 U$ e0 Y( Y\\" b+ a
    24. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数/ `2 K: z3 V, [$ \# K( z% q% X
    25. {. D/ c9 P. i* ^+ Y( w/ K# S
    26.         LuData a;% Q) J3 R/ @# s$ D! B5 X6 |
    27.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;
    28. 0 G, K\\" O  R! I$ j% E
    29.         luVOID i,j,k,m,n,u,v;
    30. 4 b, s3 r$ w\\" w5 c: R2 e  O5 K
    31.         double *pa,*pb,*pc;
    32. * S: ?: ^' I, V, _& G  t
    33.         luMessage pMessage;
    34. / H6 W7 F4 L3 i3 w7 {
    35.         wchar_t wchNum[32];
    36. \\" r, J: F! h2 Z, R* m* }7 L
    37.         char chNum[32];
    38. & g/ D2 f( l! b\\" m  Z: n* K
    39.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;7 s' j& X4 r0 g, F; s$ q9 G
    40.         switch(theOperator)
    41. % _& f7 O, k8 l/ x+ ^
    42.         {
    43. 1 |4 L( \1 `2 c. h
    44.         case 2:        //重载运算符*8 G' B; z1 j# k* }
    45.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    46. # H\\" @$ ?* k( _6 ]' s% U) ]\\" A
    47.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);6 k6 P9 m' s! C- H. }6 q  G: r
    48.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组6 b7 s- A6 e2 m6 B) v
    49.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    50. ! A; q3 t. U0 w
    51.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配1 n5 n. ?# n; d7 f% l. D
    52.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象
    53. 7 o+ o( g# b; ]' A$ y0 y
    54.                 if(!pRealArray3) break;\\" R& T- _' J\\" p
    55.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小
    56. 5 S# a: v( L- S' k
    57.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;* i4 D# F% M2 J\\" C# t7 D2 U
    58.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];
    59. % e: }( r8 U0 @* i8 w7 E$ D' e
    60.                 for(i=0; i<m; i++)        //矩阵乘* S4 }. m* @5 a5 G! T4 ~7 I4 \
    61.                 {, l6 k2 ~6 d, u: f' i& |& g
    62.                         for(j=0; j<k; j++)( ~0 m$ |! N; h( P. C2 g- i+ ^
    63.                         {
    64. 3 W: F, C$ |, L# n( o' _2 {
    65.                                 u=i*k+j; pc[u]=0.0;! ?0 S* ]. `9 l2 b2 H; M
    66.                                 for (v=0; v<n; v++)
    67. 7 `/ W: |8 v\\" M# [! {
    68.                                 {
    69. 4 G3 T+ \5 \$ O/ u
    70.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];. B2 N: Q4 Y. ^& k3 Q+ h  l
    71.                                 }
    72. 7 e8 \2 R! a$ ?; _\\" A0 t- x' p
    73.                         }
    74. \\" b1 E$ F* H- w/ U8 E* ^( m
    75.                 }
    76. ; P  J! v, t' V( }  n/ J8 p
    77.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    78. 9 B4 _# p* {2 ~+ p! O9 h
    79.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    80. 8 |$ y' q6 r& g\\" R) P4 v. U9 J8 g
    81.                 break;, f6 a5 h( O( R\\" g& Q
    82.         case 25:        //重载运算符.*
    83. 3 T. w5 Z1 m: H4 _; f: T& F
    84.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    85. ; E+ }; P8 B& r  x( P
    86.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);; b* M5 L\\" b7 ]. O' d) d& d
    87.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组! K+ \! T  {7 k' n  r. X
    88.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    89. , K2 C3 r+ }/ f: x
    90.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同* p. D6 B, U7 H/ t  E
    91.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象3 [5 ]+ d$ O6 D' N
    92.                 if(!pRealArray3) break;1 ?\\" d0 `2 Q* `* k/ u( I
    93.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小
    94. 3 B9 T\\" ?) _7 k
    95.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘4 z2 B: B' z1 a. C
    96.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    97. $ w4 n4 u9 h& M0 _& ?\\" r5 h
    98.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    99. \\" P8 H6 E2 J4 h4 o- b5 B# V  W
    100.                 break;. Z' ]/ Y$ B. E! |- K
    101.         case 46:        //重载函数new\\" d; s6 b: j$ w6 ~) I
    102.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数
    103. # ?% [3 Z3 j/ ^0 q0 [; i1 \
    104.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型
    105. $ f: f5 Y: W( |3 A: D* r$ n
    106.                 break;
    107. + F4 ^5 M( i9 J5 C; F: m' c4 p1 \
    108.         case 49:        //重载函数o  |$ [6 F. }2 b+ e
    109.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);
    110. 2 f9 U8 e  `8 f5 L, K% Q
    111.                 if(!pMessage) break;
    112. 7 `% v* L7 e4 i) Y8 C7 M+ I4 d
    113.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    114. & F9 {5 A& x5 F: g$ u' D0 d
    115.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组1 R, n, _3 @+ U; Y4 @
    116.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)
    117. 9 o$ ]- a& z6 @7 X3 |
    118.                 pa=pRealArray1->Array;
    119. ( M7 B7 v# O+ [! s2 I
    120.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;
    121. 0 I* O$ Q$ s0 j$ s  ]
    122.                 for(i=0; i<m; i++)        //输出矩阵
    123. \\" \9 A, S' g( M7 u
    124.                 {
    125. 3 {\\" t0 v- B7 {9 _# N6 x% [
    126.                         pMessage(L"\r\n"); k+=2;
    127. # o# }2 I, |1 b& g; x% {
    128.                         for(j=0; j<n; j++). z/ ]2 W, c; j# R9 w
    129.                         {$ e) [* @; p6 S& F\\" }
    130.                                 _gcvt_s(chNum,pa[i*n+j],16);- ]! Q7 C7 P1 s! k  U+ w/ X
    131.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}6 x! W\\" v& v8 P' K6 c
    132.                                 wchNum[u]='\0';
    133. 4 g' c9 l/ h$ k3 |! O
    134.                                 pMessage(wchNum); pMessage(L"  "); k+=2;  \- b5 ?) c6 L/ e# d
    135.                         }- o( z. _- M& S$ T' V7 c/ w+ _
    136.                 }
    137. 8 N# `  j. F0 K4 {7 `5 b  j0 c& j, z
    138.                 pMessage(L"\r\n"); k+=2;
    139.   v: D* Z9 m3 F\\" o5 L5 }! k
    140.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数
    141. + C9 o& O& `' D( l6 A. I: u2 @$ F
    142.                 break;
    143. 4 m1 q5 k* E3 t
    144.         default:
    145. ; f' s3 ^) ^# a+ |. B* b  D
    146.                 break;, E+ v\\" R% g1 r* i  W
    147.         }' Y9 ?( j% N$ B, V( U
    148.         return a;* J- j# F5 g% ~8 p0 _3 C
    149. }$ }4 B, l; M. X\\" D# ?( L
    150. void main(void)
    151. 1 p- a# @# t. X$ g
    152. {! M  [$ {, D5 b! s# U$ O/ G+ A
    153.         void *hFor;                //表达式句柄
    154. ; ^5 c1 y2 w\\" L% E
    155.         luINT nPara;                //存放表达式的自变量个数# V7 B+ o\\" I! u: e1 m
    156.         LuData *pPara;                //存放输入自变量的数组指针
    157. 7 f8 s' T+ z8 K
    158.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    159. 6 ]; b& A9 h8 G  h4 X% G; c
    160.         int ErrCode;                //错误代码
    161. 0 ]7 e8 ^: r: x# e1 O) C2 t
    162.         void *v;
    163. , T& [. q0 h8 I5 J
    164.         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.]}";//字符串表达式,矩阵乘
    165. / i# I\\" M6 r$ A
    166.         //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.]}";//字符串表达式,矩阵点乘
    167. 7 _7 A4 h- T3 q1 H- R$ a
    168.         LuData Val;
    169. ! f) J0 A' X, F' f; s
    170.         if(!InitLu()) return;        //初始化Lu
    171. & |; x8 M9 v% w
    172.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型# ^4 o% K  ?5 {: H$ `0 O4 X$ H, k* ^

    173. 8 a8 d1 V  ~2 Z\\" m\\" g; ^4 }* D
    174.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量
    175. 8 x0 q\\" e; p8 A. s: ^
    176.         SetConst(L"matrix",&Val);        //设置整数常量& }# [. y5 P! B$ C5 J8 }
    177.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息
    178. / F5 ]. \& D3 a4 d% n
    179.         wcout.imbue(locale("chs"));        //设置输出的locale为中文  r- `. g$ j* m
    180.   7 M/ K0 v7 `+ r& w. i% z
    181.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式5 k1 Z) o\\" L9 T: ?5 Q\\" g6 L2 z
    182.         if(ErrCode)
    183. & @% x1 x& \5 ?3 _; R
    184.         {9 O# ~\\" m4 H; M) c
    185.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;7 j4 b3 P5 V' N& u3 n. k6 Y( e
    186.         }
    187. 0 E+ i$ b1 {; Y0 j: s8 z, w2 G$ |) ]! G
    188.         else$ t5 h# Z! e5 c: I4 Y7 X
    189.         {
    190. ' c( t' |) D9 m8 |, e
    191.                 LuCal(hFor,pPara);        //计算表达式的值
    192. 3 A5 I8 l/ x% @) C\\" `( m
    193.         }' t% D9 t\\" D3 f2 b# _
    194.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用
    195. * K3 N\\" a\\" N3 V* s6 r9 E
    196.         FreeLu();                        //释放Lu
    197. & w* @! v2 |; _8 f! }
    198. }
    习题:
    6 j( s6 K! g* y7 ^$ T3 P: H) B4 G# T! g# [% C* z
        (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。 # p- o! a9 j9 ^: D8 b2 U, B( }1 G

    . v. X# e1 n9 |% h4 X    (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=. m7 U3 F  R  {8 l1 I\" _
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],
      2 p8 v4 t; C( ?# B1 B\" K1 |9 d% W
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],' P6 A. w; {  F* x  {3 G9 w
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],2 P; W- D9 ]: d% o6 ]
    5.     t=clock(),
      ' B0 T, u+ n; d9 a: Y4 a) R
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},
      9 p$ k6 D) n2 _* h/ I; m8 r) F! W. O
    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., U* y. @/ e/ j( J
    2. 5. 4.% Y# w' t; y- ]! }
    3. time=0.875 seconds.
      % M) v' i) g: y# L  l3 ~' q1 d
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];
      + r% s# I9 X5 e7 S\" `3 [+ I
    2. b=[2.,1.;1.,2.];
      : ~1 v, d5 v8 G% b2 p1 ^$ u
    3. c=[2/3.,-1/3.;-1/3.,2/3.];
      7 O8 \2 m8 [7 _% E+ ^9 _7 M, X
    4. tic,
      ! w1 \, f5 m, F4 T6 B
    5. d=a*b;
      + C: T8 `, Y\" K- F, s8 P
    6. for i=1:10000008 H; i! o- x% u/ z
    7.     d=d*c*b;
      & a! M9 U! r* v
    8. end0 S( A. n% W: f6 M: I5 }/ j3 \
    9. d,; K  G\" s3 \/ C' {/ U$ q: f
    10. toc
    复制代码
    结果:
    1. d =6 i& ~- I2 z% j3 w% Y
    2.      4     52 w+ I8 w) c9 S) i. ^/ h
    3.      5     4
      ) {3 Q* [: j/ y6 F  }
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。
    : S8 _0 N3 ?& M7 D5 u- 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:17 , Processed in 0.465644 second(s), 50 queries .

    回顶部