【问题标题】:Calculating a partial cumulative sum for a square matrix计算方阵的部分累积和
【发布时间】:2013-08-01 14:54:49
【问题描述】:

假设我有一个方阵 M:

M = [0 0 0 0 0 1 9; 0 0 0 0 0 4 4; 0 0 1 1 6 1 1; 0 1 2 9 2 1 0; 2 1 8 3 2 0 0; 0 8 1 1 0     0 0; 14 2 0 1 0 0 0]


      0 0 0 0 0 1 9
      0 0 0 0 0 4 4
      0 0 1 1 6 1 1
 M =  0 1 2 9 2 1 0
      2 1 8 3 2 0 0
      0 8 1 1 0 0 0
     14 2 0 1 0 0 0

现在我想计算两个不同的累积和:一个从每列的顶部到列的元素,即矩阵的对角线元素,另一个从列的底部开始到同一个对角线元素。

因此得到的矩阵M'应该如下:

       0 0 0 0 0 1 9
       0 0 0 0 0 4 5
       0 0 1 1 6 2 1
 M' =  0 1 3 9 4 1 0
       2 2 8 5 2 0 0
       2 8 1 2 0 0 0
      14 2 0 1 0 0 0

我希望对我想要达到的目标的解释足够通俗易懂。由于我的矩阵比本示例中的矩阵大得多,因此计算也应该是高效的......但到目前为止,我什至无法弄清楚如何“低效”地计算它。

【问题讨论】:

  • 你的矩阵总是正方形的吗?
  • 是的,它们总是方形的
  • 您是否介意清除“从每列顶部到列元素的一个,即矩阵的对角线元素,以及从列底部到相同的对角线元素。”我相信我有一个解决方案,但这让我感到困惑。所以它将所有元素从列的顶部向下添加到但不包括对角线,并且从底部向上添加到但不包括对角线?
  • 是的,这听起来像一回事……抱歉我的解释不准确。如果你得到M' 作为答案,它应该是正确的。
  • 顺便说一下,矩阵的从左下角到右上角的元素被称为anti-diagonal,而不是从左上角到右下角的对角线.

标签: matlab matrix


【解决方案1】:

在一行中使用一些翻转和上三角函数triu

Mp = fliplr(triu(fliplr(cumsum(M)),1)) ...
     +flipud(triu(cumsum(flipud(M)),1)) ...
     +flipud(diag(diag(flipud(M))));

【讨论】:

    【解决方案2】:

    以下将完成这项工作:

    Mnew = fliplr(triu(cumsum(triu(fliplr(M)),1))) + flipud(triu(cumsum(triu(flipud(M)),1)));
    Mnew = Mnew - fliplr(diag(diag(fliplr(Mnew)))) + fliplr(diag(diag(fliplr(M))));
    

    但这是最快的方法吗?

    我认为逻辑索引可能会让你更快

    【讨论】:

    • 还是非常感谢!!我不知道这是否是比较这两种解决方案的好方法,但使用 tictoc 你的解决方案会“慢”几毫秒:D
    • 我很惊讶我们如此接近相同的解决方案。我认为你是对的,可能有更快的方法来做到这一点,但这些方法可读性很强,JIT 编译器可能会很好地处理它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 2019-06-06
    • 1970-01-01
    • 2020-11-04
    • 2021-05-11
    • 2013-05-26
    相关资源
    最近更新 更多