【问题标题】:Sum of row elements between colMin and colMax, with different colMin and colMax for each row - Octave / MatlabcolMin 和 colMax 之间的行元素之和,每行具有不同的 colMin 和 colMax - Octave / Matlab
【发布时间】:2012-04-20 23:02:21
【问题描述】:

我有矩阵

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

【问题讨论】:

  • 我认为循环可能是最易读的解决方案。
  • 是的,但为了速度,我正在寻找一种没有循环的解决方案,因为实际计算将在更大的矩阵上进行......
  • 在较新版本的 Matlab 中,循环也会更快。无论如何,你从哪里得到 iMin 和 iMax?是从您从另一个与p 大小相同的数组中提取的索引中提取的吗?

标签: matlab matrix sum octave


【解决方案1】:

您可以使用逻辑索引来实现此目的,方法与我对您的other question 的回答类似。

假设iMiniMax 具有与p 中的行数相同的条目数,您可以水平平铺p 的列索引,即[1:size(p,2)],并将其与@ 的垂直平铺进行比较987654327@ 和 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

没有循环:-)

【讨论】:

  • 谢谢!在 Octave 上,相对速度似乎取决于矩阵 p 的形状:大小为 100 000 x 200 的 P 矩阵:% 你的方法(repmat)= 0.34 秒 % Jonas 的方法 1(循环)= 2.20 秒 % Jonas 的方法 2(arrayfun) = 4.92 秒。大小为 200 x 100 000 的 P 矩阵:% 你的方法(repmat)= 0.68 秒 % Jonas 的方法 1(循环)= 0.41 秒 % Jonas 的方法 2(arrayfun)= 1.412 秒 你的方法似乎一直很快,循环方法也很快但是当行数变得很大时会受到惩罚。 Arrayfun 比较慢。
【解决方案2】:

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

  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);
    

【讨论】:

    【解决方案3】:

    我很确定

    [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 组成的数组来屏蔽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)
    

    【讨论】:

    • 谢谢!在最近的 Octave 中,for 循环对于小 nRows 是最快的,但在 nRows 增加时不是最快的(请参阅上面对 rroowwllaandd 答案的评论)。不知道最近的 Matlab 版本是否会改变这个结论......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 2018-05-07
    相关资源
    最近更新 更多