2013-08-22 70 views
1

我有一段代碼,在這裏我需要簡化,因爲它大大增加了我的腳本的運行時間:如何在Matlab中矢量化這些嵌套的for-loops?

size=300; 
resultLength = (size+1)^3; 
freqResult=zeros(1, resultLength); 

inc=1; 

for i=0:size, 
    for j=0:size, 
     for k=0:size, 
      freqResult(inc)=(c/2)*sqrt((i/L)^2+(j/W)^2+(k/H)^2); 
      inc=inc+1; 
     end 
    end 
end 

C,L,W和H都是常數。當大小輸入超過400時,運行時間太長而無法等待,我可以通過千兆字節來觀看我的磁盤空間耗盡。有什麼建議?

謝謝!

+0

我可以做的第一件事是預先確定:'freqResult =零(1,size^3);' – Marcin

+0

我忘了提及我預先分配這些語句:'resultLength =(size + 1)^ 3; freqResult =零(resultLength,1);'我認爲你的排序是正確的。 – jephex

回答

0

這個怎麼樣:

[kT, jT, iT] = ind2sub([size+1, size+1, size+1], [1:(size+1)^3]); 
for indx = 1:numel(iT) 

    i = iT(indx) - 1; 
    j = jT(indx) - 1; 
    k = kT(indx) - 1;   

    freqResult1(indx) = (c/2)*sqrt((i/L)^2+(j/W)^2+(k/H)^2); 
end 

在我的電腦,爲大小= 400,版本3圈需要136S而這一次需要19秒。

更多的「matlaby」的方式ü也可以連做如下:

[kT, jT, iT] = ind2sub([size+1, size+1, size+1], [1:(size+1)^3]); 
func = @(i, j, k) (c/2)*sqrt((i/L)^2+(j/W)^2+(k/H)^2); 
freqResult2 = arrayfun(func, iT-1, jT-1, kT-1); 

但由於某些原因,這會更慢,則以上版本。

0

一個更快的解決方案,可以(基於馬辛的答案):

[k, j, i] = ind2sub([size+1, size+1, size+1], [1:(size+1)^3]); 
    freqResult = (c/2)*sqrt(((i-1)/L).^2+((j-1)/W).^2+((k-1)/H).^2); 

大約需要5秒鐘,我的PC上size = 300

下運行的更快(但不看起來非常好):

k = repmat(0:size,[1 (size+1)^2]); 
    j = repmat(kron(0:size, ones(1,size+1)),[1 (size+1)]); 
    i = kron(0:size, ones(1,(size+1)^2)); 
    freqResult = (c/2)*sqrt((i/L).^2+(j/W).^2+(k/H).^2); 

這需要3.5秒〜爲size = 300