2013-05-30 121 views
0

有沒有辦法重寫我的代碼,使其更快?遞歸循環優化

for i = 2:length(ECG) 
    u(i) = max([a*abs(ECG(i)) b*u(i-1)]); 
end; 

我的問題是心電圖的長度。

+0

應該在'b'之前有'+'嗎? – dchhetri

+0

不,一切都是正確的。 – user1729509

+2

目前還不清楚,心電圖是非常大的問題? –

回答

2

你應該預先分配u這樣

>> u = zeros(size(ECG)); 

或者可能是這樣

>> u = NaN(size(ECG)); 

,或者甚至像這樣

>> u = -Inf(size(ECG)); 

取決於你想要什麼樣的行爲。

當你預分配一個向量時,MATLAB知道向量將會有多大,並保留一個適當大小的內存塊。

如果你不預先分配,那麼MATLAB無法知道最終向量將會有多大。最初它會分配一小段內存。如果在該塊中空間不足,則必須在某處找到更大的內存塊,並將所有舊值複製到新內存塊中。發生這種情況時,每當分配塊中的空間用完時(這可能不是每次增長數組時都會發生這種情況,因爲MATLAB運行時可能足夠聰明,可以請求比需要更多的內存,但它仍然不止必要)。所有這些不必要的重新分配和複製都需要很長時間。

+0

from max([a * abs(ECG(i))b * u(i-1)]);這是否意味着u已經在循環之前預分配?如果你沒有預先分配,最大功能將會出現錯誤。 –

+0

@m_power我期望@ user1729509在循環之前只分配了'u(1)'。 –

2

有幾種方法可以優化for循環,但令人驚訝的是內存預分配並不是節省大部分時間的部分。到目前爲止。您正在使用max來查找1乘2向量的最大元素。在每次迭代中,您都會構建這個向量。但是,你所做的只是比較兩個標量。使用max的兩個參數形式並將其傳遞給兩個標量的速度要快得多:在我的機器上爲大型ECG矢量快75倍!

% Set the parameters and create a vector with million elements 
a = 2; 
b = 3; 
n = 1e6; 
ECG = randn(1,n); 

ECG2 = a*abs(ECG); % This can be done outside the loop if you have the memory 
u(1,n) = 0;  % Fast zero allocation 
for i = 2:length(ECG) 
    u(i) = max(ECG2(i),b*u(i-1)); % Compare two scalars 
end 

對於max單個輸入形式(不包括創建隨機ECG的數據):

Elapsed time is 1.314308 seconds. 

對於上面我的代碼:

Elapsed time is 0.017174 seconds. 

FYI,上面的代碼假定u(1) = 0 。如果不是這樣,那麼在預分配之後,u(1)應該被設置爲它的值。