Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
match matrix to closest values

Subject: match matrix to closest values

From: Y

Date: 9 Jun, 2013 22:50:10

Message: 1 of 6

Here's a function I wrote. It creates a matrix with the same dimensions as 'needle', placing in each element the closest value from 'haystack':

function [val] = closest(haystack, needle)
    [~, i] = min(abs( ...
         repmat(reshape(haystack,numel(haystack),1),1,numel(needle)) - ...
         repmat(reshape(needle,1,numel(needle)),numel(haystack),1) ...
        ), [], 1);
    val = reshape(haystack(i), size(needle));
end

I'd appreciate suggestions & improvements.

-- kwikwag

Subject: match matrix to closest values

From: dpb

Date: 10 Jun, 2013 17:57:59

Message: 2 of 6

On 6/9/2013 5:50 PM, Y wrote:
> Here's a function I wrote. It creates a matrix with the same dimensions
> as 'needle', placing in each element the closest value from 'haystack':
>
> function [val] = closest(haystack, needle)
> [~, i] = min(abs( ...
> repmat(reshape(haystack,numel(haystack),1),1,numel(needle)) - ...
> repmat(reshape(needle,1,numel(needle)),numel(haystack),1) ...
> ), [], 1);
> val = reshape(haystack(i), size(needle));
> end
>
> I'd appreciate suggestions & improvements.

You can simply use (:) for the two reshape() inside the repmat() calls

I'd guess could be written w/ bsxfun() but didn't try it...not that it
would likely perform any better...

--

Subject: match matrix to closest values

From: Bruno Luong

Date: 10 Jun, 2013 19:24:12

Message: 3 of 6

dpb <none@non.net> wrote in message <kp5433$adc$1@speranza.aioe.org>...
> On 6/9/2013 5:50 PM, Y wrote:

>
> I'd guess could be written w/ bsxfun() but didn't try it...not that it
> would likely perform any better...

bsxfun is much safer in term of memory consumption. It is always preferable method.

Back to the question, there is no need to compare all the pairs. This should do:

h = unique(haystack(:))
val = interp1(h,h,needle,'nearest')

% Bruno

Subject: match matrix to closest values

From: dpb

Date: 10 Jun, 2013 19:46:12

Message: 4 of 6

On 6/10/2013 2:24 PM, Bruno Luong wrote:
...

> Back to the question, there is no need to compare all the pairs. This
> should do:
>
> h = unique(haystack(:))
> val = interp1(h,h,needle,'nearest')
...

Yeah, good catch, Bruno. OP might want to add

val = interp1(h,h,needle,'nearest','extrap')

to pick end points if input runs off ends rather than return NaN but
that'll be an implementation/use choice...

--

Subject: match matrix to closest values

From: Y

Date: 15 Jun, 2013 10:46:09

Message: 5 of 6

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <kp594s$rpl$1@newscl01ah.mathworks.com>...
> dpb <none@non.net> wrote in message <kp5433$adc$1@speranza.aioe.org>...
> > On 6/9/2013 5:50 PM, Y wrote:
>
> >
> > I'd guess could be written w/ bsxfun() but didn't try it...not that it
> > would likely perform any better...
>
> bsxfun is much safer in term of memory consumption. It is always preferable method.
>
> Back to the question, there is no need to compare all the pairs. This should do:
>
> h = unique(haystack(:))
> val = interp1(h,h,needle,'nearest')
>
> % Bruno

That's a good way to use interp1 I wasn't aware of, thanks.
Do you have a suggestion on how to get back the indices back from interp1? Or is the best one find(ismember(h,val))?

My application has lambdas_ewald_hkl (3D matrix), lambdas (vector) and spectrum_intensity (vector), and needs the spectrum_intensity matching (in indices) spectrum_intensity closest to each value in lambdas. That is, I now use:

    [~,lambda_indices_hkl] = closest(lambdas, lambdas_ewald_hkl);
    lambda_intensities_hkl = spectrum_intensity(lambda_indices_hkl);

Subject: match matrix to closest values

From: Bruno Luong

Date: 16 Jun, 2013 07:34:10

Message: 6 of 6

"Y " <nospamhere@dispostable.org> wrote in message <kphglh$klb$1@newscl01ah.mathworks.com>...
>
> That's a good way to use interp1 I wasn't aware of, thanks.
> Do you have a suggestion on how to get back the indices back from interp1? Or is the best one find(ismember(h,val))?

Simply do this:

idx = interp1(h,1:length(h),needle,'nearest')

% Bruno

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us