QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8515|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。
    . Z# S) |& v3 r3 v$ p6 F
    ! k1 i, k  N! ?! R+ N$ H    基本要点:
    ! x8 \3 _; r" V! ^; x% q& C8 K% v- B! Q, ?- N% I
        (1)为扩展类型matrix编写运算符重载函数OpMatrix。
    6 P# P; x. x( ]/ w8 l" x  g* P& K+ H+ G# p
        (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。
    6 }' `5 X& i  p  `. i4 `0 h% f( P" t: P. b! {
        (3)为扩展类型matrix编写其他操作函数(本例未提供)。: {" P. s" F: W; A# |6 t4 D5 W

    # d7 M( x: o) |' N- A    (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>$ ^1 i9 }, n& ?& J
    2. #include <iostream># T# c9 s. C: N2 v+ K
    3. #include <math.h>
    4. ) g6 a* d$ L- d! ]% x
    5. #include "lu32.h"& ^2 c( n- }  t3 m

    6. ( b; B: Y) g% F8 C7 @! r7 }
    7. #pragma comment( lib, "lu32.lib" )
    8. 1 m* O0 Q1 I6 f# n( F6 q

    9. ! y8 i/ p7 C4 p' ]6 ^1 E
    10. using namespace std;
    11. $ `/ J; c% K' ?
    12. 1 i+ e) N\\" P8 `% R
    13. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定1 ^& H8 t, k. [- T7 @, ^

    14. ; m( L/ B: [4 A% `1 q8 q7 W
    15. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用
    16. : x+ [: v0 m3 a! B  m' A4 X
    17. {
    18. ! v3 Q' d+ k6 s: R- Y
    19.         wcout<<pch;
    20. 8 N7 K( u+ F5 x9 U, i0 b
    21. }
    22. 1 @: y# S4 T; V# S
    23. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做
    24. 7 u% @$ e2 b# h# y3 x% W# B
    25. {
    26. # e2 [1 v! X% Y% @# [, l4 R6 Y: G1 }- p
    27. }- p0 d' w# e9 H- o: |4 o* t
    28. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数
    29. ) L5 \# R. [8 T$ p\\" V
    30. {0 q. B6 s9 L9 X
    31.         LuData a;, g3 m6 X8 F- _. k
    32.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;9 V+ [, H5 T9 a3 v- [+ x1 P
    33.         luVOID i,j,k,m,n,u,v;
    34. # ~/ M5 l: z: V1 S, ^. q
    35.         double *pa,*pb,*pc;, }# N) W( a& x\\" U* g
    36.         luMessage pMessage;- H( o( e  |5 T. K
    37.         wchar_t wchNum[32];
    38. - O: v) C. E7 `8 q
    39.         char chNum[32];
    40. + {0 U) w8 Y* L( I& S
    41.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;1 H; A2 c- m8 X2 `6 t% Y
    42.         switch(theOperator)
    43. & U# U- g7 ]. l9 _5 e# p
    44.         {
    45. ; ^- l# ]/ v7 @) Z6 O* W
    46.         case 2:        //重载运算符*
    47. \\" G\\" g/ J- y4 ^/ c
    48.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    49. \\" D, E5 K1 g6 A
    50.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);\\" {7 E  A2 r. ?! i0 X+ a8 S7 i
    51.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组
    52. ' y; M+ U/ J- ~1 ^: _\\" ~9 {
    53.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    54. 4 B\\" e3 X\\" E; g5 b1 h6 e! f
    55.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配
    56. ( W4 N. r  Z* c$ J$ w9 J: h
    57.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象
    58. ) G; u' T, ~! ^: t- Q
    59.                 if(!pRealArray3) break;
    60. * U  C; _\\" J% N5 q
    61.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小8 A. a3 [/ X. H- V# `
    62.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;\\" n: r# ?- H4 ]& H1 b' U$ O# ^9 X
    63.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];2 B; v1 R/ x: t\\" I8 V- }% h* d; L
    64.                 for(i=0; i<m; i++)        //矩阵乘
    65. * m! X- ?* p# N1 Q
    66.                 {
    67. 2 u9 E3 m- E  h/ p
    68.                         for(j=0; j<k; j++)  r, e6 W  }$ d
    69.                         {# P3 j* j. s0 H6 ^
    70.                                 u=i*k+j; pc[u]=0.0;
    71. , R: a) n3 N! [* a
    72.                                 for (v=0; v<n; v++)* {; U3 D% C7 g1 G5 S) ?
    73.                                 {: ]7 G: c1 U, k$ b4 s4 d
    74.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];* q2 q1 P( I# P. g1 _& A
    75.                                 }
    76. 1 |. g3 J- E) \# ?0 K
    77.                         }
    78. 8 J8 p3 \$ h0 c2 N& d6 h: c$ h
    79.                 }; \6 ^, y6 b$ Q( `; N
    80.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    81. 7 m# a) m) A2 ^; G
    82.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;* K2 N% R0 v# g; [/ Q5 z
    83.                 break;6 Z  G' z+ {\\" i/ m! ]8 ^
    84.         case 25:        //重载运算符.*\\" e( c  t5 i2 ^! K: S' X) Z
    85.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);8 [1 s' ^  U* V8 {
    86.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    87. - R0 q, Z# G  U/ p6 @
    88.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组$ `  H; `8 N# L+ {9 A# S# \7 A
    89.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵): G7 q& ?1 W- o; u- y. O
    90.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同
    91. 9 ?& i$ N0 b$ M! S
    92.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象
    93. % ?3 {0 x6 @8 I
    94.                 if(!pRealArray3) break;' l! C' k, K/ Y( T, J( y! R
    95.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小
    96. ; ]% O& Z8 v- a( D; _4 j# a
    97.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘5 K1 F* h, U6 ]& v3 r) c
    98.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象- A$ U- r) F2 D\\" j3 s
    99.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;- {& g- k& }7 x4 W0 e2 A+ F
    100.                 break;
    101. # w  L( e% j, x* E6 B
    102.         case 46:        //重载函数new
    103. + H- {* Y# w3 j
    104.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数1 p$ D2 G6 e0 n! N, D+ Q( q
    105.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型
    106. / F* v3 w( @; o+ p. p0 x, Y0 |) e
    107.                 break;
    108. \\" _; P' ~: N  O: D3 s* r
    109.         case 49:        //重载函数o
    110. ) v; o, r6 G) t$ @
    111.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);
    112. ! H! p- o+ y7 [7 [3 B
    113.                 if(!pMessage) break;
    114. , g5 h( M4 Z/ V  p* ^* @1 h8 d5 t8 f
    115.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);  S- T\\" C3 t/ {3 E/ N: P+ \
    116.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组% X& C, U+ S, k3 b2 `3 C
    117.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)
    118. ; G9 ?& Q$ B: R$ r3 P% u) K$ z
    119.                 pa=pRealArray1->Array;' ^, C  K8 C0 V4 J5 X. t, _+ z. ]
    120.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;/ M, p% g- C% S) y4 Y
    121.                 for(i=0; i<m; i++)        //输出矩阵' p1 r3 ~. c4 @0 d- @\\" J
    122.                 {
    123.   v. W3 h' X# |/ d+ ?
    124.                         pMessage(L"\r\n"); k+=2;& c\\" T5 R( b! J& |
    125.                         for(j=0; j<n; j++)0 [) A+ n% }3 W) X7 r( H; L
    126.                         {
    127. 6 ~+ o- A! O3 m# A- G' X, y
    128.                                 _gcvt_s(chNum,pa[i*n+j],16);1 J) i2 j8 M4 i( C, Z1 N7 S5 D
    129.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}
    130. 4 }  U9 U8 K/ R/ p$ g9 S' e
    131.                                 wchNum[u]='\0';' r* x, Z# ~1 i
    132.                                 pMessage(wchNum); pMessage(L"  "); k+=2;& b) C& g: B0 b; m; E( R2 r
    133.                         }
    134. / T9 u/ J; N. u- h8 r2 O
    135.                 }
    136. 8 l' _% B9 p! L7 o+ E
    137.                 pMessage(L"\r\n"); k+=2;, R6 |/ w5 @$ ?6 S5 I  G- O4 Q
    138.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数
    139. ! F6 W  z# r* W4 K
    140.                 break;
    141. & s9 S\\" L8 P\\" T
    142.         default:( r9 b: i3 u/ a8 I& I6 }& Y
    143.                 break;; M6 O8 S8 F9 G* V& O
    144.         }
    145. & O) l# r' u& w2 o# r7 x1 p
    146.         return a;
    147. $ B5 a, A7 U- W% ~+ H) ?) h' \& W5 L9 Z
    148. }9 f  l. |) G5 `9 J6 h( l. Q& S
    149. void main(void)# j+ j: o& T8 A) s2 s5 i3 G6 j
    150. {
    151. ) F1 G- L. |4 o4 `- I
    152.         void *hFor;                //表达式句柄
    153. ) [3 S6 u7 I. W) v
    154.         luINT nPara;                //存放表达式的自变量个数
    155. + }( @! l; e8 ?) r6 b
    156.         LuData *pPara;                //存放输入自变量的数组指针
    157. 9 V2 P: r$ \& f. G: g+ H7 i# m- r7 \
    158.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    159. + n, h5 C; Y8 Q\\" ]
    160.         int ErrCode;                //错误代码
    161. ( p7 E. }9 E\\" [0 f! `
    162.         void *v;
    163. - R\\" |\\" p\\" n  p% f( G9 t& o
    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.]}";//字符串表达式,矩阵乘/ \4 L7 \& ?9 o6 ~, n6 [$ @7 x
    165.         //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.]}";//字符串表达式,矩阵点乘6 N# ]\\" G* S4 F. ~+ f  }2 h
    166.         LuData Val;
    167. \\" j) g. E0 U* m! p2 A
    168.         if(!InitLu()) return;        //初始化Lu
    169. 5 K' j1 y* A* I. N\\" ?
    170.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型. V3 p9 f1 t% s\\" |/ q3 u
    171. - Y8 o5 Y! T- O1 z% ^! U% l
    172.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量
    173. $ P! i$ O1 e3 B% A5 [4 F
    174.         SetConst(L"matrix",&Val);        //设置整数常量
    175. 5 ~\\" K/ R6 j3 u1 U/ U6 w! s
    176.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息9 K- N, G  r9 `' M$ q$ V) l1 e
    177.         wcout.imbue(locale("chs"));        //设置输出的locale为中文. y' {! i+ V3 i* u3 p  }
    178.   1 `' ~7 O: t4 f+ G+ G5 u1 s
    179.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式
    180. ( L/ v- u- y% q) X8 Y# Q
    181.         if(ErrCode)\\" U5 m9 g* s5 c7 W, j
    182.         {
    183. ! r' ?) n9 L7 q  c6 _
    184.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;8 X8 l, K  ?\\" E+ G5 ~
    185.         }( M- e# }9 [) n
    186.         else& p) q  S% H2 m# z( |4 |
    187.         {
    188. * o& d+ `1 E) A1 ]: M) P
    189.                 LuCal(hFor,pPara);        //计算表达式的值
    190. % K( c' |% W/ r) F) m
    191.         }% k+ i* l/ ^, P  M% d; `9 A
    192.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用. y+ E7 Z, t$ v5 g
    193.         FreeLu();                        //释放Lu; _) C+ I$ J& l8 z' a
    194. }
    习题:
    : Y) Z4 \7 B6 S, r! b5 a2 H% k2 `! h+ w9 B+ c7 R/ B7 y) Z
        (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。 1 S/ F8 L: y, v' T" K/ m( z/ r7 A

    / p7 L7 j* z! u    (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=
      ' o6 `/ y# a4 ^. }
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],6 F2 v\" ?' Z2 f( z% W
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],
      # ?/ D4 L0 G5 ]0 m  c, @( J
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],
      % v7 q# M\" w. b/ u5 c. b
    5.     t=clock(),1 y\" M% D+ C! `. C4 b
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},7 j/ x1 q' ]# S\" ^3 C
    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 b1 b  T# _/ c+ U$ N* f
    2. 5. 4.
      \" Z\" R4 z& R; r4 F/ N
    3. time=0.875 seconds.3 C2 A# V. T  r7 `% V9 o  g
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];
      & ?) g/ o$ h% v\" m: c! ]# i
    2. b=[2.,1.;1.,2.];* j\" Z+ z/ y8 u
    3. c=[2/3.,-1/3.;-1/3.,2/3.];3 N* ]/ Z1 ~3 A9 [* Z! E9 ~8 M
    4. tic,
      \" |1 A( m9 y& t$ o( o3 \' s, v; L* D* M
    5. d=a*b;8 M# t8 M# i# J8 s# b. R/ Q\" K
    6. for i=1:1000000! [6 H. H7 K2 T# p+ f( F
    7.     d=d*c*b;: H/ Y/ G5 M: {1 {
    8. end* v6 N8 W$ R3 t
    9. d,
      ! p% C0 A9 G  x3 B8 q  v, e
    10. toc
    复制代码
    结果:
    1. d =
      ) n- H' p: r9 K
    2.      4     5
      * J8 p% h/ ^- a+ n
    3.      5     49 A0 ~7 C' c/ s
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。
    , T8 i( X1 }/ z6 d% t
    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-12 17:01 , Processed in 1.603282 second(s), 50 queries .

    回顶部