Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Build a Distance Matrix without a Loop (Vectorization)?

I have many points and I want to build distance matrix i.e. distance of every point with all of other points but I want to don't use from loop because take too time... Is a better way for building this matrix? this is my loop: for a setl with size: 10000x3 this method take a lot of my time :(

 for i=1:size(setl,1)
     for j=1:size(setl,1)        
         dist = sqrt((xl(i)-xl(j))^2+(yl(i)-yl(j))^2+...
             (zl(i)-zl(j))^2);
         distanceMatrix(i,j) = dist;
     end
 end
like image 599
ahmad hosseini Avatar asked Nov 29 '22 01:11

ahmad hosseini


2 Answers

How about using some linear algebra? The distance of two points can be computed from the inner product of their position vectors,

D(x, y) = ∥y – x∥ = √ ( xT x + yT y – 2 xT y ),

and the inner product for all pairs of points can be obtained through a simple matrix operation.

x = [xl(:)'; yl(:)'; zl(:)'];
IP = x' * x;
d = sqrt(bsxfun(@plus, diag(IP), diag(IP)') - 2 * IP);

For 10000 points, I get the following timing results:

  • ahmad's loop + shoelzer's preallocation: 7.8 seconds
  • Dan's vectorized indices: 5.3 seconds
  • Mohsen's bsxfun: 1.5 seconds
  • my solution: 1.3 seconds
like image 122
A. Donda Avatar answered Feb 15 '23 03:02

A. Donda


You can use bsxfun which is generally a faster solution:

s = [xl(:) yl(:) zl(:)];
d = sqrt(sum(bsxfun(@minus, permute(s, [1 3 2]), permute(s, [3 1 2])).^2,3));
like image 22
Mohsen Nosratinia Avatar answered Feb 15 '23 01:02

Mohsen Nosratinia