QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8903|回复: 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(标识矩阵)。为了简单,我们仅处理二维实数数组即矩阵类型。
    / M2 e& n( u+ L) d+ e& p% C+ c8 ^4 e4 \6 ]6 t
        基本要点:( |# K: ?: K1 V4 E7 W
    # |/ |. `8 ?# m' s! w$ ~3 L
        (1)为扩展类型matrix编写运算符重载函数OpMatrix。# B1 S5 b8 t( t2 b
    0 ^) E/ `/ v, z9 S5 Y
        (2)用函数LockKey将重载函数OpMatrix注册到Lu,锁定的键的类型即为matrix,要注册为常量,以便于使用。( @! c6 }5 q# o1 X) C

    ( D5 z7 w5 @2 A4 h$ ^  n, D! {    (3)为扩展类型matrix编写其他操作函数(本例未提供)。
    9 a0 u0 J+ Z$ X9 }% |/ H4 U! @) K6 Q: V+ b' X
        (4)用函数LockKey解锁键matrix(本例中,程序退出时会自动解锁,故可以不用)。
    1. #include <windows.h>1 d/ G* X' @8 g2 e
    2. #include <iostream>; v9 k: Q7 K- T
    3. #include <math.h>/ F( b2 Q  z. I$ o6 K
    4. #include "lu32.h"1 z& ?( N2 v, I0 D& Q/ W1 s& p! R  T; v

    5. + Z# b2 e) @+ Q- n/ h
    6. #pragma comment( lib, "lu32.lib" )
    7. 8 ?% R+ M! V3 S4 @) q* m% A

    8. # n9 F5 B: A% c' s& r
    9. using namespace std;
    10. # x1 k, U. Y; f; y& t
    11.   e' M7 X, W, @( d5 Q
    12. luKEY Matrix=-1000;        //标识矩阵类型,最终的Matrix由LockKey决定
    13. \\" G, x( ]; t! w3 a& Q

    14. 7 d  Q( H) b# w1 y7 T0 Z8 ~3 C( Y
    15. void _stdcall LuMessage(wchar_t *pch)//输出动态库信息,该函数注册到Lu,由Lu二级函数调用 $ |& F) z; c) l5 D# z
    16. {0 y( F4 {% B6 W: U* n4 J\\" a
    17.         wcout<<pch;. a  A! X/ K/ s% U\\" f$ g' o, u! T8 N
    18. }
    19. , u0 r. e9 L+ D
    20. void _stdcall DelMatrix(void *me)        //用于LockKey函数,因为是基于系统内置实数数组创建矩阵,故该函数什么也不做; @# Y  P4 ^* g
    21. {
    22. \\" N! W3 B# t- O3 v& T; e
    23. }1 S4 e6 ?# x0 ]# _' }7 C  e+ T
    24. LuData _stdcall OpMatrix(luINT mm,LuData *xx,void *hFor,int theOperator)        //运算符重载函数,用于LockKey函数
    25. 5 ^6 c) O4 n/ p+ ~) Y
    26. {' W& c$ z9 d) |8 ^* a
    27.         LuData a;( r, D8 b0 c5 X\\" F% l& w
    28.         luRealArray *pRealArray1,*pRealArray2,*pRealArray3;/ i. h  B) u5 s) P: C( Y
    29.         luVOID i,j,k,m,n,u,v;
    30. \\" f% ]6 z% x\\" E# d* y& p
    31.         double *pa,*pb,*pc;# t& m( |1 P8 N2 m
    32.         luMessage pMessage;. u* H1 I\\" H\\" O& o9 G
    33.         wchar_t wchNum[32];2 u9 w\\" G6 {+ A5 s1 T9 I  T* k$ S& M
    34.         char chNum[32];
    35. . M  T, q7 Q$ A9 M2 s1 A
    36.         a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;! m2 |. F' `5 m. ~( g9 N, v) q
    37.         switch(theOperator)% q6 W4 Y  s1 q: A
    38.         {
    39. 6 Y2 n! B4 t7 c5 w6 E5 d( `
    40.         case 2:        //重载运算符*5 b9 r1 H( \1 s5 k
    41.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);. Y: q5 J  ^& Z7 ^0 W( n$ n
    42.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);
    43. 4 J+ q5 }8 D0 @* e, s$ W* f' x
    44.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组8 p0 @8 z) k( H) ]. H' R
    45.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)
    46. * B3 S8 t  q( q+ R# @$ X* Z
    47.                 if(pRealArray1->Dim[1]!=pRealArray2->Dim[0]) break;        //维数不匹配
    48. & G4 E\\" y. [! Y1 M# y3 W
    49.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->Dim[0]*pRealArray2->Dim[1],2);        //创建矩阵对象
    50. / B5 m% j2 t; h' N: B0 [
    51.                 if(!pRealArray3) break;3 ?) t* r2 x) q$ M% B
    52.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray2->Dim[1];        //设置矩阵维数大小! ^6 J8 c/ b) W9 v. ~\\" r
    53.                 pa=pRealArray1->Array; pb=pRealArray2->Array; pc=pRealArray3->Array;
    54. 7 L  Z5 W& [9 @' Z: s; r* j
    55.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=pRealArray2->Dim[1];
    56. / F\\" \) V) D7 m\\" ?7 O
    57.                 for(i=0; i<m; i++)        //矩阵乘
    58.   u& T$ F! U; M8 w5 W\\" {
    59.                 {7 [+ ]. E- Q. B2 o' @6 H4 N
    60.                         for(j=0; j<k; j++)4 }% W# k6 b$ m+ M+ ]5 C$ M5 p+ c1 W
    61.                         {
    62. * T% T& g& n1 w& O
    63.                                 u=i*k+j; pc[u]=0.0;+ Z! M9 E$ G\\" C- l: v+ W1 C
    64.                                 for (v=0; v<n; v++)
    65. # f2 g3 U: d! v5 M
    66.                                 {
    67. 1 q* r4 C\\" I2 K) [/ {
    68.                                         pc[u]=pc[u]+pa[i*n+v]*pb[v*k+j];
    69. % e! [) d4 ^* d3 ~+ \  n3 u. r
    70.                                 }
    71. ' S* C9 u, F- A% M! n5 k( N1 i) i
    72.                         }
    73. \\" A- n0 P( o( l# _! n
    74.                 }( K/ L* a3 ]: L/ e3 \* X
    75.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象: f) b3 ~+ [\\" R  L# O
    76.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    77. 5 t6 v# i& [# r\\" S3 b; B
    78.                 break;
    79. $ ^& H9 P; q  X\\" D3 {7 n( X: ?. T( m
    80.         case 25:        //重载运算符.*
    81. 0 j6 r( F7 b6 ?
    82.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);9 J* V% ^6 s. K% V5 {' d' e% L: B
    83.                 pRealArray2=(luRealArray *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_realarray);, D3 x& j- @8 B7 B: a7 V$ D. \- ?
    84.                 if(!pRealArray1 || !pRealArray2) break;        //对象句柄无效,不是实数数组1 C- q; ?; a0 ~) @
    85.                 if(pRealArray1->DimLen!=2 || pRealArray2->DimLen!=2) break;        //不是二维实数数组(矩阵)  k, K! f9 x  `% w! L+ ]4 A$ T* X5 r- H
    86.                 if(pRealArray1->Dim[0]!=pRealArray2->Dim[0] || pRealArray1->Dim[1]!=pRealArray2->Dim[1]) break;        //维数不相同
    87. $ ]4 J4 l) E( m3 O$ ~7 f
    88.                 pRealArray3=(luRealArray *)NewSysObj(luDynData_realarray,pRealArray1->ArrayLen,2);        //创建矩阵对象
    89. ) K2 @: n* Y- i% L
    90.                 if(!pRealArray3) break;
    91. ! F% A9 ]8 i8 C7 ?
    92.                 pRealArray3->Dim[0]=pRealArray1->Dim[0]; pRealArray3->Dim[1]=pRealArray1->Dim[1];        //设置矩阵维数大小
    93. ( j& X+ u: A0 h\\" f- Y
    94.                 for(i=0;i<pRealArray1->ArrayLen;i++) pRealArray3->Array[i]=pRealArray1->Array[i]*pRealArray2->Array[i];//矩阵点乘
    95. ; S7 J, Q$ y& d: l5 w
    96.                 FunReObj(hFor);        //告诉Lu,返回一个动态对象
    97. ; J: d: D2 Q# R: v# `# c
    98.                 a.BType=luDynData_realarray; a.VType=Matrix; a.x=0; *(luVOID *)&(a.x)=(luVOID)pRealArray3;
    99. 3 M$ J- J9 ?2 x7 j
    100.                 break;$ S7 M: Z2 g7 E
    101.         case 46:        //重载函数new7 @+ [. _# v& a, \' V
    102.                 a=ExeOperator(mm,xx,hFor,theOperator,luDynData_realarray);        //直接调用基本类型luDynData_realarray的new函数
    103. , U2 a) q) h, @+ b) g
    104.                 if(a.VType==luDynData_realarray) a.VType=Matrix;        //设置扩展类型为自定义的Matrix类型' {0 p3 I% c# E8 l, |; k
    105.                 break;
    106. 3 R+ ~: P$ O) G9 }: p
    107.         case 49:        //重载函数o
    108. & y% P$ h; k, e. j3 C* T! U3 b
    109.                 pMessage=(luMessage)SearchKey("\0\0\0\0",sizeof(luVOID),luPubKey_User);
    110. ' V& t3 Q: o5 C- k\\" O, O
    111.                 if(!pMessage) break;! L& o  [, g% t$ K, @( r
    112.                 pRealArray1=(luRealArray *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_realarray);
    113. ! {3 B+ z- A8 m' K5 Y
    114.                 if(!pRealArray1) break;        //对象句柄无效,不是实数数组
    115. 6 V2 g$ I8 `& G- w$ ]
    116.                 if(pRealArray1->DimLen!=2) break;        //不是二维实数数组(矩阵)# L# W- ?9 _) r7 b- q
    117.                 pa=pRealArray1->Array;; K3 W  E- r* b6 D& y' V% Y
    118.                 m=pRealArray1->Dim[0]; n=pRealArray1->Dim[1]; k=0;  Z) Y+ c1 y3 R* I# G
    119.                 for(i=0; i<m; i++)        //输出矩阵
    120. 1 d# S7 Q8 K, ~; z# J# _: A
    121.                 {, U( V' L, Y9 d4 d
    122.                         pMessage(L"\r\n"); k+=2;' z* Z& P* ^! y+ `\\" G! D\\" B
    123.                         for(j=0; j<n; j++)1 ~  T; V, l* \% `) a8 v5 T* o; v
    124.                         {' X- G8 n7 Y6 z* n) _
    125.                                 _gcvt_s(chNum,pa[i*n+j],16);9 ~3 S7 m% ^1 l; s- a) W
    126.                                 for(u=0;chNum[u];u++) {wchNum[u]=chNum[u]; k++;}6 o5 U2 y, _- T/ U
    127.                                 wchNum[u]='\0';
    128. ( h/ v8 K% g5 O- w3 K
    129.                                 pMessage(wchNum); pMessage(L"  "); k+=2;
    130. 5 b; [1 m7 u2 w* k; c/ K
    131.                         }
    132. & V, J8 ^' T4 o2 |. ]\\" g; K0 `
    133.                 }9 [( |; E* ^+ P' b$ _
    134.                 pMessage(L"\r\n"); k+=2;9 d$ h& R- I0 B& ~0 o
    135.                 a.BType=luStaData_int64; a.VType=luStaData_int64; a.x=k;        //按函数o的要求,返回输出的字符总数2 [2 H( d! e! [8 M, N
    136.                 break;
    137. + f7 ?' L- K0 f+ G
    138.         default:, w8 E7 U$ t8 Q\\" X/ n/ I0 s
    139.                 break;
    140. 7 ~. ?* B/ V\\" i5 }# N9 m0 F
    141.         }2 L1 d# i. A8 a$ H6 ^4 z
    142.         return a;
    143. - b/ Q+ H& C& d, M% n! D' ~  |8 ]/ K
    144. }9 M* G6 h) S  a' I3 b1 A
    145. void main(void)
    146. - ?+ `$ j6 S! H; Q  y, h
    147. {
    148. % L) Y, P3 G; u7 W/ ~' w& y- `' ?9 R
    149.         void *hFor;                //表达式句柄
    150. 3 K# d2 X% \) v\\" p
    151.         luINT nPara;                //存放表达式的自变量个数* r+ i. I6 I- R
    152.         LuData *pPara;                //存放输入自变量的数组指针
    153. ! v* H6 B# H2 E: j
    154.         luINT ErrBegin,ErrEnd;        //表达式编译出错的初始位置和结束位置
    155. 7 w7 ^5 K0 i) ~1 L/ {3 D
    156.         int ErrCode;                //错误代码
    157. $ {$ y/ a4 v# b# R2 ^
    158.         void *v;- b4 p7 D% n6 J9 \5 C
    159.         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 U2 p1 r5 f* s/ ^$ f3 u# K5 u/ ^+ [
    160.         //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.]}";//字符串表达式,矩阵点乘, b5 T* `\\" {) X. Z' p  C3 W
    161.         LuData Val;3 ^' c4 |' `* a4 ?7 e2 }
    162.         if(!InitLu()) return;        //初始化Lu
    163. + i, _7 W& F& w
    164.         while(LockKey(Matrix,DelMatrix,OpMatrix)){Matrix++;}        //锁定一个键,用于存储矩阵扩展类型
    165. 8 D8 ^1 E. q3 r( _) P, D
    166. ( o! W; D. Q. M/ X- y
    167.         Val.BType=luStaData_int64; Val.VType=luStaData_int64; Val.x=Matrix;        //定义整数常量5 Q( k: j8 y/ U0 l; ~
    168.         SetConst(L"matrix",&Val);        //设置整数常量
    169. 4 w% R: p! I1 f' d
    170.         InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息3 x& h# N: [# @. Q6 @' V% k, _, r
    171.         wcout.imbue(locale("chs"));        //设置输出的locale为中文4 q+ V/ f, O' [% D4 a3 R4 ^; I$ l0 W
    172.   
    173. 1 n: [6 E% o& k- ^/ X: ?0 n
    174.         ErrCode=LuCom(ForStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式/ U/ u& C1 ]8 L7 [! K6 h) C$ M
    175.         if(ErrCode)
    176. / ]\\" k9 [( b/ q, j: C( o7 f
    177.         {, a2 r# n1 F6 W# U7 n1 h/ m- _7 G0 [
    178.                 wcout<<L"表达式有错误!错误代码:"<<ErrCode<<endl;
    179. ; `: D* Z6 r- }7 R, C
    180.         }
    181. \\" D# F4 X: r) O8 t4 d+ j
    182.         else
    183. 0 f3 g8 w# ~) [0 c2 D
    184.         {
    185. 9 q2 w& o% ^2 V) @2 ~9 N+ x
    186.                 LuCal(hFor,pPara);        //计算表达式的值2 S/ Y* }# c& V
    187.         }8 d, E! |& Z! J\\" y! \# y5 b
    188.         LockKey(Matrix,NULL,OpMatrix);//解锁键Matrix,本例中,该函数可以不用
    189. & r# h6 }: J5 H9 r5 v4 L$ @
    190.         FreeLu();                        //释放Lu* a& G8 ~' X: J+ j1 w
    191. }
    习题:
    5 z' D3 x3 H* z$ D2 @) r2 S5 q! {3 h
    / C/ S$ b0 {" D. f' z- O+ j' \    (1)自定义矩阵的加、减、左除、右除、点左除等运算,自编测试字符串代码,重新编译运行程序,观察计算结果。 ' q( C% n' o. z. _

    . N" x% _1 `4 v7 ^8 U    (2)小矩阵乘效率测试。编译运行以下Lu字符串代码:
    1. main(:a,b,c,d,t,i)=
      ' |. `1 |! X0 `3 I) x: E2 V7 l$ S
    2.     a=new[matrix,2,2,data:1.,2.,2.,1.],
      5 i/ F% ~- S! b) ^0 ?$ A# k% M6 K3 W
    3.     b=new[matrix,2,2,data:2.,1.,1.,2.],8 T5 b% |0 o\" ^) D7 g
    4.     c=new[matrix,2,2,data:2/3.,-1/3.,-1/3.,2/3.],2 a: C; \7 v% C: l\" g) X$ W8 G
    5.     t=clock(),
      . L$ q5 f$ Z) @\" y\" ?2 f) c+ Q
    6.     d=a*b, i=0, while{i<1000000, d=d*c*b, i++},3 H( o% Y) H\" [/ M; v. 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.1 f4 ?+ i- o& T! M
    2. 5. 4., `: x3 V+ O. d$ s& r9 F- I\" g
    3. time=0.875 seconds.
      ! d  x+ U( z9 N& k) d* x
    4. 请按任意键继续. . .
    复制代码
    Matlab 2009a 代码:
    1. a=[1.,2.;2.,1.];7 s6 I: x3 v6 \1 s2 B- z3 u
    2. b=[2.,1.;1.,2.];7 r; K, \& `* G/ o5 {# ^
    3. c=[2/3.,-1/3.;-1/3.,2/3.];+ x3 N& N6 S! D! n
    4. tic,8 Y' J* t: m) p
    5. d=a*b;9 C5 b7 r' i3 ^6 S3 X2 O
    6. for i=1:1000000
      3 @0 M% n, v+ J
    7.     d=d*c*b;
      ; Y1 Y  r2 Q  `* `2 R
    8. end& e  v; Z6 r; c  @; L, ]
    9. d,
      2 A4 I: O2 ?3 g! r8 c3 i, w- s
    10. toc
    复制代码
    结果:
    1. d =3 S& F! D- ]; |* h9 n% ^
    2.      4     5- S/ F+ d# E9 Q7 l% O
    3.      5     4# s# Z- [0 k2 W/ {  h, B2 y; p$ m
    4. Elapsed time is 2.903034 seconds.
    复制代码
    本例矩阵乘效率测试,Lu的速度超过了Matlab,主要在于Lu有更高的动态对象管理效率。& w, |) j, x( {- S5 A6 ]+ K8 M
    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 15:32 , Processed in 0.473814 second(s), 52 queries .

    回顶部