私はマトリックスを持っています
p=[1 2 3 4;
5 6 7 8;
10 20 30 50];
列 iMin と iMax の間にある各行の要素の合計を計算したいのですが、iMin と iMax は行ごとに異なります
例えば
iMin = [3 2 1];
iMax = [4 4 3];
結果は
[7 21 60]
ループなしでこれを行う簡単な Octave/Matlab の方法はありますか?
他の質問に対する私の回答と同様のアプローチに従って、論理インデックスを使用してこれを実現できます。
行数と同じ数のエントリがあると仮定するとiMin
、ieの列インデックスを水平方向に並べて表示し、これを の垂直方向のタイル表示と比較して、基準を満たすエントリの論理インデックスを生成できます。iMax
p
p
[1:size(p,2)]
iMin
iMax
p
c_min=repmat(iMin',1,size(p,2))
c_max=repmat(iMax',1,size(p,2))
c_ind=repmat([1:size(p,2)],size(p,1),1)
result=sum(p.*(c_ind>=c_min & c_ind<=c_max),2)
与える:
result =
7
21
60
ループなし:-)
私は少し遅れていることを知っていますが、ここに私の貢献があります:
ワンライナーbsxfun
:
sum((p.*bsxfun(@le,iMin(:),1:size(p,2)).*bsxfun(@ge,iMax(:),1:size(p,2))).')
A solution with linear indexing
:
aux = [zeros(1,size(p,1)); cumsum(p.')];
rowjumps = 0:size(p,2)+1:numel(p);
result = aux(iMax+1+rowjumps) - aux(iMin+rowjumps);
私はそれをかなり確信しています
[nRows,nCols]=size(p);
result = zeros(nRows,1);
for iRow = 1:nRow
result(iRow) = sum(p(iRow,iMin(iRow):iMax(iRow));
end
少なくとも最近のバージョンの Matlab では最速のソリューションです。
p
合計を一度に実行するには、マスクする 1 と 0 の配列を作成する必要があります。
[nRows,nCols] = size(p);
idxCells = arrayfun(@(x,y)...
[false(1, x-1), true(1,y-x+1), false(1,nCols-y)], iMin, iMax,...
'UniformOutput',false);
result = sum( p .* cell2mat(idxCells), 2)