QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8525|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。- F9 z. J# x. l: Z+ R) V

    ( S6 C7 S+ b2 r    基本要点:
    + h5 B+ m3 c: A% q( B
    6 R3 R) A3 d2 H$ A$ ^* p1 W' ]5 Y    (1)为扩展类型matrix编写运算符重载函数OpMatrix。
    " n! n) i: A- J/ S" g9 N! n, o& B. e8 @
        (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。0 s  S, S5 B& W/ k) O. C: |
    3 t7 w" Q2 h* o/ {( y
        (3)为扩展类型matrix编写其他操作函数(本例未提供)。
    : M( D. Q' I0 p) J  D3 x" U3 w* a2 r% B! Z- V& d  G2 A
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>
    2. + @7 U* H' g/ R2 g
    3. #include <iostream>9 b$ d, M2 h2 ^6 Y  ^; F: U5 u
    4. #include <math.h>0 W& R2 m, m! M
    5. #include "lu32.h"
    6. 6 r. }( ^. ~7 K; U

    7. # |; R\\" i: G8 Z7 a  ~1 z+ |
    8. #pragma comment( lib, "lu32.lib" )& w/ ^6 Q8 y! T. o

    9. ' p. z& G! s  H! I: @
    10. using namespace std;5 p2 @9 z# B) O9 n' q( o* d

    11. # W7 L+ d7 f+ B6 R5 C+ u; `
    12. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定
    13. * P; R\\" r; E. _

    14. : z# v% j) J7 [8 j3 r8 }. P  w/ i
    15. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用
    16. ' A8 k) T3 l$ w' W
    17. {
    18. 0 {' s( W( n( E) U9 J
    19.         wcout<<pch;7 Q. G9 l9 F! O( k5 v, M9 i2 e
    20. }# [* s; \0 z- `* ~% N
    21. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做. ^) b# N$ Z; S9 @6 e1 d
    22. {
    23. + D3 K1 e6 W  c
    24. }
    25. * n+ s. ]# [+ u' ]
    26. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数
    27. 7 B! |. g; G# B7 I
    28. {
    29. % o4 G$ T' J4 g% h
    30.         LuData a;% Q& O( r; g  e, @) n7 E
    31.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;
    32. # J3 b+ q5 T8 `  U0 `% V8 \
    33.         luVOID i,j,k,m,n,u,v;2 L! B) Q6 m8 Y8 }: R4 L6 g2 o
    34.         double *pa,*pb,*pc;
    35. 1 X3 v6 W) G+ o* r6 ~8 ]4 C& ?
    36.         luMessage pMessage;
    37. , m0 S1 |% j, ~' Q& @
    38.         wchar_t wchNum[32];. V1 D( p; k* T6 x0 |
    39.         char chNum[32];+ x3 h  N  w7 O+ E2 e
    40.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;
    41. - ], Y; d. w7 Z\\" g2 x* B0 s; m3 y
    42.         switch(theOperator)
    43. 8 X1 D( q( f. r0 d/ ]/ z
    44.         {* e. X  w  W' O5 w6 Z! Z+ T1 k4 z( `
    45.         case 2:        //重载运算符*
    46. ; E& v\\" v- T/ X
    47.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);! v/ t. x# ^2 q8 }6 Z
    48.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);2 F9 k* r$ @9 |5 X
    49.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组
    50. + h& i; ^5 A7 v& D. k, ~
    51.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)5 q, H+ E* N5 v% F
    52.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配$ ]! D7 s\\" Q# d& k+ @
    53.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象
    54. \\" w9 x6 c; k2 d
    55.                 if(!pRealArray3) break;, L# K9 N1 B( L
    56.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小
    57. \\" X1 d1 T2 R2 k) s- \
    58.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;$ Z/ E4 ^' o9 d2 |, V
    59.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];+ C+ z7 }6 b5 ?
    60.                 for(i=0; i<m; i++)        //矩阵乘1 L4 p: D9 b& I\\" I
    61.                 {\\" k' @! V8 x& b9 F5 M
    62.                         for(j=0; j<k; j++)% p: k: P9 E1 Q) T7 Y1 J! \
    63.                         {9 P3 V7 T\\" H; k5 u4 \\\" C: W0 l( ?, D
    64.                                 u=i*k+j; pc[u]=0.0;
    65. : u1 P5 }& w% `6 S6 k
    66.                                 for (v=0; v<n; v++)
    67. $ c+ C% j2 w. Q1 l9 F$ e! K! d) @
    68.                                 {' w8 g- l& h. A8 V( ]' M; e\\" l
    69.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];3 z* y! g, s$ Y
    70.                                 }
    71. & D1 V* l8 g* S+ }
    72.                         }
    73. & F2 x, v. ~/ y  |) [0 x
    74.                 }! t6 j6 _- _/ J1 e
    75.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    76. # X2 G. l) }! H. \
    77.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    78. ; ?; m1 p) B\\" p4 ^) s* ^
    79.                 break;
    80. ' \6 E/ d. @0 f8 r  M! M- ~$ b\\" Y2 ~
    81.         case 25:        //重载运算符.*
    82. ( r6 S+ G2 v- k
    83.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    84. 2 w6 s! i9 h3 z( X3 X. }6 N
    85.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);6 y  U6 s* e* j! a: W
    86.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组/ E0 h; a* ]6 H7 W3 w\\" W% q* o
    87.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)3 v2 V+ l. E( g1 }! E
    88.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同1 _! c\\" h: Y5 M' g3 N, {$ B! O& K# ?
    89.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象
    90. ) z\\" y9 b% o! p3 r, I. o
    91.                 if(!pRealArray3) break;, L2 [7 K\\" ~4 y8 G( O
    92.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小
    93. # I8 s! j3 M. N' n* m- }( H2 |6 E# G
    94.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘
    95. 4 F& E9 z\\" K, F+ w
    96.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    97. ) P# ?( g5 |9 H. r5 x5 ]& k
    98.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;8 p: f$ f# v3 {\\" _* b- u
    99.                 break;$ m: k: |7 ?$ f' @7 I3 ^6 a. E
    100.         case 46:        //重载函数new
    101. . O: u: P\\" `1 O# r2 _! B
    102.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数
    103. / J5 }' t& X' _7 L& J8 g
    104.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型: m\\" {/ _! T& n8 y+ N
    105.                 break;
    106. 6 v2 E0 _, y5 l! e\\" k, z$ d
    107.         case 49:        //重载函数o
    108. ( _2 d\\" @0 t! }& H5 u
    109.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);: t% \& k# Y, r
    110.                 if(!pMessage) break;
    111. * k3 H  P/ i5 y& g5 E6 [$ G! a' P6 s
    112.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    113. : J. ?, g7 r& O) ~, I3 ]& t
    114.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组
    115. * [. Q( {0 `5 M# g+ K6 F
    116.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)
    117. 5 i6 Z5 K) ^6 ~8 ?( `
    118.                 pa=pRealArray1->Array;
    119. : @6 }* m6 u5 y- F' u# F$ A
    120.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;
    121. 7 k5 M/ a  M3 R; Y5 R
    122.                 for(i=0; i<m; i++)        //输出矩阵
    123. & J, i/ o% }# g  l
    124.                 {
    125. 0 _& B# E2 u( k/ b( M! n
    126.                         pMessage(L"\r\n"); k+=2;) L2 |& c2 S* b' w
    127.                         for(j=0; j<n; j++)
    128. 2 v8 L0 c$ t8 Z) I
    129.                         {
    130. $ J( g# `8 V7 {$ n9 d
    131.                                 _gcvt_s(chNum,pa[i*n+j],16);1 M8 a( q' W, f9 c2 V: s9 [
    132.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}# z: L1 g* j0 K7 R& X: @& e
    133.                                 wchNum[u]='\0';# P1 G; q, j4 A( i+ |
    134.                                 pMessage(wchNum); pMessage(L"  "); k+=2;  O/ C& j2 ]6 I4 t
    135.                         }2 h; X4 a: V; u7 S
    136.                 }
    137. ( W1 w% ~' W% r) D
    138.                 pMessage(L"\r\n"); k+=2;  w# R) q# O0 N' g' A, ]% }
    139.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数
    140. % f, k) ^( k# a
    141.                 break;* x  p* _$ O8 u) a6 P/ |7 `
    142.         default:
    143. 1 z, A6 S/ s3 X- \
    144.                 break;9 n& a. k3 x/ w2 n- r
    145.         }3 H9 ^3 {+ D9 `8 l4 e: Y; Y* `% Z
    146.         return a;6 I% L; |! O\\" z* [
    147. }
    148. + c+ z+ l, q\\" L$ `2 y( B
    149. void main(void)
    150. * e, u; u0 s/ m9 T/ b
    151. {
    152. # r6 W) T! ?* e7 w7 _5 @2 @+ j, V
    153.         void *hFor;                //表达式句柄% U8 S+ {0 J8 p1 j; x
    154.         luINT nPara;                //存放表达式的自变量个数
    155. : _1 ~. t6 ]6 y6 T0 a5 p) K/ O
    156.         LuData *pPara;                //存放输入自变量的数组指针
    157. ( ]( b9 @4 M/ L8 t
    158.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    159. ! O8 D! y# j\\" O. |$ a: ]6 ]
    160.         int ErrCode;                //错误代码* k; l3 }, l8 c
    161.         void *v;
    162. 4 d8 F* q- O2 ^# w/ G6 _7 R
    163.         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.]}";//字符串表达式,矩阵乘7 E; L# T' |1 \1 F0 x9 [' `) \
    164.         //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.]}";//字符串表达式,矩阵点乘( v* n( `0 [7 B
    165.         LuData Val;# ^, Y$ [8 {9 O. a$ k
    166.         if(!InitLu()) return;        //初始化Lu
    167. \\" H9 Z/ i7 V/ F6 e' r
    168.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型
    169. + D9 Y' }' b; u: P; V

    170. 0 ]7 ?* y4 S/ g; b* n
    171.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量5 R4 S\\" e& h% [/ L; Q# t
    172.         SetConst(L"matrix",&Val);        //设置整数常量: ^! y4 R0 z+ h9 |3 _  E\\" i
    173.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息
    174. , m7 Z( y5 `7 }# b& t
    175.         wcout.imbue(locale("chs"));        //设置输出的locale为中文( A: }# V6 n4 i. v( j& G0 d( g
    176.   / U- [, t, ^/ a8 a
    177.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式: E' p4 h( a- S. e6 f% [
    178.         if(ErrCode)
    179. ; S  M4 n  X. q% S) |
    180.         {
    181. , {0 ]0 b: \  E' r
    182.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;
    183. 2 z5 B6 ?4 w! b- x1 L7 q+ K
    184.         }
    185. , z2 l( y5 B/ h# ?) K6 [: C& J+ R
    186.         else7 `8 ?, T2 G2 i4 c5 L
    187.         {3 @3 Q1 C) v$ x6 t6 ~
    188.                 LuCal(hFor,pPara);        //计算表达式的值' L! a- H5 r( b/ ]
    189.         }' j& \8 A2 A6 H/ y; b
    190.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用
    191. 8 \4 u: m5 Y( {9 a, c
    192.         FreeLu();                        //释放Lu
    193. . n! a$ D1 c/ y5 I0 V. J
    194. }
    习题:
    & `) q* o& t( r: s, h1 ]
    ( Z& F4 ?6 [3 h0 a' \  M1 \    (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。 $ X$ {. c6 p: @% I3 ?6 n
    9 Z7 P1 Z, O. W, A: g) g6 p
        (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=) ~/ v. _1 B! W- Z/ ^, C. |: D
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],* o% X) i  U. I* `6 Y) d
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],7 @: ^4 x2 j3 r* z
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],
      % `/ x6 F$ E6 z: K
    5.     t=clock(),
      . U1 S0 Y\" z5 h5 f( V3 u. ~
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},/ K0 @' R/ m& f
    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.
      - `5 D* X# N4 _* v. F
    2. 5. 4.
      % ?9 c! i. N5 k
    3. time=0.875 seconds.
      ; [7 @0 v3 H) o1 X5 u* `0 e7 E8 ^
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];% |! ^, b% d  E! @1 a
    2. b=[2.,1.;1.,2.];$ h/ w% E* M* _! `5 ?# P
    3. c=[2/3.,-1/3.;-1/3.,2/3.];
      3 a; D( ]- g5 \) L, H/ ]5 n7 X
    4. tic,
      6 G7 l( ^, x; f; o
    5. d=a*b;9 E- s, R! R( N9 w; o
    6. for i=1:1000000
      \" \4 x( ]6 D8 a! M
    7.     d=d*c*b;- \0 z/ b# C$ s\" e- G  |5 K; V\" A
    8. end
      4 P' U6 |  X. \! b
    9. d,* j; m3 P! w+ N3 G\" H6 f. A
    10. toc
    复制代码
    结果:
    1. d =4 W% _2 b6 u# `! u; Q1 ~# S
    2.      4     5
      \" r$ z; m# t$ ?6 V$ J
    3.      5     4
      : j; n+ k( @6 l' }1 i! o
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。" q3 E0 K, ~4 M" y+ N& {$ p
    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:38 , Processed in 0.657854 second(s), 50 queries .

    回顶部