0

I had this problem assigned to me in class. I'm still learning MATLAB, so I couldn't figure out how to solve this one using indices. The problem is: Given a row vector of numbers, find the indices of the two closest numbers. For instance:

[index1 index2]=nearestNumbers([2 6 3 13 0 -16.1])
This would output:
index1 = 1
index2 = 3
Since the numbers 2 and 3 in the vector are closer to each other than 
any other pair of numbers

I'm guessing I need to use the find function here (somewhere along the lines of y = find(min()) ) but I'm just not sure how to translate that into a coherent line of code. I tried using the find function I mentioned, but it just gives me a vector row of 0's. Your help would really be appreciated!

2 Answers2

2

No loops, just bsxfun:

>> B = abs( bsxfun(@minus, A, A' ) ); %//'
>> B( 1: (numel(A)+1) : end ) = inf; % ignore zeros on diagonal
>> [ii jj] = find( B == min(B(:)) );
Shai
  • 111,146
  • 38
  • 238
  • 371
  • Thank you for your input. I tried your code out, but I keep getting columns of 1:6 for both ii and jj. Is there a way to remedy this? – John Wayne's Stunt Double Jul 07 '13 at 19:09
  • @JohnWayne'sStuntDouble - my bad. The smallest distances are those of each element to itself (the diagonal). I corrected my solution to ignore these distances. Please see my updated solution. – Shai Jul 08 '13 at 06:53
  • @JohnGalt - thanks for spotting the problem. I corrected my solution now. – Shai Jul 08 '13 at 06:53
-1

Try to get a distance function for each index to every other index.

for i=1:length(A)
   for j=1:i
      B(i,j)=NaN;
   end
   for j=i+1:length(A)
      B(i,j)=abs(A(i)-A(j));
   end
end

B =

       NaN    4.0000    1.0000   11.0000    2.0000   18.1000
       NaN       NaN    3.0000    7.0000    6.0000   22.1000
       NaN       NaN       NaN   10.0000    3.0000   19.1000
       NaN       NaN       NaN       NaN   13.0000   29.1000
       NaN       NaN       NaN       NaN       NaN   16.1000
       NaN       NaN       NaN       NaN       NaN       NaN

[ind1,in2]=find(B==min(min(B)))

ind1 =

 1

ind2 =

 3
Zero
  • 74,117
  • 18
  • 147
  • 154
  • nested loop? `min(min(B))`? – Shai Jul 07 '13 at 18:56
  • min(min(B)) gives the minimum value of the matrix. min(B) gives column minimum. @Shai's solution is efficient. – Zero Jul 07 '13 at 18:59
  • Are you sure `min` works correctly for your example? The `NaN`s don't bother it? Shouldn't you replace `min` with `nanmin`? – Shai Jul 07 '13 at 19:02
  • what version of matlab are you running? – Shai Jul 07 '13 at 19:05
  • R2010a. Check your solution. It doesn't give single ouput in my system. – Zero Jul 07 '13 at 19:07
  • Thanks John, your solution works great. However, our professor's beating the `for loops` out of us for the sake of understanding the coding process. Would using `length` without a `for loop` be feasible? Or would that simply be too long for practicality? – John Wayne's Stunt Double Jul 07 '13 at 19:16
  • @JohnWayne'sStuntDouble - for a solution without `for` loops you'll have to do something similar to my solution using `bsxfun`. `length` only gives you the number of elements in `A`, it cannot help you figure out the distances. – Shai Jul 08 '13 at 06:55