数学建模社区-数学中国
标题:
极限测试之Matlab与Forcal代码矢量化
[打印本页]
作者:
forcal
时间:
2011-8-2 15:02
标题:
极限测试之Matlab与Forcal代码矢量化
代码矢量化是matlab的特色,但这点似乎不难实现。代码矢量化的优势并不明显,通过一个例子说明。
//用C++代码描述为:
$ W$ [7 `1 n$ k/ o
s=0.0;
% U7 k0 O- n' ]' E* C' ~/ I$ G/ K
for(x=0.0;x<=1.0;x=x+0.0011)
; P+ C4 s) W, l# a( ~* Y0 B' b
{
# ?+ G- L2 E3 ^% f4 [; q
for(y=1.0;y<=2.0;y=y+0.0009)
/ W' S- L- ~+ q' \
{
8 R2 z F P% [
s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
v* v' H1 m5 b4 r1 V$ |3 G
}
6 q7 ~/ c! {6 l
}
复制代码
Matlab代码:
tic
/ K* t# O+ _( n6 U* y4 x( R
[x,y]=meshgrid(0:0.0011:1,1:0.0009:2);
5 O4 \! P" k9 `- _
s=sum(sum(cos(1-sin(1.2*x.^(y/2)+cos(1-sin(1.2*y.^(x/2)))))))
. e9 l6 |# c# G$ G
toc
8 g! y7 }9 E( {! |0 J
6 O5 R5 U- h5 Z/ L, X6 B0 x
s =
0 ^1 N8 @/ F- [+ @ K- l4 w
0 D# y) d! ~6 ~+ p" O
1.0086e+006
5 `4 \1 Z L5 t( V7 N
7 x5 z; `2 | X8 A
Elapsed time is 0.561108 seconds.
复制代码
Forcal代码:
!using["math","sys"];
0 n+ [1 }# F7 q6 B: w4 W: X
mvar:
$ w* s3 t7 A8 L" M
t=clock(),
1 P# L5 b$ U- w$ e N C) R
oo{
. b$ l' |7 N9 ]
ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],
s4 _" t) T4 c
Sum[Cos(rn(1)-Sin(rn(1.2)*x^(y/rn(2))+Cos(rn(1)-Sin(rn(1.2)*y^(x/rn (2)))))),0]
; V T. J. T& M; K
};
* I9 d3 i; R# U; |- T+ z
[clock()-t]/1000;
复制代码
结果:
- i6 _8 r5 T- F2 T0 X
1008606.64947441
0 s7 z4 c: A- i
0.641
/ T# q6 x' X' j
" {! n: ?7 y8 p) A* Z
Forcal比Matlab稍慢些。
/ Y' L& e8 M4 }. r& U/ o7 V* _
& m5 l6 r9 y' ~" }5 N) x
----------
, j- B" `% D7 j$ u( B* G
& Q( ^9 T1 V& d% j
再看循环效率。
3 Z- d& q; s0 a3 Q/ d) u
) e( L" p1 ?+ C
Matlab代码:
tic
. j: k( A9 E2 J
s=0;
; A, g6 ]6 X+ ~! g
x = 0;
v% ]2 }7 L G: E4 j* A
y = 1;
1 f# g# c' I) x
while x<1
6 |' H! B/ |4 P' F) S
while y<2;
; ]1 M4 L9 V1 y- r2 D* W
s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
) x7 I$ \+ I& N) _- ]4 P6 ]% u6 H
y = y+0.0009;
z: [2 v! n5 {- @6 \" M
end
% V; M: q' q" H" R6 Z4 B5 R$ `8 n
x = x+0.0011;
# H: n9 w6 c& t' K2 ^4 `- a
y = 1;
2 g2 n, \- ]( E5 ~
end
% q+ s/ f1 O1 `5 T C
s
& G c2 r |6 s: q6 J2 t
toc
& O( t1 ]3 |7 O0 z! [4 l& Q+ a3 S) X
% U7 r8 O! D: O$ C+ y
s =
; x* G) a7 d% h2 B. _7 @
3 I( @5 \! y% o
1.0086e+006
% c1 L/ j/ F% E0 I7 k
- E' A/ Q2 ?; K& |/ H
Elapsed time is 0.933513 seconds.
复制代码
Forcal代码:
mvar:
, G9 F( Q' D1 c1 p3 i/ {: @
t=sys::clock();
) L4 c) T" K! u5 ^ E& v+ y
s=0,x=0,
1 S' ?) [8 Z& [/ H8 V3 a( \5 j; _3 S
while{x<=1, //while循环算法;
9 z' K8 ]% y" O% \
y=1,
8 X6 M r% ]9 h6 q
while{y<=2,
% x$ S( u! |2 h+ O8 r8 Y
s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))),
# }! K& W- B9 O `8 c
y=y+0.0009
- P' n; @- p7 ^& N7 A% R P+ C, H
},
$ i# ?4 U5 @- R
x=x+0.0011
: g# N9 X9 ?( R# \5 m
},
) g) c3 X; v- [ `" F
s;
" _% r0 o3 v2 [( K6 j# ^# S2 D
[sys::clock()-t]/1000;
复制代码
结果:
/ {, W. s# O/ m t. _; T0 w
1008606.64947441
4 u- _6 h8 h& w0 |
0.734 //时间,秒
+ t4 f2 e3 a; I& {+ F0 V* T
8 E P( R& w3 b. J9 L
我很奇怪,在这个例子中,matlab的JIT加速器为什么没有起作用?
2 J0 h8 y0 k [' _3 A& k0 i2 h
S; ^$ p* W8 G7 z4 G9 m
-------
" K; n% e& T% v% ^2 U8 N
1 |" e' e8 I" ~! W3 J$ a N, x: E
Forcal中还有一个函数sum专门进行这种计算:
mvar:
; l! a- I$ v. q7 H1 w/ O9 Z5 a
t=sys::clock();
# U& F4 Z( D; Z
f(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
: d J; ~3 d: N# R
sum["f",0,1,0.0011 : 1,2,0.0009];
. W7 u; b- s: S& _# I7 D( K6 Z
[sys::clock()-t]/1000;
复制代码
结果:
/ K8 p$ ? z( A+ e, Q) D
1008606.64947441
# B. K6 R9 Z) j: n& Q: t4 s Z5 P
0.719 //时间,秒
作者:
forcal
时间:
2011-8-2 15:24
说到代码矢量化,就不能不提到大名鼎鼎的arrayfun函数,现在再来看看它的表现。
0 X& y. Y: o+ J9 C# ?2 o. t
6 D' L' s( o9 \
matlab代码:
f=@(x,y)cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
& n. [/ H/ h1 J$ y9 i
tic
$ ?3 C* C+ z. r/ l' e
[x,y]=meshgrid(0:0.0011:1,1:0.0009:2);
- I9 I: K, ?: g0 T5 J3 j
sum(sum(arrayfun(f,x,y)))
( V _' K' R5 P3 E
toc
$ ]( J" l3 y3 z, u" g
) I9 e0 E4 K) |3 N$ W/ W
ans =
0 a n' Q7 W* u' ]
" j, j. m1 l, c& \$ }# O
1.0086e+006
! R i. l. U# ~$ ?! x4 i- S
- m% x% S$ x$ E& {$ t; A s6 c
Elapsed time is 7.339923 seconds.
复制代码
Forcal代码:
!using["math","sys"];
5 @3 J/ x$ @8 H9 B) M
mvar:
6 ]3 ~: [& S2 Y
f(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
# i) d4 A! ~# R/ J/ Y
t=clock(),
( p% k% h& K0 A, g
oo{
9 |- Z& U9 `0 I" n* w! ^6 ~
ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],
1 D4 `7 F8 k' o6 i& A
arrayfun[HFor("f"),x,y].Sum[]
* g! J1 V/ o5 [8 z1 @' O7 w
};
2 N# g8 R+ H! a( J$ j0 @# ~
[clock()-t]/1000;
复制代码
结果:
7 I& `! B/ R" E
1008606.64947441
" W) @4 e4 {4 t4 ^* J0 A
0.735 秒
, X- p+ l4 A6 ]
( N4 `' Y& U' Y5 j, Y* o4 a
可以看出,Forcal的arrayfun函数远快于matlab的arrayfun函数。
J+ |' J4 m* O
; r1 a, S4 e' b0 u
--------
6 Y6 Y2 I2 D! ^* ~8 A
3 c# c N8 C z4 y: u, m! P
从这里似乎可以看出,matlab若借助于arrayfun函数计算三重及以上积分,其效率将远远落后于Forcal。当然,Forcal不使用arrayfun函数计算三重及以上积分。
作者:
我就在你背后
时间:
2011-8-2 16:10
学习中。。。。。。。。。
作者:
海水
时间:
2011-8-2 18:00
看看看。。。。。。。。。。。。。
作者:
alair005
时间:
2012-2-7 12:38
恩,参考一下。。
1449529676012957
作者:
sxjm567
时间:
2012-11-20 08:56
一起交流!楼主给咱们提供机会了
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5