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

Conditional cumsum - how to create?

Asked by Eric Sampson on 2 Apr 2013

This is probably easy, but my brain isn't working today...

How can you do the following operation in a vectorized way? I'd think it should be possible with some combination of cumsum, diff & logical indexing:

input = rand(10,1);
output = zeros(size(input);
output(1) = input(1);
for ind = 2:numel(input)
  dif = input(ind) - input(ind-1);
   if dif < 0
      output(ind) = output(ind-1) + dif;
   else
      output(ind) = output(ind-1);
   end
end

2 Comments

the cyclist on 2 Apr 2013

It would be useful if you also described conceptually what you are trying to do.

Eric Sampson on 2 Apr 2013

Basically it's a copy of the input, but anytime that the original increases from one val to the next, the output should be hold constant. Sort of like a copy that can only go down :)

Eric Sampson

Products

2 Answers

Answer by Roger Stafford on 2 Apr 2013
Accepted answer

Try this.

 outp = cumsum([inp(1);min(diff(inp),0)]);

1 Comment

Eric Sampson on 2 Apr 2013

Ding ding ding! Roger wins, to Matt's detriment :) Thanks!

Roger Stafford
Answer by Matt Tearle on 2 Apr 2013

There may be better ways, but this works:

d = [true;diff(input)<0];
idx = find(d);
output = input(idx(cumsum(d)));

When the array is large enough, there's a pretty decent speedup (~50x)

5 Comments

Eric Sampson on 2 Apr 2013

Argh, I'm sorry Matt. See my revised problem statement. This was clearly a case of 'do what I mean, not what I say' :)

Sean de Wolski on 2 Apr 2013

As you know, the DWIM Toolbox still hasn't been released to the public.

Eric Sampson on 2 Apr 2013

Sean, wasn't Loren or Steve supposed to be on that? Slackers.

Matt Tearle

Contact us