2017-06-08 9 views
2

ベクトルがa = [1 3 4 2 1 5 6 3 2]です。今度は、cumsumaの新しいベクトル 'b'を作成したいが、閾値に達した後、cumsumをリセットして再びしきい値に達するまで再開する必要があるので、新しいベクトルは次のようになります。閾値までベクトル値を合計してから、もう一度やり直してください

b = [1 4 4 2 3 5 6 3 5] 

+0

あなたには整数しかありませんか? – thewaywewalk

+0

いいえ、私も0.987 – Toxicsmile

答えて

0

1つの方法はループを使用することです。最初の累積合計csを作成し、csの要素がしきい値thより大きい場合は、残りの要素の累積合計の要素をaに置き換えます。

aの一部の要素がthより大きい可能性があるため、これらの要素も削除しない限り、このループは無限になります。

a = [1 3 4 2 1 5 6 3 2]; 
th = 5; 
cs = cumsum(a); 
while any(cs>th & cs~=a) % if 'cs' has values larger that 'th', 
         % and there are any values smaller than th left in 'a' 
    % sum all the values in 'a' that are after 'cs' reached 'th', 
    % excluding values that are larger then 'th' 
    cs(cs>th & cs~=a) = cumsum(a(cs>th & cs~=a)); 
end 
+0

ありがとう、それはまさに私が探していたものでした! – Toxicsmile

-1

累積合計を計算し、条件に従ったインデックス値を置き換えます。

a = [1 3 4 2 1 5 6 3 2] ; 

b = [1 4 4 2 3 5 6 3 5] ; 

iwant = a ; 
a_sum = cumsum(a) ; 
iwant(a_sum<5) = a_sum(a_sum<5) ; 
+0

のような非整数を持っていますそれは私のためには機能しません...最初に閾値に達した後、新しいベクトルの残りの部分がしきい値を超えて合計されます... – Toxicsmile

+0

Ohhh ..yes。私はそれを逃した..明日戻ってくるだろう... :) –

1

閾値とcumsumの引数を正規化し、その後、cumsum明のGroupWiseを行うことができますaccumarray、のグループ化indizesを得ることができますフローリングで::ここで

whileループを備えたシンプルなソリューションです

t = 5; 
a = [1 3 4 2 1 5 6 3 2]; 

%// cumulative sum of normalized vector a 
n = cumsum(a/t); 
%// subs for accumarray 
subs = floor(n) + 1; 
%// cumsum of every group 
aout = accumarray(subs(:), (1:numel(subs)).', [], @(x) {cumsum(a(x))}); 
%// gather results; 
b = [aout{:}] 
+1

いいです、私は、 'accumarray'を完全な可能性をもって使う方法を明確に学ぶべきです – Max

2

元のベクトルを乗算すると累積合計を返す疎行列を作成できます。私はこのソリューションと他のソリューションとのタイミングを合わせることはできませんでしたが、私はこれが大規模な配列の中で最も速くなると強く思っています。

% Original data 
a = [1 3 4 2 1 5 6 3 2]; 
% Threshold 
th = 5; 
% Cumulative sum corrected by threshold 
b = cumsum(a)/th; 
% Group indices to be summed by checking for equality, 
% rounded down, between each cumsum value and its next value. We add one to 
% prevent NaNs from occuring in the next step. 
c = cumsum(floor(b) ~= floor([0,b(1:end-1)]))+1; 
% Build the sparse matrix, remove all values that are in the upper 
% triangle. 
S = tril(sparse(c.'./c == 1)); 
% In case you use matlab 2016a or older: 
% S = tril(sparse(bsxfun(@rdivide,c.',c) == 1)); 
% Matrix multiplication to create o. 
o = S*a.'; 
関連する問題