2013-05-20 47 views
2

我在八度以下代碼:如何優化以下爲雙八度音中的循環?

dist=0; 
for i = 1:length(x);   
    for j = 1:length(y); 
     v = x(i,:) - y(j,:); 
     distvect(j) = norm(v); 
    endfor 
    dist = dist + min(distvect); 
endfor 

其中x和y是具有大小爲n×2和一M×2。我的主要問題矩陣:我需要運行上述幾次的代碼。

我敢肯定有一種方法使用可能只是一個矩陣,而不是V向量在內部for循環每次去優化它,但我找不到它。我在網上搜索,我發現了一個arrayfun功能,這可能會幫助,但我無法弄清楚如何使用。

感謝您的幫助, 灰鶴

回答

2

你可以在這種情況下做出最好的優化是自己實現norm採取矩陣乘法的優勢,而不是遍歷各個元素。

回想一下,對於矢量值,norm(v)計算norm(v, 2),這是歐氏距離

norm(v, 2) = (sum (abs (v) .^ 2))^(1/2) 

既然你只需要找到的最小距離,你實際上並不需要採取平方根,直到後來。爲了緊湊,讓a = x(i, :)b = y(j, :)M = length(x)N = length(y)。由於您的變量v包含不同的向量,我們可以擴大distvect計算到

distvect = norm(v) 
      = norm(x(i, :) - y(j, :)) 
      = norm(a - b) 
      = (sum (abs(a - b) .^ 2))^(1/2) 
distvect^2 = sum (abs (a - b) .^ 2) 

現在,展開二次項,(a - b)^2 = a^2 - 2ab + b^2,這使得abs功能冗餘

distvect^2 = sum (sum(a.*a) * ones(1,N) - 2*a*b' + ones(M,1) * sum(b'.*b')) 

最終的優化,它將跨多個值應用該功能。這是通過使用您的xy矩陣的外積來創建length(x)通過length(y)矩陣來完成。然後,沿着每一列取最小距離並對結果的平方根求和

xx = sum(x .* x, 2) * ones(1, length(y)) 
xy = x * y' 
yy = ones(length(x), 1) * sum(y' .* y') 

dist = sum(sqrt(min(xx - 2.*xy + yy))) 
+0

我認爲存在一些錯誤。用x = rand(440,2),y = rand(740,2); –

+0

謝謝,我認爲它現在已經修復。我正在總結錯誤的軸。 – Lucas

+0

太好了,非常感謝。這正是我所期待的,這種方式要快得多。 – grus