Find max values of n previous values in a matrix without a loop.

Hello,
I have a single column matrix and need to add a second column containing on each row the highest value of n previous row.
For example, my matrix would have this column:
Column1
1
4
3
6
3
5
4
7
2
5
6
1
I am looking to add a column containing the high value of 3 previous rows (including the current row) in the first column, so that I would obtain:
Column1 Column2
1 NaN
4 NaN
3 4
6 6
3 6
5 6
4 5
7 7
2 7
5 7
6 6
1 6
Is it possible in Matlab without a for to loop?
Many thanks,
Libor

 Accepted Answer

a = randi(10,10,1);
your_result = max([a, circshift(a,1), circshift(a,2)],[],2);
your_result(1:2) = NaN;

8 Comments

Thank you so much, Jose-Luis!
Am I correct to think that this would be faster than using a for to loop?
My pleasure.
I don't know if this would be faster than a loop. Best way to find out is to test it. There are probably more efficient ways, in any case. arrayfun() is probably not one of them.
OK, thanks.
Also, how would this scale to an arbitrary number of values to compare? I gave the value of 3 as an example, but realistically, I would need this code to work with a lookback of up to 50 or so...
https://de.mathworks.com/help/matlab/ref/movmax.html
Best wishes
Torsten.
Thank you Thorsten, this is actually the best answer, I believe. I don't think I can accept it as such, though, as you entered it in a comment and not as an answer...
If you want to set the number of shifts programatically;
numRep = 50;
a = randi(10,10,1);
xx = size(a,1);
idx = bsxfun(@minus,[2:xx+1]',1:numRep);
idx(idx<1) = xx - abs(mod(idx(idx<1), -xx))
your_array = max(a(idx),2);
Thank you again, Jose-Luis! I really appreciate your help!
My pleasure. I had no idea something like movmax() existed, and it is indeed a better answer.
It was fun coming up with this anyway.

Sign in to comment.

More Answers (2)

The simplest solution is to download Jos's excellent FEX submission slidefun, which works for all MATLAB versions (movmax was introduced in R2016a):
V = [1;4;3;6;3;5;4;7;2;5;6;1];
N = 3; % window size
W = slidefun(@max,N,V,'backward');
W(1:N-1) = NaN;
And checking the answer:
>> [V,W]
ans =
1 NaN
4 NaN
3 4
6 6
3 6
5 6
4 5
7 7
2 7
5 7
6 6
1 6

1 Comment

Thank you very much Stephen, this also does exactly what I need, although as per Torsten's comment above, there are apparently built-in and optimized functions in Matlab now. Thanks again!

Sign in to comment.

Actually, the simplest solution is to use movmax (since R2016a):
v = [1 4 3 6 3 5 4 7 2 5 6 1].';
n = 3;
[v, [nan(n-1, 1); movmax(v, n, 'EndPoints', 'discard')]]
edit: which I see was already suggested by Torsten in the hidden comments

1 Comment

Yes. :)
But thank you anyhow, Guillaume! I really appreciate all help. Et... Bonne annee! ;)

Sign in to comment.

Asked:

on 3 Jan 2017

Edited:

on 4 Jan 2017

Community Treasure Hunt

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

Start Hunting!