ऑक्टेव: वैक्टर के दो मेट्रिसेस के बीच की दूरी की गणना करें


12

मान लीजिए कि मेरे पास दो मैट्रिसेस Nx2 हैं, Mx2 क्रमशः N, M 2d वैक्टर का प्रतिनिधित्व करते हैं। क्या प्रत्येक वेक्टर जोड़ी (एन, एम) के बीच की दूरी की गणना करने का एक सरल और अच्छा तरीका है?

आसान लेकिन अक्षम तरीका निश्चित रूप से है:

d = zeros(N, M);
for i = 1:N,
  for j = 1:M,
    d(i,j) = norm(n(i,:) - m(j,:));
  endfor;
endfor;

निकटतम उत्तर जो मुझे मिला है bsxfun, उसका उपयोग किया गया है :

bsxfun(inline("x-y"),[1,2,3,4],[3;4;5;6])

ans =
  -2 -1  0  1
  -3 -2 -1  0
  -4 -3 -2 -1
  -5 -4 -3 -2

मैंने इस पर एक नज़र डाली और मैं गणना को वेक्टर करने से बेहतर नहीं कर सका। मुझे लगता है कि यह गणना एक बाहरी सी / फोरट्रान फ़ंक्शन लिखने के लिए एक बहुत अच्छा उम्मीदवार है।
एरन अहमदिया

1
मुझे यकीन है कि आप एक 2xNxM मैट्रिक्स बना सकते हैं जिसे आप बाहरी उत्पाद के साथ आबाद करते हैं, फिर प्रत्येक प्रविष्टियों को जोड़ते हैं और शून्य अक्ष और वर्गमूल के साथ योग करते हैं। पायथन में यह इस तरह दिखेगा: दूरी_मेट्रिक्स = (एन [:,: नेक्सैक्सिस] * एम [:, न्यूएक्सिस ,:]); दूरी_मेट्रिक्स = दूरी_मेट्रिक्स ** 2; दूरी_मेट्रिक्स = वर्गर्ट (दूरी_मेट्रिक्स.सम (अक्ष = 1)); यदि आपको केवल निकटतम n-vectors को जानने की आवश्यकता है तो ऐसा करने के बहुत बेहतर तरीके हैं!
मेवप्लप

3
@meawoppl (ऑक्टेव में नया) मुझे पता चला कि ऑक्टेव में रैखिक-बीजगणित पैकेज का उपयोग कैसे करें , जो प्रदान करता है cartprod, इसलिए अब मैं लिख सकता हूं: (1) x = cartprod(n(:,1), m(:,1)); (2) y = cartprod(n(:,2), m(:,2)); (3) d = sqrt((x(:,1)-x(:,2)).^2+(y(:,1)-y(:,2)).^2) .. जो बहुत तेजी से चलता है!
केली वैन एवर

कैसे के बारे में octave.sourceforge.net/statistics/function/pdist.html
निमो

जवाबों:


6

इस तरह की रणनीति का उपयोग करके इन स्थितियों में वेक्टर करना सीधा है:

eN = ones(N,1);
eM = ones(M,1);
d  = sqrt(eM*n.^2' - 2*m*n' + m.^2*eN');

यहाँ एक उदाहरण है जो M = 1000 और N = 2000 के लिए 15x स्पीडअप के साथ लूप के लिए वेक्टर करता है।

n = rand(N,2);
m = rand(M,2);
eN = ones(N,2);
eM = ones(2,M);

tic;
d_vect  = sqrt(eN*m.^2' - 2*n*m' + n.^2*eM);
vect_time = toc;

tic;
for i=1:N
  for j=1:M
     d_for(i,j) = norm(n(i,:)-m(j,:));
  end
end
for_time = toc; 

assert(norm(d_vect-d_for) < 1e-10*norm(d_for)) 

डेविड, आपको बहुत अच्छा लगता है! मैंने बेशर्मी से आपके कोड के टुकड़े को संपादित किया और इसे कुछ विस्तारित किया, यदि मेरे संपादन में आपका इरादा स्पष्ट करने से गलत दिशा में चला गया तो कृपया वापस कर दें।
एरन अहमदिया

2

ऑक्टेव 3.4.3 और बाद में ऑपरेटर से - स्वचालित प्रसारण (आंतरिक रूप से bsxfun का उपयोग करता है) करता है। तो आप इस तरह से आगे बढ़ सकते हैं।

Dx = N(:,1) - M(:,1)';
Dy = N(:,2) - M(:,2)';
D = sqrt (Dx.^2 + Dy.^2);

आप 3D मैट्रिक्स का उपयोग करके भी ऐसा कर सकते हैं लेकिन मुझे लगता है कि यह अधिक स्पष्ट है। D, N की हर एक वेक्टर के विपरीत N की एक NxM मैट्रिक्स है।

उम्मीद है की यह मदद करेगा

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.