# Find closest value in array

5,002 views (last 30 days)
Chiranjibi on 25 Aug 2014
Edited: Marc Vaillant on 26 Apr 2020
I have two vector(which are time stamps) like,
V N
1375471092848936 1375473384440853
1375473388165900 1375471277856598
1375471320476780 1375473388165900
1375473388947681 1375471322465961
1375473392527002 1375471335206288
.................. ..................
My goal is to find closest time in N with respect to V (i.e. find time in N which is nearly equal with V). My frame is W = 1e4, furthermore V should lies between N-W and N+W. So how do I get closest time through MATLAB? Any help would be appreciated.
Thanks

Joe S on 10 Sep 2018
Edited: MathWorks Support Team on 27 Nov 2018
To compute the closest value in a vector “N” for each element of “V”, try the following code with example vectors “N” and “V”:
V = randi(10,[5 1])
N = randi(10,[5 1])
A = repmat(N,[1 length(V)])
[minValue,closestIndex] = min(abs(A-V))
closestValue = N(closestIndex)
Note that if there is a tie for the minimum value in each column, MATLAB chooses the first element in the column.

Abdullah Al on 20 Feb 2019
For MATLAB2015b (probably 2016a too) and earlier, use:
[minValue,closestIndex] = min(abs(bsxfun(@minus,A, V')))
John Snoap on 17 Apr 2020
At least as of R2020a, it seems as though
[minValue, closestIndex] = min(abs(N - V.'))
closestValue = N(closestIndex)
produces the same result, is more efficient, and uses less RAM than:
A = repmat(N,[1 length(V)])
[minValue,closestIndex] = min(abs(A-V.'))
closestValue = N(closestIndex)
So that would reduce the script to:
V = randi(10,[5 1])
N = randi(10,[5 1])
[minValue, closestIndex] = min(abs(N - V.'))
closestValue = N(closestIndex)
The biggest issue with repmat is that when the vectors become very large, out of memory errors are more likely to occur - that's what led me to try and find a solution to this problem that didn't use repmat.
Marc Vaillant on 24 Apr 2020
To make this solution consistent when the length of N is 1, a suggestion would be to change
[minValue,closestIndex] = min(abs(A-V'))
closestValue = N(closestIndex)
to
[minValue,closestIndex] = min(abs(A-V'),[],1)
closestValue = N(closestIndex')
Otherwise the min will return a scalar when the length of N is 1. Note the transpose on closestIndex also, otherwise you won't get a column vector when the length of N is 1.

Andrew Reibold on 25 Aug 2014
Edited: Andrew Reibold on 25 Aug 2014
This finds the value in N which is closest to the V value I am calling.
N = [1990 1998 2001 2004 2001]
V = [2000 2011 2010 2001 1998]
[c index] = min(abs(N-V(1)))
In this case Im looking for the closest value to 'V(1)' which is 2000. It should return the 3rd or 5th value of N which is 2001.
Note: 'index' is the index of the closest value. If two are the same, like in this example with two different '2001's, it will return the index of the first one.

Show 1 older comment
Image Analyst on 6 Oct 2017
Caution/Note: This solution only compares a row to the very same row in the other vector. My solution compares all rows to all other rows. So this solution might come up with, say, row 40 as the closest distance, but my solution might come up with a closer distance between row 34 or N with row 53 of V.
If you have the Statistics and Machine Learning Toolbox, you can also compute the distance between every element and every element of the other array using the function pdist2().
So it really depends if you want the closest distance between corresponding rows (this solution), or if you want the overall closest distance no matter what rows they may occur in (my solution).
reetu hooda on 17 Feb 2018
if N is just a decimal number and it is to be searched in a matrix V(containing decimal numbers). how would the code change?
Image Analyst on 17 Feb 2018
reetu, if N is just a single number then you can do this
[minDistance, indexOfMin] = min(abs(V-N));

Image Analyst on 25 Aug 2014
clc;
% Sample data
numberOfRows = 5;
V = rand(numberOfRows, 1)
N = rand(numberOfRows, 1)
% Find min distance
minDistance = inf;
for ni = 1 : numberOfRows
for vi = 1 : numberOfRows
distances(vi, ni) = abs(N(ni) - V(vi));
if distances(vi, ni) < minDistance
minNRow = ni;
minVRow = vi;
minDistance = distances(vi, ni);
end
end
end
% Report to command window:
distances
fprintf('Closest distance is %f which occurs between row %d of N and row %d of V\n',...
minDistance, minNRow, minVRow);
In the command window:
V =
0.5309
0.6544
0.4076
0.8200
0.7184
N =
0.9686
0.5313
0.3251
0.1056
0.6110
distances =
0.4378 0.0005 0.2057 0.4252 0.0801
0.3142 0.1231 0.3293 0.5488 0.0435
0.5610 0.1237 0.0825 0.3020 0.2033
0.1487 0.2886 0.4948 0.7144 0.2090
0.2503 0.1870 0.3932 0.6127 0.1074
Closest distance is 0.000470 which occurs between row 2 of N and row 1 of V

Aristo on 2 Nov 2017
@Image Analyst- is there a shortcut method to it or getting read of for loop and including all values between 0 and 0.2
Image Analyst on 2 Nov 2017
You can try this:
% Sample data
numberOfRows = 5;
V = rand(numberOfRows, 1)
N = rand(numberOfRows, 1)
% Find min distance
distances = pdist2(V, N)
[minDistance, index] = min(distances(:))
[minVRow, minNRow] = ind2sub(size(distances), index)
fprintf('The closest distance is %f which occurs between\nrow %d of V (%f) and\nrow %d of N (%f)\n',...
minDistance, minVRow, V(minVRow), minNRow, N(minNRow));
% Double-check / Prove it
V(minVRow) - N(minNRow)
Image Analyst on 10 Nov 2017
What's wrong with a for loop? And what is ni and vi?

Hi,
I have a matrix A of size [30x36] and B of size [38x36]. How do I find the closest pairs?
FYI- Those are the HOG Descriptors of block size 16x16 and cell size 8x8. I am trying to find the closest HOG descriptors.