arrays - valor - sumatoria en matlab
MATLAB: Ventana del integrador(suma) móvil con tamaño variable, según una condición (2)
Me gustaría definir los índices de inicio y final de una ventana del integrador en movimiento (suma) en función de la suma acumulada de los valores de la array
. Cada ventana debe tener una suma acumulativa menor o igual a un umbral.
El end_index
de esta ventana se mueve uniformemente hacia adelante en 1 para las ventanas futuras, sin embargo, el start_index
depende de los valores de la array
. start_index
podría avanzar, permanecer igual o retroceder (valores negativos), por lo tanto, el tamaño de esta ventana en movimiento no es fijo.
Por ejemplo:
array = [ 1 0 2 1 1 2 0 0 1 2 0 1 0 1 1]
;
Con el start_index = 1
, la suma acumulativa de la array
será 5 en end_index = 5
, para la primera ventana.
Ahora para la próxima ventana, end_index
se adelanta por 1 de modo que el nuevo end_index = 6
. Me gustaría saber cómo puedo encontrar el nuevo start_index
mediante el cálculo posterior de la suma acumulada del nuevo end_index
modo que cumsum
sea menor o igual a 5 para la nueva ventana también. En este caso, el nuevo start_index = 4
.
¿Alguna sugerencia sobre cómo se podría hacer?
Gracias.
La idea es que si queremos obtener una suma acumulada de un índice de inicio k
no es necesario volver a calcular cumsum. En cambio, solo cumsum calculó onec, y la suma acumulada disipada es la diferencia de la suma acumulativa original y el elemento k-1
la suma acumulativa original
original_Summ = [1 1 3 4 5 7 7 7 8 10 10 11 11 12 13]
k=3
new_Summ = original_Summ - original_Summ(k-1)
Nota: la siguiente implementación puede causar límites de memoria si el tamaño de la array
es lage. En cambio, cada cmp y cmp1 se deben compilar en cada iteración.
array = [ 1 0 2 1 1 2 0 0 1 2 0 1 0 1 1 ];
%forward cumsum
fwd = cumsum(array);
%backward cumsum
bkw = cumsum(array(end:-1:1));%cumsum(array,''reverse'')
%difference of cumulative sum with all starting indices
cmp = bsxfun(@minus,fwd,[0 fwd(1:end-1)].'');%in matlab r2016b cmp= fwd-[0 fwd(1:end-1)].''
cmp1= bsxfun(@minus,bkw,[0 bkw(1:end-1)].'');%in matlab r2016b cmp1=bkw-[0 bkw(1:end-1)].''
%find last indices of elements that are <=5
[r, c] = find(cmp <=5);
idx = accumarray(r,c,[],@max);
[r1, c1] = find(cmp1 <=5);
idx1 = accumarray(r1,c1,[],@max);
idx1 =flipud(numel(array) + 1-idx1);
%loop to find indices from previous indices
si = 1;
index={};
while true
ei = idx(si);
if ei == numel(array)
break;
end
index {end+1} = [si,ei];
ei = ei+1;
si = idx1(ei);
index {end+1} = [si,ei];
end
disp(index)
Para encontrar el end_index para cualquier start_index dado:
start_index = 2;
threshold = 20;
if(sum(start_index:end)<threshold) %Error checking
end_index = -1;
else
end_index = find(cumsum(array(start_index:end)) >= threshold,1) + start_index - 1;
end
Para encontrar el start_index para cualquier end_index dado:
end_index = 6;
threshold = 20;
if(sum(1:end_index)<threshold) %Error checking
start_index = -1;
else
start_index = end_index + 1 - find(cumsum(fliplr(array(1:end_index))) >= threshold,1);
end %Error checking