【问题标题】:Summing elements at the end of a column with elements at the beginning of the next row将列末尾的元素与下一行开头的元素相加
【发布时间】:2021-04-29 15:09:01
【问题描述】:

假设我在 Matlab 中有以下矩阵:

A = [1 2 3
     4 5 6
     7 8 9
     3 2 1
     6 5 4]; 

现在假设我想要一个向量如下:

v = [1 4 7 3 6 0 0 0 0 0 0] + [0 0 0 2 5 8 2 5 0 0 0] + [0 0 0 0 0 0 3 6 9 1 4];

也就是说,我想按列读取 A 但我希望每列的最后 2 个元素与下一列的前 2 个元素相加(第一列的最后一个元素与第二个元素第 2 列、第 1 列的第 4 个元素与第 2 列的第 1 个元素等)

现在,如果 A 的维度非常大,我如何在没有循环的情况下有效地执行此过程?

感谢您的回答。

【问题讨论】:

    标签: arrays performance matlab matrix


    【解决方案1】:

    您可以从零填充列创建一个稀疏矩阵并沿其第二维求和:

    s = size(A);
    f = s(1) - 2;
    r = (1:s(1)).' + (0:f:(s(2) - 1) * f);
    c =  repmat(1:s(2), s(1), 1);
    M = sparse(r, c, A);
    v = full(sum(M, 2));
    

    【讨论】:

    • 由于sparse自动添加,所以可以直接使用v = full(sparse(1, r, A));
    • @LuisMendo 非常聪明!您可以将您的建议作为新答案发布吗?
    • 完成!我还包括了accumarray 变体
    【解决方案2】:

    @rahnema1's answer 的一个小变体,它利用了 sparse 自动在重合索引处添加值的事实:

    A = [1 2 3; 4 5 6; 7 8 9; 3 2 1; 6 5 4]; % data matrix
    N = 2; % shift to be applied to each column
    s = size(A);
    f = s(1) - N;
    r = (1:s(1)).' + (0:f:(s(2) - 1) * f);
    v = full(sparse(1, r, A));
    

    等效地,您可以使用accumarray 代替sparse,将最后一行替换为

    v = accumarray(r(:), A(:)).';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-08
      相关资源
      最近更新 更多