Question

How can I find the closest element in a matrix in matlab?

Suppose I have a matrix of the size 300x200 and I want to find the value and the index of the element in the matrix which is the closest to a element given.

Does anyone know how this can be done in matlab? I know how to do this for a given array but I can not figure out how this is done for a matrix.

Was it helpful?

Solution 2

A smaller case might help you understand -

Code

%%// Given big matrix, taken as a matrix of random numbers for demo
a1 = rand(10,5); %%// Replace this with your 300X200 matrix

%// For demo, let us assume, you are looking for the element that happens to be closest to the element in the 4th row and 5th column, which will be verified at the end 
element = a1(4,5)+0.00001; %%// The element in search

%%// Find the linear index of the location
[~,ind] = min(reshape(abs(bsxfun(@minus,a1,element)),numel(a1),[]));

%%// Convert the linear index into row and column numbers
[x,y] = ind2sub(size(a1),ind) 

Output

x =
     4

y =  
     5

As can be seen, the output matches the expected answer.

Extended Part: If you have a set of search numbers, you can process them for closeness very efficiently using bsxfun. This is shown below -

Code

%%// Given big matrix, taken as a matrix of random numbers for demo
a1 = rand(10,5); %%// Replace this with your 300X200 matrix

%// For an array of search numbers
search_array = [a1(4,5)+0.00001;a1(6,5)+0.00001;a1(4,4)+0.00001;a1(4,2)+0.00001];

%%// Find the linear index of the location
[~,ind] = min(abs(bsxfun(@minus,a1(:),search_array')));%//'

%%// Convert the linear index into row and column numbers
[x,y] = ind2sub(size(a1),ind) 

Output

x =
     4     6     4     4


y =
     5     5     4     2

OTHER TIPS

Let matrix denote your matrix, and ref denote the reference value you want to get closest to. Then you can use

[value, ii] = min(abs(matrix(:)-ref));    %// linear index of closest entry
[row, col] = ind2sub(size(matrix), ii);   %// convert linear index to row and col

value gives the value of the closest entry; and row, col give its row and column indices.

Divakar answer is good, and bsxfun() is a very useful function to learn, but I think in this case it's a bit of an overkill. Here you have another way of doing it using linear indexing for the matrix a:

a=rand(3);

a1=a(1,2)+0.001;

[~,ind]=min(abs(a(:)-a1));

[x,y]=ind2sub(3,ind);

Hope that helps!

An inline function can be created to do this task based on Jana's solution. This solution only works on vectors.

    nearest_index = @(vector,element) find(abs(element-vector) == min(abs(element-vector)));

    vector = [9 8 7 6 5 4 3 2 1];
    element = 3.1;
    index = nearest_index(vector,element);
    value = vector(index);

When combined with Divakars solution an inline function can be created which will perform the requested task. The function itself is complicated, but its usage is simple.

    nearest_index = @(matrix,element) find(abs( ...
        repmat(element,size(matrix)) - matrix) == ...
        min(reshape(abs(repmat(element,size(matrix)) - matrix), ...
        [1,numel(abs(repmat(element,size(matrix)) - matrix))])));

    matrix = rand(10,5); 
    element = matrix(4,5)+0.00001;
    [x, y] = nearest_index (matrix,element) 
    value = matrix(x,y)

Even faster can be

a=rand(10,10);

element=a(3,4)+0.00001;

[x,y]=find(abs(a-element)==min(abs(a-element)))

at least in the case I used it

I was doing more homework assignments from MIT's OCW (question number 5) and this thread helped me a lot! So I came with another solution in which all of you contributed somehow.

If you want to represent this as a function, it could be written like this.

function [n, m]=findNearest(x, y)
theAbs=abs((x(:))-y); % Calculates absolute value of the difference
minValues=find(theAbs==min(theAbs)); % finds the position where one or more numbers match the criteria
[n, m]=ind2sub(size(x), minValues); % Returns one or multiples values and their indices, if the distance between them is the same.
return 

I've tried this with row vectors, column vectors and matrices. It works for all of them. The outcome is n (for rows) and m (for columns). If there are two or more values that are equally distant, the values of n and m will be larger too. Let's say we have 3 values that are equally close to our reference, our outcome should have n= n1, n2, n3 and m= m1, m2, m3. Where the position of every value is (n1, m1), (n2, m2) and (n3, m3).

An example of it's use:

x=eye(4,4);
y=1.698;
[a, b]=findNearest(x, y)

The outcome is:

a =

     1
     2
     3
     4


b =

     1
     2
     3
     4

Hope this helps a bit :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top