How to find the closest value pair in a matrix?
27 views (last 30 days)
Show older comments
I have two numbers 0.85 and 1.25. I would like to find the closest pair of columns that contains both these values. I.e. A = [0.84 1.26; 0.90 1.24; 0.83 1.30]; and intersted pair is [0.85 1.25]. The closest pair from [0.85 1.25] is [0.84 1.26]. The difference is [-0.01 0.01], while for other pairs the difference is [0.04 -0.01] and [0.02 0.04]. So is there any way, I can make trial and error and find the closest pair of columns that has closest values? I tried following code, but it is not sufficient.
A = [0.84 1.26; 0.90 1.24; 0.83 1.30];
Pairs = [0.85 1.25];
for i = 1:size(Pairs,1)
loc = ismember(A,Pairs(i,:));
index(i,:)=find(sum(loc,2)==numel(Pairs(i,:)))';
end
Any help will be greatly appriciated. Thank you so much in advance!
2 Comments
Torsten
on 17 Jul 2023
Is it given that A has only two columns and that the numbers in A and Pairs are in ascending order ?
Accepted Answer
John D'Errico
on 17 Jul 2023
Assuming that you have a much larger problem, and that you have multiple points, to test, knnsearch is the correct tool.
A = [0.84 1.26; 0.90 1.24; 0.83 1.30];
B = [0.85 1.25;.80 1.31];
IDX = knnsearch(A,B)
So point number 1 in A is the closest to B(1,:), and point 3 in A is the closest to B(2,:).
Note that knnsearch will be much faster than exhaustively testing the points to see which is closest.
A = rand(1e6,2);
B = rand(1e5,2);
tic, IDX = knnsearch(A,B);toc
So only a little over a second to identify the nearest point in A for all of the 100000 points in B.
0 Comments
More Answers (3)
Voss
on 17 Jul 2023
A = [0.84 1.26; 0.90 1.24; 0.83 1.30];
Pairs = [0.85 1.25];
[~,idx] = min((Pairs(:,1).'-A(:,1)).^2 + (Pairs(:,2).'-A(:,2)).^2, [], 1);
closest = A(idx,:)
Note that the above method also works when you have multiple rows in Pairs:
% 3 points to find the closest point in A to:
Pairs = [0.85 1.25; 0.9 1.1; 0.95 1.4];
[~,idx] = min((Pairs(:,1).'-A(:,1)).^2 + (Pairs(:,2).'-A(:,2)).^2, [], 1);
closest = A(idx,:)
1 Comment
Steven Lord
on 17 Jul 2023
You can simplify and generalize the computation of the data you pass into your min call using vecnorm.
A = [0.84 1.26; 0.90 1.24; 0.83 1.30];
Pairs = [0.85 1.25];
distance1 = (Pairs(:,1).'-A(:,1)).^2 + (Pairs(:,2).'-A(:,2)).^2
distance2 = vecnorm(Pairs-A, 2, 2).^2 % 2-norm squared along dimension 2
This also lets you experiment with other norms.
distance3 = vecnorm(Pairs-A, 1, 2).^2 % 1-norm squared
distance4 = vecnorm(Pairs-A, Inf, 2).^2 % Inf-norm squared
Bruno Luong
on 17 Jul 2023
For A that has at least 3 rows and the closest in the sense of l2 norm (auclidian distance), without the need of toolbox.
A = [0.84 1.26; 0.90 1.24; 0.83 1.30]
Pairs = [0.85 1.25]
T = delaunayTriangulation(A)
T.Points(T.nearestNeighbor(Pairs),:)
It can also handle a very large number of points
A = rand(1e6,2);
B = rand(1e5,2);
tic
T = delaunayTriangulation(A);
T.nearestNeighbor(B);
toc
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!