Round a set to the nearest values in another set (2D), faster algorithm with Matlab

2.5k Views Asked by At

Given a set of numbers, like

A={{1,2.5,3},
   {4.2,7,10}};

and another set of numbers, like

B={1,2,3,4,5};

Is there a fast algorithm to round A to the nearest values in B?

result = {{1,3,3},
          {4,5,5}};

we can write a intuitive program with Matlab by calculating the distance of every element of A with all the values in B, and get the index of the number with "min" in Matlab, but is there a faster way to do this?

The current method relies on enumerating over every element in A, is there a method to enumerate row by row, or over the whole set at once?

3

There are 3 best solutions below

0
On BEST ANSWER

If you have the data in the form of numeric arrays (that is, A is a matrix and B is a vector, as opposed to cell arrays as in your example), it can be done in one line, using interp1 with the 'nearest' and 'extrap' options. The former option specifies nearest-neighbour method of interpolation; the latter indicates that values may be outside the original range. See documentation for further details.

A = [1,2.5,3,
     4.2,7,10];
B = [1,2,3,4,5];

result = interp1(B,B,A,'nearest','extrap');
0
On

Step 1: Sort set $B$ and receive a sorted array with $B$'s elements.

Step2: For each element in $A$, search for the closest element in the sorted array of $B$ using binary search.

Complexity: $O((m+n)logm)$ where $m=|B|, n=|A|$.

1
On

Suppose both $A$ and $B$ are row vectors.

What we're going to do is look at each element of $A$, and compute the distance to each element in $B$:

Ap = zeros(size(A));
for i=1:length(A)
    a = A(i);
    [mn,idx] = abs(B-a); % A vector plus/minus a scalar acts elementwise.
    Ap(i) = B(idx);
end

It's possible to do this in 2 lines of code without looping, but I don't have my MATLAB install handy, so I don't want to post an unverified solution.