2

我有矩阵

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 方法可以在没有循环的情况下做到这一点?

4

3 回答 3

2

您可以使用逻辑索引来实现这一点,遵循与我对您的其他问题的回答类似的方法。

假设iMin并且iMax具有与行数相同的条目数,p您可以水平平铺pie的列索引,[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

没有循环:-)

于 2012-04-22T12:39:17.417 回答
1

我知道我有点晚了,但这是我的贡献:

  1. 单线bsxfun

    sum((p.*bsxfun(@le,iMin(:),1:size(p,2)).*bsxfun(@ge,iMax(:),1:size(p,2))).')
    
  2. 一个解决方案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);
    
于 2013-12-16T22:51:22.383 回答
0

我相当确定

[nRows,nCols]=size(p);
result = zeros(nRows,1);
for iRow = 1:nRow
   result(iRow) = sum(p(iRow,iMin(iRow):iMax(iRow));
end

是最快的解决方案,至少在最新版本的 Matlab 上是这样。

要一次性执行求和,您需要创建一个包含 1 和 0 的数组来进行 mask p,即

[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)
于 2012-04-21T15:26:34.597 回答