2015-05-09 32 views
8

Supponiamo di avere 2 ingressi vettori x e reset della stessa dimensioneSomma cumulativa in intervalli - MATLAB

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

ed un'uscita y che è la somma degli elementi in x. Ogni volta che il valore di ripristini corrisponde a 1, la somma cumulativa per gli elementi resettare e ricominciare tutto da capo, proprio come sotto

y = [1 3 6 4 9 15] 

Come dovrei implementare questo in Matlab?

risposta

7

Un approccio con diff e 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) 
+0

Ehi, funziona benissimo, ma sareste in grado di spiegare questa sezione del codice. id (reset == 1) = diff ([0 diff1 (reset == 1)]) – Alex

+0

@Alex Sure, in arrivo. – Divakar

+0

Grazie mille. Sono stato a grattarmi la testa su questo per un po 'di tempo. – Alex

4

Ecco un modo:

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

Questo funziona perché se il primo ingresso a accumarray è ordinato, l'ordine all'interno di ciascun gruppo del secondo ingresso è conservato (più su questo here).