Cumulative Summation in intervals - MATLAB
Asked Answered
C

2

9

Suppose I have 2 input vectors x and reset of the same size

x = [1 2 3 4 5 6]
reset = [0 0 0 1 0 0]

and an output y which is the cumulative sum of the elements in x. Whenever the value of resets corresponds to 1, the cumulative sum for the elements reset and start all over again just like below

y = [1 3 6 4 9 15]

How would I implement this in Matlab?

Candless answered 9/5, 2015 at 9:42 Comment(0)
C
8

One approach with diff and cumsum -

%// Setup few arrays: 
cx = cumsum(x)         %// Continuous Cumsumed version
reset_mask = reset==1  %// We want to create a logical array version of 
                       %// reset for use as logical indexing next up

%// Setup ID array of same size as input array and with differences between 
%// cumsumed values of each group placed at places where reset==1, 0s elsewhere
%// The groups are the islands of 0s and bordered at 1s in reset array.
id = zeros(size(reset))
diff_values = x(reset_mask) - cx(reset_mask)
id(reset_mask) = diff([0 diff_values])

%// "Under-compensate" the continuous cumsumed version cx with the 
%// "grouped diffed cumsum version" to get the desired output
y = cx + cumsum(id)
Celik answered 9/5, 2015 at 10:1 Comment(4)
Hey, it works great but would you be able to explained this section of the code. id(reset==1) = diff([0 diff1(reset==1)])Candless
@Candless Sure, coming up.Celik
Thanks so much. Have been scratching my head on this for a while now.Candless
@LuisMendo Thanks, Yours was good alternative approach too! +1 already for you :)Celik
M
5

Here's a way:

result = accumarray(1+cumsum(reset(:)), x(:), [], @(t) {cumsum(t).'});
result = [result{:}];

This works because if the first input to accumarray is sorted, the order within each group of the second input is preserved (more about this here).

Maible answered 9/5, 2015 at 10:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.