数学建模社区-数学中国
标题:
极限测试之Matlab与Forcal代码矢量化
[打印本页]
作者:
forcal
时间:
2011-8-2 15:02
标题:
极限测试之Matlab与Forcal代码矢量化
代码矢量化是matlab的特色,但这点似乎不难实现。代码矢量化的优势并不明显,通过一个例子说明。
//用C++代码描述为:
- H5 P) E0 A [; x7 X! }" G* e
s=0.0;
% E0 |; F( M. x) M4 D
for(x=0.0;x<=1.0;x=x+0.0011)
% b3 \9 U& L4 Y
{
y8 ~+ Z# Z1 ^8 v4 [9 U
for(y=1.0;y<=2.0;y=y+0.0009)
7 I+ }9 x# P$ G: z
{
( E; r- a+ d5 @9 ~. I
s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
2 b6 {$ P) Q( C/ Z+ z: @% a7 x
}
5 v; @: E4 [0 p" |/ Z, d3 K7 [
}
复制代码
Matlab代码:
tic
' u. n v. W" P& g, k+ A) x
[x,y]=meshgrid(0:0.0011:1,1:0.0009:2);
9 n- M4 @+ S |0 i, S# ^$ u
s=sum(sum(cos(1-sin(1.2*x.^(y/2)+cos(1-sin(1.2*y.^(x/2)))))))
$ a) k' X7 E n% X5 ]2 Z% e* r* ~
toc
" ^' x% ^/ `7 H' n
' b: ~ p5 n6 n1 J( i
s =
; e7 {: }6 s0 A5 O0 D7 j! p
; a3 ]& F6 ~4 }
1.0086e+006
2 |0 A3 G+ V+ @) h+ U
$ `& z5 P& y# V
Elapsed time is 0.561108 seconds.
复制代码
Forcal代码:
!using["math","sys"];
" Z3 n9 i5 K: b6 B7 |
mvar:
/ R, c$ e/ \8 L% _- [1 E2 k* j8 A
t=clock(),
' Q- E# f" _9 O2 X1 d8 r7 t3 R
oo{
) p0 X, `' T# E2 n4 a; P
ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],
% Q/ y# ]3 {* [) l
Sum[Cos(rn(1)-Sin(rn(1.2)*x^(y/rn(2))+Cos(rn(1)-Sin(rn(1.2)*y^(x/rn (2)))))),0]
" `; d# z9 D x" p: m( P
};
) p+ k# n1 m5 ^/ Y( P% A
[clock()-t]/1000;
复制代码
结果:
8 i6 \/ c4 Y- d' z" }
1008606.64947441
4 X0 v! F% |) B1 y
0.641
- R: L1 g9 `1 I4 ^% w% ?
# N1 k4 q' l( b- K. `/ S' [: a# ?
Forcal比Matlab稍慢些。
$ ~' S8 L2 r6 y3 }/ t* `' G, J6 u! V
* T$ G# X6 | P) K
----------
$ o9 `$ F: h& C# ^8 _* j7 z
& ?$ V0 C. c! ?/ G! W e
再看循环效率。
2 Z& c$ Y, Z5 r9 i( e$ @8 @
# U& k0 ?! ]# z! i( }6 ?
Matlab代码:
tic
* f8 _& O# Z6 q( i# ~' f
s=0;
1 h$ O! C( _6 v9 G
x = 0;
- l% A1 m# a M, |! a% {
y = 1;
! ^- A9 u/ V+ M; b9 | z0 U G
while x<1
; B9 [ V0 X5 i: b
while y<2;
; \! X& A$ i3 S0 B9 j: `* z1 p+ n
s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
# B7 K6 _9 u) [" T
y = y+0.0009;
$ B& Y& E+ ~- U+ a8 Q
end
8 B' ?' s' C- e o: L
x = x+0.0011;
1 P) t7 w: @: B" ~0 V* U6 h& D
y = 1;
: K9 }0 Z: X6 e! x
end
) `7 A% V8 P) f. K9 Y
s
* }5 f" T/ e+ f' k$ S
toc
) j" x% P8 S. ?: M: \! D2 @5 z6 L8 u* u
+ l$ |9 X) ]" ?* E
s =
4 X) o4 e( x: P1 ] Y) P; e
6 l& j% a& |/ w2 @5 z
1.0086e+006
% y4 M+ j0 j' K! @2 ?4 l7 r
, f7 n, ?+ ]4 Y) n! x
Elapsed time is 0.933513 seconds.
复制代码
Forcal代码:
mvar:
7 z: h+ Z* U# C! `; ?, V+ W
t=sys::clock();
# }; F, B' F: _1 [9 V# G" B) I* E; N
s=0,x=0,
1 E4 u9 U. X; g; w2 C
while{x<=1, //while循环算法;
, i1 _* T# N; k! l3 \) n( w1 I
y=1,
' A# Y1 o* S: e, w# b
while{y<=2,
: f- u# {3 s, R. Y3 k
s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))),
) V( m1 |. J. r2 r% g
y=y+0.0009
& V+ N1 _7 g6 |) t3 H! ^
},
r+ c* r8 o) K# u
x=x+0.0011
W/ T7 O) }' p3 `& A B4 v$ g8 O
},
- B% ?! p7 J+ Y' V# S2 u
s;
# `0 b2 x2 b8 q; x, @
[sys::clock()-t]/1000;
复制代码
结果:
3 R) h. l9 m4 T, V* B9 c. S3 @
1008606.64947441
1 \# L+ m5 b0 a, l; W8 C
0.734 //时间,秒
& J" D) ^6 x7 I6 H6 T2 E
. s) i* m& b6 y y4 L) n/ C
我很奇怪,在这个例子中,matlab的JIT加速器为什么没有起作用?
0 W( h' T" W6 R9 _' B3 S4 `
L e$ b: N* Z; ]7 A/ A% `
-------
) F' {9 A4 ~1 Z, W
7 o/ Z& Y% P4 u' F
Forcal中还有一个函数sum专门进行这种计算:
mvar:
. y- ?& f7 P1 \4 y+ h
t=sys::clock();
/ U7 l7 {2 w" x7 K5 x3 A" ?
f(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
Y& x9 o* Z4 k9 w5 U. g5 z
sum["f",0,1,0.0011 : 1,2,0.0009];
) H4 Z* l- r; Z, N0 S9 |
[sys::clock()-t]/1000;
复制代码
结果:
: A7 t$ A% N, O& j# I$ n4 |* M
1008606.64947441
5 D: H8 R) O% `, N9 o$ F
0.719 //时间,秒
作者:
forcal
时间:
2011-8-2 15:24
说到代码矢量化,就不能不提到大名鼎鼎的arrayfun函数,现在再来看看它的表现。
5 N1 g* E8 M3 y( p# z0 ~
1 l$ U6 p( ^; P: X
matlab代码:
f=@(x,y)cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
4 w5 q" G( m1 z; O& c
tic
* Y6 ~& o3 O7 h. H3 K% J
[x,y]=meshgrid(0:0.0011:1,1:0.0009:2);
" ~2 ?& | z4 E& o3 D
sum(sum(arrayfun(f,x,y)))
; M1 A; |4 ^- u
toc
! _" ~8 M: [* D: G" o8 T
4 E( O8 z- d; \+ ?4 I, W6 i* M# R
ans =
" e H/ X% _6 q) ~# r
2 l* W* Q5 C- x+ g. {( r7 k$ `
1.0086e+006
# A/ \0 T X. Z0 r" ^
8 {. H) m) R s
Elapsed time is 7.339923 seconds.
复制代码
Forcal代码:
!using["math","sys"];
% s2 z: m# S; m5 V
mvar:
% l- s9 T8 E+ b# ]
f(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
7 x: y1 i# j& N0 x( }4 W' [# E6 o
t=clock(),
# _+ R0 b7 z5 H: R: D
oo{
) x5 d. F1 Z6 n+ Y
ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],
1 {! p) U8 M5 U0 Q, e2 c6 |% U
arrayfun[HFor("f"),x,y].Sum[]
) u* Y1 S' |2 X% B' j6 X! {7 Y
};
+ b7 O. K, `0 |1 o* a9 z1 @# @; l
[clock()-t]/1000;
复制代码
结果:
/ P8 x" [% |" a! V8 C0 ]
1008606.64947441
2 _$ t5 z( m) n8 K
0.735 秒
1 M0 V/ R* e( \ ~. v4 k: Y
+ {6 y: R( h3 Q; u
可以看出,Forcal的arrayfun函数远快于matlab的arrayfun函数。
& q/ N) N& ?7 [6 W# h% L
; e: _6 p& n% R3 `4 X$ m
--------
& A& d; d0 R1 o/ w
2 H1 o7 u, y0 J$ U1 M' e1 L
从这里似乎可以看出,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