|
1.避免使用for循環(huán):
在Matlab中,for循環(huán)運算效率非常低,因為Matlab是一種解釋語言。像矩陣乘法的宏操作與諸如增加標號的微操作差不多一樣快,因為代碼解釋的頂層都存在于這兩個情形之中。for循環(huán)應該只用于做最后的手段,并且一般用于控制運算,而不是由于計算的原因。 一般的Matlab程序中,90%的for循環(huán)都可以用等效但更為快速的向量代碼代替。(一般為尋找替代函數(shù)或使用技巧)例如,求和運算就可以使用sum函數(shù),也可以通過將該向量乘以所有元素都為1的列向量來求得。 2.向量化 轉(zhuǎn)換一個for循環(huán)矩陣向量的操作過程可以稱為向量化。有時向量化看上去似乎十分低效,因為可能它做了比for循環(huán)更多的計算。然而,向量化后的程序運行速度要快得多,因為重復應用到這個向量的是一個簡單運算。 1)重復行與列經(jīng)常需要從頭至尾重復一個或多個數(shù)值來構(gòu)建矩陣。如果矩陣所有的數(shù)值都要相同,則可以使用像ones和zeros這樣的函數(shù)。但是假設有一個行向量x,并且要產(chǎn)生一個10行的矩陣,其每一行都是x的復制。這里應避免使用循環(huán),而是使用外積矩陣乘法操作。 X = ones(10,1)*x 2)向量邏輯操作 程序運行速率慢的一個地方是條件語句。表面上看,條件檢驗無法進行向量化,但實際上,在Matlab中,如大于、等于這些比較函數(shù)都能夠在向量或矩陣上運算。這樣,下面的Matlab代碼 [1 2 3 4 5 6] < 4 將返回結(jié)果[1 1 1 0 0 0],其中0代表假,1代表真。由后面產(chǎn)生一個沖激信號向量的技巧給出另一個簡單例子: nn = [-20:80]; impulse = (nn==0); stem(nn,impulse); 3)Clip函數(shù)向量化 Clip函數(shù)用來以給定的上限和下限剪切一個輸入信號。用常用的語句編寫的代碼如下: function y = clip(x,lo,hi) %Clip --- threshold large and small elements in matrix x %======>slowest possible version <========= [M,N] = size(x); for m = 1:M for n = 1:N if x(m,n) > hi x(m,n) = hi; elseif x(m,n) < lo x(m,n) = lo; end,end,end y = x; 上面代碼具有雙重嵌套的for循環(huán),用于經(jīng)過矩陣所有的元素。為得到速度較快的版本,必須完全放棄該循環(huán)而利用邏輯操作的向量性質(zhì)。進一步,我們可以利用:true和false具有1和0的數(shù)值作為屏蔽,例如上述代碼可以改寫如下:
function y = clip(x,lo,hi) %=========>fast version<========= %(uses matrix logicals to replace loops) y = (x .* [x<=hi]) + (hi .* [x>hi]); y = (y .* [x>=10]) + (lo .* [x<lo]);
如果使用上面的方法,算術運算的次數(shù)大于第一個版本。(可以使用etime和flops函數(shù)對這兩個版本的函數(shù)進行計時)。即使是產(chǎn)生第二個版本需要進行10倍次數(shù)的大量計算的情形,第二個版本仍運行得比第一個版本快上10倍。 4)“:”算子 “:”符號可以通過給出起始序號、步長以及結(jié)尾序號來產(chǎn)生標號范圍。因此,規(guī)則相間的整數(shù)(或?qū)崝?shù))向量可經(jīng)由下式得到 iii = start:skip:end 另外,“:”可以與矩陣結(jié)合起來操作,對矩陣A,A(2:5,1:3)分出一個4*3的子矩陣。而A(:)產(chǎn)生一個列向量,該向量正是A的連接在一起的列。矩陣A的更一般的“再成形”可以用reshape(A,M,N)函數(shù)實現(xiàn)。 5)經(jīng)常使用help指令來查詢函數(shù)的幫助信息,而用type指令查看函數(shù)內(nèi)容 |
|
|