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:
masked max (without a for loop)

Subject: masked max (without a for loop)

From: Wazza

Date: 23 Apr, 2010 17:17:28

Message: 1 of 3

G'Day All,

Does anyone know if is possible to perfom max calculation for
alternating values of a mask without using a for loop?

e.g.
data = [ 1 2 3 4 5 6 7 1 2 3 4 5 6 1 2];
mask = [ 0 1 1 0 1 1 1 1 0 0 0 0 1 1 1];
mask_max = [ 1 3 3 4 7 7 7 7 5 5 5 5 6 6 6];

I have a feeling this should be possible, I just cant think of the
right functions.

-Wazza

Subject: masked max (without a for loop)

From: Thomas Clark

Date: 23 Apr, 2010 21:01:06

Message: 2 of 3

Wazza,

Disclaimer: It's 10pm on friday night - totally not thinking straight, so there may yet be a better alternative. Still, this might get you some way there.

I think sortrows() might help, although depending on the size of your data it may not be numerically very efficient. I think sortrows will be quicker than a direct for-loop, but know that there is room for improvement in the underlying sorting algorithm it uses.

Don't have matlab running here, so errors and ommissions excepted - but code should probably go like this:

% Define a vector with a 1 wherever a change is made
dmask = [0 abs(diff(mask))]
% data = [ 1 2 3 4 5 6 7 1 2 3 4 5 6 1 2];
% mask = [ 0 1 1 0 1 1 1 1 0 0 0 0 1 1 1];
% dmask = [ 0 1 0 1 1 0 0 0 1 0 0 0 1 0 0];

% Accumulate that to give ascending, unique values:
cumdmask = cumsum(dmask);
% cumdmask = [ 0 1 1 2 3 3 3 3 4 4 4 4 5 5 5];

% Use sortrows to sort in descending order
% within the groups defined by cumdmask:
inds = 1:numel(data);
sorting_array = [cumdmask', data', inds];
sorted = sortrows(sorting_array, [1 -2]);

% Select the data you want
max_vals = sorted(:, 2);

% And index back into a results array using cumdmask. Note the addition +1 to give one-based indexing.
results = max_vals(cumdmask(:)+1);

In the sortrows command, I included an 'inds' array, which can be used to determine indices of the maximum locations into the original dataset if required, with:
orig_inds = sorted(cumdmask(:)+1,3).
If not required, sortrows can be sped up by ommitting this from the input matrix.

Hope this helps

Tom Clark








Wazza <the.duckman@gmail.com> wrote in message <11757c5e-891a-4a02-af53-0199f6836e1f@g1g2000pre.googlegroups.com>...
> G'Day All,
>
> Does anyone know if is possible to perfom max calculation for
> alternating values of a mask without using a for loop?
>
> e.g.
> data = [ 1 2 3 4 5 6 7 1 2 3 4 5 6 1 2];
> mask = [ 0 1 1 0 1 1 1 1 0 0 0 0 1 1 1];
> mask_max = [ 1 3 3 4 7 7 7 7 5 5 5 5 6 6 6];
>
> I have a feeling this should be possible, I just cant think of the
> right functions.
>
> -Wazza

Subject: masked max (without a for loop)

From: Wazza

Date: 24 Apr, 2010 01:11:12

Message: 3 of 3

On Apr 24, 5:01 am, "Thomas Clark" <t.cl...@remove.spamcantab.net>
wrote:
> Wazza,
>
> Disclaimer: It's 10pm on friday night - totally not thinking straight, so there may yet be a better alternative. Still, this might get you some way there.
>
> I think sortrows() might help, although depending on the size of your data it may not be numerically very efficient. I think sortrows will be quicker than a direct for-loop, but know that there is room for improvement in the underlying sorting algorithm it uses.
>
> Don't have matlab running here, so errors and ommissions excepted - but code should probably go like this:
>
> % Define a vector with a 1 wherever a change is made
> dmask = [0 abs(diff(mask))]
> % data      = [ 1 2 3 4 5 6 7 1 2 3 4 5 6 1 2];
> % mask    = [ 0 1 1 0 1 1 1 1 0 0 0 0 1 1 1];
> % dmask   = [ 0 1 0 1 1 0 0 0 1 0 0 0 1 0 0];
>
> % Accumulate that to give ascending, unique values:
> cumdmask = cumsum(dmask);
> % cumdmask = [ 0 1 1 2 3 3 3 3 4 4 4 4 5 5 5];
>
> % Use sortrows to sort in descending order
> % within the groups defined by cumdmask:
> inds = 1:numel(data);
> sorting_array = [cumdmask', data', inds];
> sorted = sortrows(sorting_array, [1 -2]);
>
> % Select the data you want
> max_vals = sorted(:, 2);
>
> % And index back into a results array using cumdmask. Note the addition +1 to give one-based indexing.
> results = max_vals(cumdmask(:)+1);
>
> In the sortrows command, I included an 'inds' array, which can be used to determine indices of the maximum locations into the original dataset if required, with:
> orig_inds = sorted(cumdmask(:)+1,3).
> If not required, sortrows can be sped up by ommitting this from the input matrix.
>
> Hope this helps
>
> Tom Clark
>
> Wazza <the.duck...@gmail.com> wrote in message <11757c5e-891a-4a02-af53-0199f6836...@g1g2000pre.googlegroups.com>...
> > G'Day All,
>
> > Does anyone know if is possible to perfom max calculation for
> > alternating values of a mask without using a for loop?
>
> > e.g.
> > data           = [ 1 2 3 4 5 6 7 1 2 3 4 5 6 1 2];
> > mask         = [ 0 1 1 0 1 1 1 1 0 0 0 0 1 1 1];
> > mask_max = [ 1 3 3 4 7 7 7 7 5 5 5 5 6 6 6];
>
> > I have a feeling this should be possible, I just cant think of the
> > right functions.
>
> > -Wazza

Cheers Mate.

I think that may get me some of the way there.
I'll work at it ans see how it goes.

-Wazza

Tags for this Thread

No tags are associated with 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