非常实用的Matlab编程技巧。可以试一试。
* l; `" o3 Z4 _CTerm下载文章: 紫丁香★
6 Z6 p F6 g5 z: \& g+ \5 {5 e: R4 C5 v7 t5 L3 A2 d0 M
发信人: fork (撒哈拉沙漠的沙), 信区: Matlab
3 a3 A- h3 u7 b标 题: 加速matlab运行的三重境界
% J1 u8 ]. M+ N发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)/ `' }1 [: X) j% C+ R f t
* u9 y2 F: R7 j a: ?' U% p9 b
加速matlab运行的三重境界- e! u5 L5 J% K; k
一、 遵守Performance Acceleration的规则
5 G6 }" e6 G; t$ b4 I: O& e1 ^8 o二、 遵守三条规则7 x" Y1 o, X+ @; \
三、 绝招
% Y3 V0 X, X) B3 Z* r4 b' Y( J' ^一、 遵守Performance Acceleration的规则
# C6 E1 r$ G$ l
* P: W- d6 T, ^ Q; k8 G$ ~& t! {关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
# N" ?& c7 {% o( w" b" h2 A8 f其规则总结如下7条:, V2 c7 U2 ?$ e0 Z- l6 x( W
1、只有使用以下数据类型,matlab才会对其加速:
) p P E8 Q# x6 K8 b$ v0 U% @$ klogical,char,int8,uint8,int16,uint16,int32,uint32,double$ v) E! F! l K7 V) M: V
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
" x8 W, m; g' |9 P$ z; jre,single,
1 r; H* v+ h- w' P! G n! p" o+ U( U+ }8 \) w% u
function handle,java classes,user classes,int64,uint64
/ \- [! S( ?: K3 `0 V! }2、matlab不会对超过三维的数组进行加速。: S- o q" B( P* a) F; f( B
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
$ a1 n9 L8 Q$ i2 o; t) G9 T U来表示;
|( a: G, p# {* Cb、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
( r: F& c* R0 T* p, _0 Z" @据类型,只使用1 M9 x& R) z1 {+ @/ g w
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
( m |. ]2 V4 X5 p4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
7 `' C& ?$ L# U' y0 v5 z8 n加速运行。
+ @' z' P8 d6 q5 |5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
3 p) F- L% F; U5 q; e6 Q, y$ ux = a.name; for k=1:10000, sin(A(k)), end;
2 o5 v" g7 a) x6 W6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
7 J" p' _1 R2 P2 J0 T+ s2 F1 V/ E. V度。0 F i/ m$ m2 S% X
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
: q9 g% v0 U& n2 n运行速度。
& N4 L: A" R, \* g! f2 l* F. _4 b. b" o8 s0 s$ Y/ Y; b
. d) p7 `" G! {! r- R6 @& t/ g
二、 遵守三条规则
# d, O2 f/ ]" O8 f+ g6 D0 g% y# L- K! Q$ v3 P) A
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic0 l" U. r2 g a9 ^' T3 Z
h means it is designed
9 @# c# T4 ^% M8 o7 N5 `3 m. T& h0 Z$ y9 ]2 K7 V9 ]
for vector and matrix operations. You can often speed up your M-file c
- O( c: G5 S7 A, Z% code by using4 |( Z) q% V: K- N6 U, f+ V6 ?" N
vectorizing algorithms that take advantage of this design. Vectorizati
0 ^, f( e- h" m S, ~% p, _3 t! \1 c% uon means converting0 T* ]$ @, Q, m* l. B/ x
for and while loops to equivalent vector or matrix operations.”。改进 W$ I: J4 E/ [) i, d
这样的状况有两种方法:
6 ?+ l( x3 P; v! k4 T8 u! s" t% [1 H' c* Q4 C4 W/ K( Z7 E
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
3 _ S+ f# Q$ K' m
- o- Q! W- P! X* p! F8 Bi=0;, b* J' X6 L& u6 F: z
for t = 0:.01:10
2 q p1 B3 ?# ?i = i+1;# ], `( x$ A$ `+ i i
y(i) = sin(t);/ [) I1 l4 K. `/ Q. w& m8 B
end
+ l- [% V. |) d% V5 F替换为:, w; H: n( @) B" E: c M! ?
t = 0:.01:10;
6 T- ?' ~# a0 s6 X6 E2 s6 uy = sin(t);
; U: w6 z0 {8 `% ?- E+ j; e+ d速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i
& s! A: m/ |% ~9 }- _7 ?, q% f8 Xpermute、permute、
( v; Z/ S% O% ~7 w# B8 o4 Areshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
* u7 c; @6 I M- Hum、ind2sub、, Y) T( Q, [8 c, Y
ndgrid、repmat、sort、sum 等。
- @6 J6 c5 z2 N" R/ W- \* ]- P/ `
- j9 E& {* P& N, H+ s# c8 l% \' ^请注意matlan文档中还有这样一句补充:“Before taking the time to
) J2 P8 z4 `4 m4 h' q
$ Z: P5 H8 \7 q/ E! [% bvectorize your code, read the section on Performance Acceleration.% n- P" \- R5 M* e( N
You may be able to# N* [& F4 l' A
speed up your program by just as much using the MATLAB JIT Accelera F( ^3 q' N0 Z
tor instead of2 K$ d5 F0 b, F. a
vectorizing.”。何去何从,自己把握。
, v. ]( @5 M! [( z) q; O9 H4 F6 f& g4 t) z6 N% u; R
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
; X& d$ L" ?5 p% X% e/ r( }行循环次数少的,
; m. G* ]5 D( x) e# L, ^/ v内环执行循环次数多的。这样可以显著提高速度。& |: h' r9 ~: K5 ]; }8 }
* P$ f! D$ \5 F$ \ z2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on& }- k* g% m; b7 W; k+ C$ f: x( n
es、cell、struct、! n( w" r) X- B/ k" g% Z
repmat等。; q) ?" o+ V5 i; i
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
9 E5 o& p8 C) V9 u& j9 x
) g7 K& F4 X6 [% D6 EA = int8(zeros(100));
2 }/ k/ N: L5 n( i1 S+ L换成:* C7 o8 f* E1 H: n
A = repmat(int8(0), 100, 100);1 N! Z/ s8 \! G5 T4 N1 d
c、当需要扩充一个变量的大小、维数时使用repmat函数。
8 ^ Q8 p1 Z& Y3 Z1 p, i% ]7 {/ ~/ F$ K6 A/ ^) E
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
8 w; X. B% l4 {3 a( z4 ?b、使用Functions而不是Scripts 。3 i( v( P& @( t7 L
/ n J6 u: F' E2 ?4 p( T: a0 t- f# K2 w& h+ H1 j
三、 绝招% [* }3 L& U' ?$ w3 i& d
% P0 p6 d6 s! ^* q$ ^0 i: @. r你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
. k$ r, T& F. B1、改用更有效的算法
2 {' T1 |& U7 d2 c5 k6 B' h2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。8 Q- W) f9 k* m* @0 P6 a; l
2 j9 H: _5 b, ] b7 e" M6 {0 @1 ~关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
$ q; U0 G! F; _! M# }' W7 q语言文件,VC编译”。 5 ?2 t. t2 i+ ^+ J* E7 M( y
|