Find the distance from one point of the matrix to all other points in the matrix

I have a matrix a , and I want to calculate the distance from one point to all other points . So in fact, the result matrix should have zero (at the point I selected), and should be displayed as some circle of numbers around this particular point.

This is what I already have, but I can’t find the correct result.

 a = [1 2 3 4 5 6 7 8 9 10] for i = 2:20 a(i,:) = a(i-1,:) + 1; end N = 10 for I = 1:N for J = 1:N dx = a(I,1)-a(J,1); dy = a(I,2)-a(J,2); distance(I,J) = sqrt(dx^2 + dy^2) end end 
0
source share
3 answers

This is what I was looking for, but thanks for all the suggestions.

 A = rand(5, 5); select_cell = [3 3]; distance = zeros(size(A, 1), size(A, 2)); for i = 1:size(A, 1) for j = 1:size(A, 2) distance(i, j) = sqrt((i - select_cell(1))^2 + (j - select_cell(2))^2); end end disp(distance) 

You can also improve it with vectorization:

 distances = sqrt((x-xCenter).^2+(y-yCenter).^2 
-2
source

Your matrix a is a 1D vector and is incompatible with a nested loop that calculates the distance in 2D space from each point to another point. Thus, the following answer relates to the problem of finding all pairwise distances in the N-by-D matrix, since your cycle is executed for the case D=2 .

Option 1 - pdist

I think you are looking for a pdist with the 'euclidean' option.

 a = randn(10, 2); %// 2D, 10 samples D = pdist(a,'euclidean'); %// euclidean distance 

Follow this squareform to get a square matrix with zero diagonal as you wish:

 distances = squareform(D); 

Option 2 - bsxfun

If you do not have pdist , which is in the statistics toolbar, you can do this easily with bsxfun :

 da = bsxfun(@minus,a,permute(a,[3 2 1])); distances = squeeze(sqrt(sum(da.^2,2))); 

Option 3 - reformulated equation

You can also use an alternative form of Euclidean (2-normal) distance,

 ||AB|| = sqrt ( ||A||^2 + ||B||^2 - 2*AB ) 

Writing this to MATLAB for two data arrays u and v size NxD ,

 dot(uv,uv,2) == dot(u,u,2) + dot(v,v,2) - 2*dot(u,v,2) % useful identity %// there are actually small differences from floating point precision, but... abs(dot(uv,uv,2) - (dot(u,u,2) + dot(v,v,2) - 2*dot(u,v,2))) < 1e-15 

With the reformulated equation, the solution becomes:

 aa = a*a'; a2 = sum(a.*a,2); % diag(aa) a2 = bsxfun(@plus,a2,a2'); distances = sqrt(a2 - 2*aa); 

You can use this method if option 2 consumes too much memory.

Delays

For a random data matrix of size 1e3-3 (N-by-D), the timings for 100 runs are shown here (Core 2 Quad, 4 GB DDR2, R2013a).

  • Option 1 ( pdist ): 1.561150 s (0.560947 s in pdist )
  • Option 2 ( bsxfun ): 2.695059 sec.
  • Option 3 ( bsxfun alt): 1.334880 s

Conclusions: (i) Perform calculations using bsxfun , use an alternative formula. (ii) the pdist + squareform has comparable performance. (iii) The reason squareform takes twice as much time as pdist is likely because pdist only calculates a triangular matrix, since the distance matrix is ​​symmetric. If you can do without a square matrix, you can avoid squareform and do the calculations in about 40% of the time needed to do this manually using bsxfun (0.5609 / 1.3348).

+10
source

IMPORTANT: data_matrix is ​​DXN, where D is the number of measurements and N is the number of data points!

final_dist_pairs = data_matrix '* data_matrix;

norms = diag (final_dist_pairs);

final_dist_pairs = bsxfun (@plus, norms, norms') - 2 * final_dist_pairs; Hope this helps!

% Another important thing, Never use the pdist function for MATLAB . This is a consistent evaluation, something like loops and takes a lot of time, possibly in O (N ^ 2)

-3
source

All Articles