|
非常实用的Matlab编程技巧。可以试一试。
2 s P& @5 Y2 m& E- \+ nCTerm下载文章: 紫丁香★
/ i* A1 A, I) s; g$ N: C. X' c
* m, N$ L: S, p A4 f7 V5 `发信人: fork (撒哈拉沙漠的沙), 信区: Matlab- P3 h3 r+ [! w5 d9 N# A- g
标 题: 加速matlab运行的三重境界& L$ B s" p; x# S0 _
发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)
: }& T, y' T/ ~" k. Q9 C/ u2 L8 f
) X* H, b9 a. H: w9 C+ O加速matlab运行的三重境界
, r( ^( \" e3 P% }/ _ p一、 遵守Performance Acceleration的规则
9 H" [3 Y- M7 y. J. a% w二、 遵守三条规则7 c0 _# v9 _: B4 V
三、 绝招
" Q8 h1 d. i& S; [0 \- A/ ]3 p+ q
一、 遵守Performance Acceleration的规则: ?: {, ?$ y9 @6 m+ ^- N! B
# o- x+ f' d! y" T8 n9 k关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将; u# |8 N& @& c6 i+ \
其规则总结如下7条:0 q. g, Q" i& g
1、只有使用以下数据类型,matlab才会对其加速:% r: o3 k. v% B( O- n$ F$ V/ {6 b. q
logical,char,int8,uint8,int16,uint16,int32,uint32,double) A% e7 p3 y; {. p# A3 s" x2 Z& @
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
6 H7 q# u- i" e( |! g! Yre,single,: c: n( Z, z: m5 Y+ D4 @2 V1 G
3 F$ |: H6 V N, I& Nfunction handle,java classes,user classes,int64,uint64
6 @; ?. x! f: {2、matlab不会对超过三维的数组进行加速。
8 q" M8 f4 ]0 @# z5 t+ w" d( C1 q3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
3 {1 w; Y6 C& T% u' g来表示;
; @* K+ d6 o- q% {; Y$ X, Ub、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数% L% h7 B4 u g& U
据类型,只使用8 Q( F b9 U1 ^7 Z
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
! v% L# Y$ U1 a! D4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
6 s2 I6 [( x* K0 T- a加速运行。
$ X: Y+ Q+ I M" `; ^% k8 C' X5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:+ b0 k; i8 C1 M, m1 s a: U7 K
x = a.name; for k=1:10000, sin(A(k)), end;
9 }/ h: B* ^2 u F6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
4 d! | N6 G( L6 O# _度。5 a/ @- i+ P4 h: f
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
' G8 w) J; G, u5 L& Q7 e0 V; G运行速度。
! c; R, w/ L0 n, @( ~$ n* W" i+ ^
9 _% ^' |' f( X' w) v8 H
二、 遵守三条规则
+ _5 P1 v) {0 D7 I; o# s7 T: T; J' E5 T6 k. \7 d3 t0 l2 b
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic' U0 S7 q+ F" l n. O
h means it is designed
v4 w/ X+ R( `# e
# {1 j: \) N5 \# W+ G6 p ufor vector and matrix operations. You can often speed up your M-file c& F8 N/ ^4 Q$ O& Y9 ]/ J
ode by using
& ~) q- w' Q, B2 Mvectorizing algorithms that take advantage of this design. Vectorizati( N2 s( v+ B! X7 e
on means converting
( S/ {' T. M# ?* _6 ^for and while loops to equivalent vector or matrix operations.”。改进+ Z1 B* R% Y- B" p
这样的状况有两种方法:
9 k! j) X- o M* d1 l# v: I5 j
+ U+ D1 I$ G7 O+ ?a、尽量用向量化的运算来代替循环操作。如将下面的程序:
. W/ v( G# |7 g! ]
# |$ p" h: c) {/ o; h% O7 ui=0;
; t- v- D* p9 Q: z! _8 d+ }for t = 0:.01:10
0 @4 G3 m3 l3 M- V5 c3 [i = i+1;. F1 g6 T# W- n. I7 u" {+ S
y(i) = sin(t); A G5 ?+ e0 l4 e+ t' g2 H+ b
end9 n9 c, U8 T" N! [& w R
替换为:
$ a$ r: f5 G* Bt = 0:.01:10;
& P |: G% m- J8 L) ]y = sin(t);" h4 a I$ V/ j, K: n9 m' ^7 H
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i1 R0 w$ \1 w2 }/ R' W& P
permute、permute、
, `! Q' N# |% @4 n8 |reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
* S8 E6 r3 {, _$ ]3 Vum、ind2sub、
% S3 }6 v, l" A$ X7 g3 v3 e. ~& ^ndgrid、repmat、sort、sum 等。' [+ J4 w+ o# s7 ^1 z6 v; E2 h K
7 J, y0 F) c1 X
请注意matlan文档中还有这样一句补充:“Before taking the time to
7 T: T0 O2 ~; l6 z$ \8 u0 ~, a. B- K2 b/ u
vectorize your code, read the section on Performance Acceleration.
7 e5 n1 S6 F/ R& k: R3 R4 o7 q# {You may be able to
0 Z( p5 D* Y2 }( G7 G5 uspeed up your program by just as much using the MATLAB JIT Accelera
+ w' e4 `8 y$ p# otor instead of9 w% c1 X8 ~: t% e" Z
vectorizing.”。何去何从,自己把握。
! i) d" J: X0 P+ w% R
. V/ r- r3 e$ P" S0 }6 bb、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执4 V7 ~9 Q* I; C! s1 H
行循环次数少的,
. u3 V$ k8 g% R5 [内环执行循环次数多的。这样可以显著提高速度。
. G) y, F, A, |0 M3 k( t5 O% [* c. H6 P! V6 D
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
5 h" t+ P( a* l \3 `es、cell、struct、
8 s+ T; k& x B7 Erepmat等。
: F' F* p3 [8 v# C; I' L& J9 xb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:+ p* R* G5 }8 A% f" U4 L
" ?, x, j8 o' Q
A = int8(zeros(100));" p/ c" I0 C _! r* }6 P
换成:
% q2 K% r2 k6 y8 DA = repmat(int8(0), 100, 100);
" G. m9 a2 o. o$ Vc、当需要扩充一个变量的大小、维数时使用repmat函数。* X" r C+ p: O4 u" Y# q% _8 @8 j
+ K. h- n3 K! G$ g. c
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。$ U! U! n- J- C2 v9 N3 q
b、使用Functions而不是Scripts 。; w0 |2 q. \0 k: w; \, \
8 m- q' {7 W1 h& ~+ M. h
( u1 b) ^' B8 w! Z三、 绝招1 V' ]1 l. o' }* m' r# j8 g5 q
( ]" T( ^4 Z- I/ f& d* F
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。! G! R* H4 ?" q# M) a8 d! Z) q
1、改用更有效的算法
; D" B! T$ i( V2 H+ e2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
, e4 q" L+ o" n) V3 a$ T' D& A( _5 j5 k
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
9 M- q3 p7 `6 ]; V5 \: @语言文件,VC编译”。 7 [& `$ }! N+ B; }+ a
|