2014-08-28 107 views
1

我正在尋找一種有效的方法來計算大小座標矩陣(nodeCount x 2)中所有點之間使用MATLAB的成對距離。我不希望兩次計算配對距離(例如,在節點1-2和節點2-1之間)。我構建了一個外部'for'循環,該循環通過每個節點增加一個內部循環,該循環僅評估更高索引號的節點。結果是由節點分隔距離填充的上三角矩陣。我想對這些計算進行向量化,或者至少提高此操作的效率。任何幫助,將不勝感激。向量化依賴嵌套循環

gap = 10; 

for s = 1:(nodeCount); 
    for ss = s+1:(nodeCount); 
    if abs(nodeCoord(s,1)-nodeCoord(ss,1)) < gap; 
     sep(s,ss) = sqrt((nodeCoord(s,1)-nodeCoord(ss,1))^2+(nodeCoord(s,2)-nodeCoord(ss,2))^2); 
    end 
    end 
end 
+0

很想看看這裏發佈的解決方案如何在效率方面爲您服務! – Divakar 2014-08-28 14:36:48

+0

大家好,非常感謝您的評論!我修改了我的原始代碼來顯示一個技巧,我正在使用它來加快計算速度,爲我的應用程序。我最感興趣的是計算由變量「間隙」定義的彼此之間的一定距離內的節點對之間的距離。我在代碼中添加了一個額外的屏幕,它可以過濾掉比'x'方向上的間隙更遠的節點座標,所以我進一步減少了計算時間和內存需求。我正在處理數以千計的節點,這個代碼是瓶頸。 – 2014-08-28 14:48:48

+0

你是否預先分配'sep'爲零?我在問,因爲如果條件 - 如果abs(nodeCoord(s,1)-nodeCoord(ss,1)) Divakar 2014-08-28 16:08:26

回答

1

該循環不是真正依賴的持久性。我想你想找到的所有其他座標的距離試試這個:

xCoord = [1;2;3;4;5]; 
yCoord = [1;2;3;4;5]: 
xSquare = bsxfun(@(x,y) power((x-y),2),xCoord,xCoord.'); 
ySquare = bsxfun(@(x,y) power((x-y),2),yCoord,yCoord.'); 
dist = sqrt(xSquare+ySquare); 
+0

感謝您的答覆。這段代碼似乎比我構建的代碼慢,而且內存不足(我正在筆記本上運行,並且有大約50,000個節點對)。 – 2014-08-28 14:40:00

1

而不是試圖用事實不需要的下三角元素,因爲它們是在輸出零,我覺得你是最好使用基於這個very smart solution中討論的快速矩陣乘法的技術來獲得歐幾里德距離的完整矩陣。爲了得到上三角矩陣的所需輸出,可以用triu來包裝輸出。

接下來的代碼是稍微修改後的代碼,我們正在計算nodeCoord同一對座標之間的距離。

代碼

numA = size(nodeCoord,1); 
helpA = ones(numA,6); 
helpB = ones(numA,6); 
for idx = 1:2 
    sqA_idx = nodeCoord(:,idx).^2; 
    helpA(:,3*idx-1:3*idx) = [-2*nodeCoord(:,idx), sqA_idx ]; 
    helpB(:,3*idx-2:3*idx-1) = [sqA_idx , nodeCoord(:,idx)]; 
end 
sep = triu(sqrt(helpA(:,1:3) * helpB(:,1:3)')<gap).* sqrt(helpA * helpB'); 
1
xCoord = [1;2;3;4;5]; 
yCoord = [1;2;3;4;5]; 

dist = sqrt(pdist2(xCoord,yCoord,'euclidean')); 

可以使用函數pdist2

+0

謝謝! pdist2實際上比我的代碼慢,大概是因爲每對之間的距離計算兩次。 – 2014-08-28 14:36:59

0

pdist(nodeCoord)做它在一個快速的方式,但在矢量返回數據。將它映射回矩陣的時間與計算距離大致相同:

sep3=zeros(nodeCount,nodeCount); 
sep3(tril(true(nodeCount),-1))=pdist(nodeCoord); 
sep3=sep3+sep3.'; 

如果您對下三角矩陣感到滿意,則可以省略最後一行。