|
非常实用的Matlab编程技巧。可以试一试。 ! ~5 Q% x3 B4 ]. m' a
CTerm下载文章: 紫丁香★1 A3 T5 v6 T4 T: }: p& P) W
9 l* J9 l' ?' t' L发信人: fork (撒哈拉沙漠的沙), 信区: Matlab
) w8 e. q& x/ I3 o, a4 u) W$ \9 I标 题: 加速matlab运行的三重境界, h& n2 m* }2 a/ H; m- S- L
发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)3 T5 P: A5 I4 Y% ~8 `
0 r1 B& t& k" |! `5 C( V8 t# U
加速matlab运行的三重境界
5 j( P* N5 g7 `. k |3 ]. T一、 遵守Performance Acceleration的规则
( v1 }% t4 m( b6 n$ w/ o, X. C$ ~二、 遵守三条规则0 S* |+ E) t0 ?/ D% K0 h, p
三、 绝招
; o! l$ ~! {% L+ \3 Z; p: q( Z( X8 O一、 遵守Performance Acceleration的规则
3 {$ x9 S+ A3 C& z; V* v4 C3 f+ v8 N2 O. e5 }6 c# P4 N
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将) h" }# p, c/ D" t# a
其规则总结如下7条:
- I" T5 }1 r% | q* }1、只有使用以下数据类型,matlab才会对其加速:
' {7 t" `0 L7 ~# F4 E1 V, n6 n, wlogical,char,int8,uint8,int16,uint16,int32,uint32,double
3 S1 g0 C4 g) r, y而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu# l) c) [3 y+ C0 U; M9 N' q
re,single,
3 J4 w0 P/ c6 ~. w# Q2 z8 P" h; K- M7 N" P* H+ N/ ]0 p9 d1 W1 G
function handle,java classes,user classes,int64,uint64. z1 a' Q# o* L; \' Z0 _9 Y
2、matlab不会对超过三维的数组进行加速。
" z5 e% S/ u9 a/ `9 P3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
8 x, s2 O8 m: m2 C T4 E来表示;+ T# ?5 N' Y2 A' l0 z2 A
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
# X, o: ]1 G% K# v+ o: N% t; a据类型,只使用
2 T0 m% W- f7 h2 v) }三维以下的数组;c、循环内只调用了内建函数(build-in function)。, x( X. ]1 B& M, v' b
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将4 R5 f3 m% N) l0 Y
加速运行。
. }4 T- g* o2 [+ _, [. l5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:3 D9 ~# L$ P6 \* {
x = a.name; for k=1:10000, sin(A(k)), end;
" h5 ^& o. n+ i- `- j/ Y6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速, S4 h6 ?* O- d1 q
度。
2 C8 {+ r: x. R, A" F7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
- }4 O; M3 I6 }' s, t运行速度。
3 W! ~8 H( z5 Y" K# T2 G* f! x" h, l. j/ m1 s
7 l8 X1 D A T
二、 遵守三条规则4 z9 @3 u" Y2 o
8 F; M* E5 F8 m, Y
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic* F# c8 B, G' z/ i2 s
h means it is designed4 R; d& n! V$ y: f0 `
; s# T: [$ o& i1 V: B
for vector and matrix operations. You can often speed up your M-file c6 R; B! G" y4 ^: A7 M
ode by using! i% e% g% _( y- ` f; ]3 s/ [- S: {
vectorizing algorithms that take advantage of this design. Vectorizati1 M9 T2 u- @/ ~" Q B5 d# M T
on means converting
6 }2 a. [* Z( D, gfor and while loops to equivalent vector or matrix operations.”。改进
; u3 S! @. R7 P/ q9 c0 d2 g! ^1 b" |这样的状况有两种方法:
: |/ L0 p3 N7 M6 }+ n ~) w8 G7 \
* u" {& E+ k( Z5 r4 I& Qa、尽量用向量化的运算来代替循环操作。如将下面的程序:. k( B, T9 {+ x2 O8 K
& N8 G6 a: F8 p3 C
i=0;3 T/ I" Y. l) c; ]: l
for t = 0:.01:102 z, ~% @9 |! @) G. t' l" |
i = i+1;3 b: ?5 K. l9 M$ Q
y(i) = sin(t);. ^0 z) _8 Q4 X+ [( X( ?2 i7 x
end
. E. [5 H8 ^+ L6 Z: X替换为:
, N9 F. R& ^7 Et = 0:.01:10;
6 `, `( n7 {$ o: Iy = sin(t);/ U% Y; R0 U( g7 i" p
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i
$ _9 x( `) _, r5 \$ Opermute、permute、& e; w, y6 F; q/ n1 X+ s8 j* b( r3 {
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums3 m$ r1 ~3 ? b c. o1 x! \, V% L8 _
um、ind2sub、2 c G! _: _3 ~- [9 i
ndgrid、repmat、sort、sum 等。0 ?1 P3 T! W- w) x* X
0 ?% X3 h7 e, l/ A9 f3 b0 X+ y5 W/ [请注意matlan文档中还有这样一句补充:“Before taking the time to
* k) O, a9 o# B3 s6 e4 x3 t
! T X7 S( d5 m6 F8 dvectorize your code, read the section on Performance Acceleration.( l' U& ~# c5 G! c4 t& o6 ]& @8 k
You may be able to
/ ?( K; }* u. M& @speed up your program by just as much using the MATLAB JIT Accelera
5 K4 p3 F& J' C. P/ {1 |+ D1 utor instead of
& d# s, ~. l. c* v1 {# Kvectorizing.”。何去何从,自己把握。1 X8 u9 r+ f0 t( ?6 T
( o* K+ N" v$ y7 K4 j* G+ A+ }
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
; m' \4 G+ F/ W6 }6 T行循环次数少的,
C8 y/ [9 g- @' @, U0 X+ B内环执行循环次数多的。这样可以显著提高速度。
" o, Y! F$ K. J, W6 i8 ~+ O
; Y2 k# G4 a8 k% f8 `2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on- X% j5 C& @2 x5 z: C2 O; j- [
es、cell、struct、
& k- V$ l- K# b k) l: Irepmat等。& e i' f# i$ }5 Z) k1 [4 @+ l+ o
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:$ q$ @6 C# O2 S; f9 y
1 ^/ P0 I+ @/ ~1 Q) mA = int8(zeros(100));4 L0 Y7 ^+ }4 P9 {# F4 x: U+ z3 @ B
换成:
$ x9 F3 |& Y8 X4 P- t( _A = repmat(int8(0), 100, 100);
1 ?. F. [* A' mc、当需要扩充一个变量的大小、维数时使用repmat函数。
! n& X/ ^4 C6 U" B
7 D+ d" P0 S3 t& W9 J3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
) x1 a( i9 P% {4 t$ Ob、使用Functions而不是Scripts 。9 y- w1 E% G; f0 p$ B( Q! g
( [- B6 ^% i6 X
: x+ H2 E7 [& x" {& y
三、 绝招
6 m9 [* Z2 B8 o0 t- H: |7 U. {; X+ [8 H* v$ f0 U2 J
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
0 W# V' P9 y$ ?9 r1 e( y0 B1、改用更有效的算法
Y R# X0 E5 A* T. N2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。5 o" f4 }0 {3 ?/ t' B$ g1 F
. R' Q \8 R6 D% ^/ ?& \0 U
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++5 F) V# i# d1 Z6 F) u. E" X8 m d
语言文件,VC编译”。
( \1 I% F3 f6 M7 _0 F5 |8 Q# @4 D9 V |