# Find maximum array values avoiding mat2cell.

1 view (last 30 days)

Show older comments

Santos García Rosado
on 28 Dec 2020

Commented: Santos García Rosado
on 4 Jan 2021

Hello Matlab community.

I was wondering if someone could give me a hand with a code problem I've been having for a while.

So I have an array A =1xn such as:

(NaN, NaN, NaN, NaN, 1, 6, 8, 32, -5, NaN,NaN,NaN,NaN,NaN,NaN, 65, 2 ,16 80, 35, 26, 12, NaN, ..., n).

As you can tell, both the NaN and numeric lenghts do not follow any pattern. The main idea is trying to get the maximum value of each numeric string and being able to get this sort of array as an output:

(NaN, NaN, NaN, NaN, 0, 0, 0, 32, 0, NaN,NaN,NaN,NaN,NaN,NaN, 0, 0 ,0 80, 0, 0, 0, NaN, ..., n).

I'd like to do it without using the mat2cell function since later on I'll have to use the code for Simulink and this kind of function is not allowed by the software.

My first idea was using the common max function:

[value, position] = max(A);

Obviously this will only give me the maximum number of the whole array.

It would be great if someone could help me out. Thank's in advanced!

##### 2 Comments

Rik
on 28 Dec 2020

### Accepted Answer

Bruno Luong
on 28 Dec 2020

Edited: Bruno Luong
on 28 Dec 2020

Just a for-loop (is it allowed in Simulink?)

A=[NaN, NaN, NaN, NaN, 1, 6, 8, 32, -5, NaN,NaN,NaN,NaN,NaN,NaN, 65, 2 ,16 80, 80, 35, 26, 12, NaN];

imax = [];

Amax = -Inf;

for i=1:length(A)

if isnan(A(i))

imax = [];

Amax = -Inf;

else

if A(i) > Amax

A(imax) = 0;

imax = i;

Amax = A(imax);

else

A(i) = 0;

end

end

end

##### 5 Comments

### More Answers (3)

Jan
on 30 Dec 2020

Edited: Jan
on 30 Dec 2020

For the expanded question in the comment to Bruno's solution you ask for the n largest elements:

A = [NaN, NaN, NaN, NaN, 1, 6, 8, 32, -5, NaN,NaN,NaN,NaN,NaN,NaN, 65, 2 ,16 80, 35, 26, 12, NaN]

n = 3;

BlockMaxK(A, n)

% NaN, NaN, NaN, NaN, 0, 6, 8, 32, 0, NaN, NaN, NaN, NaN, NaN, NaN, 65, 0, 0, 80, 35, 0, 0, NaN

function B = BlockMaxK(A, n)

m = [true, isnan(A), true];

ini = strfind(m, [true, false]);

fin = strfind(m, [false, true]) - 1;

B = nan(size(A));

for k = 1:numel(ini)

ik = ini(k);

fk = fin(k);

[v, ind] = maxk(A(ik:fk), n);

B(ik:fk) = 0;

B(ik - 1 + ind) = v;

end

end

Bruno Luong
on 30 Dec 2020

Edited: Bruno Luong
on 30 Dec 2020

This is a method for multiple maxima by block.

I post this for illustration of algorithmic mainly, because the real performance is rather poor, but it should be good theoretically. It uses the so called red-black tree structure, something that MATLAB really miss for decades, and I lost all my fate to see it available one day.

Such method is kind of sequential, meaning it just scan once the data and more adatped for problems where the data are avaiblable sequantially in time (thus simullink framework). Unfortunately the RedBlack library is not as fast as if it was implemented natively in C/C++.

This method can also be seen as an extension of my answer for the original question of single maximum by block.

A=[NaN, NaN, NaN, NaN, 1, 6, 8, 32, -5, NaN,NaN,NaN,NaN,NaN,NaN, 65, 2 ,16 80, 80, 35, 26, 12, NaN]

k = 3;

% FEX file By Brian Moore

% https://www.mathworks.com/matlabcentral/fileexchange/45123-data-structures

T = RedBlackTree();

for i=1:length(A)

if isnan(A(i))

T.Clear();

else

Insert = T.Count < k;

if ~Insert

Min = T.Minimum();

Insert = A(i) > Min.key;

if Insert

A(Min.value) = 0;

T.Delete(Min);

else

A(i) = 0;

end

end

if Insert

T.Insert(A(i),i);

end

end

end

For a better solution, see Jan's answer.

Image Analyst
on 28 Dec 2020

Edited: Image Analyst
on 28 Dec 2020

If you have the Image Processing Toolbox you can use regionprops() to ask for the MaxIntensity:

A=[NaN, NaN, NaN, NaN, 1, 6, 8, 32, -5, NaN,NaN,NaN,NaN,NaN,NaN, 65, 2 ,16 80, 80, 35, 26, 12, NaN];

[labeledGroups, numGroups] = bwlabel(~isnan(A))

props = regionprops(labeledGroups, A, 'MaxIntensity');

maxIntensities = [props.MaxIntensity]

output = zeros(size(A));

output(isnan(A)) = nan;

for group = 1 : numGroups

thisGroup = ismember(labeledGroups, group);

% Find out where in this group the max intensity occurs.

indexes = (A .* thisGroup) == maxIntensities(group);

output(indexes) = maxIntensities(group);

end

output % Show in command window.

You'll get

numGroups =

2

maxIntensities =

32 80

output =

Columns 1 through 19

NaN NaN NaN NaN 0 0 0 32 0 NaN NaN NaN NaN NaN NaN 0 0 0 80

Columns 20 through 24

80 0 0 0 NaN

### See Also

### Categories

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!