1

I have two matrices:

A = [  76  159
      112  143
      153  159];

and

B = [  77   159
      114   143
      153   159
      173   236];

How can I get the nearest location with the result is the index of nearest location from another matrix without looping if possible.

For the above example, the result would look like this:

iA = 1 2 3;
iB = 1 2 3 3;
m.s.
  • 16,063
  • 7
  • 53
  • 88

2 Answers2

4

You can compute the distances between pairs of rows using pdist2 (Statistics Toolbox), and then find the minimizing index along each dimension:

d = pdist2(A,B);     % // default is Euclidean distance. You can specify other metrics
[~, iB] = min(d);    % // arg min along each column
[~, iA] = min(d.');  %'// arg min along each row

If you don't have the Statistics Toolbx, you can replace pdist2 with bsxfun to compute squared Euclidean distance:

d = squeeze(sum(bsxfun(@minus, A, permute(B,[3 2 1])).^2, 2));
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
1

Using bsxfun, permute and calculating Euclidean distance based on native approach

This may not look elegant, but its very faster than pdist2 for small data sizes

d = sqrt(sum((bsxfun(@minus,permute(A,[1 3 2]),permute(B,[3 1 2]))).^2,3));

[~, iB] = min(d);    %// from Luis's answer
[~, iA] = min(d.');

Bechmarking (performed after warming up several times)

tic
out = sqrt(sum((bsxfun(@minus,permute(A,[1 3 2]),permute(B,[3 1 2]))).^2,3));
toc

tic
d = pdist2(A,B); 
toc

Elapsed time is 0.000080 seconds.
Elapsed time is 0.000453 seconds.


Bench Marking performed (using timeit())for Different data sizes of A keeping Datasize of B constant at 20.

enter image description here


enter image description here

Conclusion: pdist2 is significantly efficient with large datasizes while bsxfun+permute could be used for very small data sizes.

Santhan Salai
  • 3,888
  • 19
  • 29