How to find the closest value pair in a matrix?

42 次查看(过去 30 天)
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 个评论
Torsten
Torsten 2023-7-17
Is it given that A has only two columns and that the numbers in A and Pairs are in ascending order ?
Megha
Megha 2023-7-17
Yes, we can consider that A has only two columns but Pairs may not be in ascending order always..@Torsten

请先登录,再进行评论。

采纳的回答

John D'Errico
John D'Errico 2023-7-17
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)
IDX = 2×1
1 3
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
Elapsed time is 1.404760 seconds.
So only a little over a second to identify the nearest point in A for all of the 100000 points in B.

更多回答(3 个)

Voss
Voss 2023-7-17
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,:)
closest = 1×2
0.8400 1.2600
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,:)
closest = 3×2
0.8400 1.2600 0.9000 1.2400 0.8300 1.3000
  1 个评论
Steven Lord
Steven Lord 2023-7-17
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
distance1 = 3×1
0.0002 0.0026 0.0029
distance2 = vecnorm(Pairs-A, 2, 2).^2 % 2-norm squared along dimension 2
distance2 = 3×1
0.0002 0.0026 0.0029
This also lets you experiment with other norms.
distance3 = vecnorm(Pairs-A, 1, 2).^2 % 1-norm squared
distance3 = 3×1
0.0004 0.0036 0.0049
distance4 = vecnorm(Pairs-A, Inf, 2).^2 % Inf-norm squared
distance4 = 3×1
0.0001 0.0025 0.0025

请先登录,再进行评论。


Torsten
Torsten 2023-7-17
移动:Torsten 2023-7-17
A = [0.84 1.26; 0.90 1.24; 0.83 1.30];
Pairs = [0.85 1.25];
Ah = sort(A, 2, 'ascend')
Ah = 3×2
0.8400 1.2600 0.9000 1.2400 0.8300 1.3000
Pairsh = sort(Pairs,'ascend')
Pairsh = 1×2
0.8500 1.2500
[~,idx] = min(sum(abs(Ah-Pairsh),2))
idx = 1
A(idx,:)
ans = 1×2
0.8400 1.2600

Bruno Luong
Bruno Luong 2023-7-17
For A that has at least 3 rows and the closest in the sense of l2 norm (auclidian distance), without the need of toolbox.
But if you have the toolbox @John D'Errico solution is faster.
A = [0.84 1.26; 0.90 1.24; 0.83 1.30]
A = 3×2
0.8400 1.2600 0.9000 1.2400 0.8300 1.3000
Pairs = [0.85 1.25]
Pairs = 1×2
0.8500 1.2500
T = delaunayTriangulation(A)
T =
delaunayTriangulation with properties: Points: [3×2 double] ConnectivityList: [2 3 1] Constraints: []
T.Points(T.nearestNeighbor(Pairs),:)
ans = 1×2
0.8400 1.2600
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
Elapsed time is 4.397585 seconds.
  1 个评论
Megha
Megha 2023-7-19
Thank you @Torsten, @John D'Errico, @Voss, @Steven Lord for giving your valuable time. I agree that other methods works too but knnsearch was the quick and easy one for me to adapt! I appriciate your efforts.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Linear Algebra 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by