计算矩阵对角线之和

3

我有一个类似A的矩阵,希望计算出每条对角线上元素的和并显示在向量Y中。

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

Y=[3 8 15 12 7]

我了解这段代码。
[sum(diag(y,2)),sum(diag(y,1)),sum(diag(y,0)),sum(diag (y,-1)),sum(diag (y,-2))]

但我想将其编写为函数。

3个回答

5

spdiags可以完全满足您的要求:

dsum = sum(spdiags(A))

您可以使用fliplr函数来反转向量,并创建一个函数:
function dsum = diagsum(A)
    dsum = fliplr(sum(spdiags(A)));
end

结果

dsum =

    3    8   15   12    7

3
这里有一个可能的解决方案:
[r ,c]=size(A);
idx=bsxfun(@plus,(r:-1:1)',0:c-1);
s=flipud(accumarray(idx(:),A(:)));

与其他答案中提出的 spdiags 相比,这种方法在 Octave 中表现得更好。 基准测试:

A = rand(1000);
disp('---------bsxfun+accumarray----------')
tic
    [r ,c]=size(A);
    idx=bsxfun(@plus,(r:-1:1)',0:c-1);
    s=flipud(accumarray(idx(:),A(:)));
toc
disp('---------spdiags----------')
tic
    dsum = fliplr(sum(spdiags(A)));
toc

结果:

---------bsxfun+accumarray----------
Elapsed time is 0.0114651 seconds.
---------spdiags----------
Elapsed time is 8.62041 seconds.

2
自从Matlab R2016b以来,您现在可以删除对bsxfun的使用并直接使用(r:-1:1)' + (0:c-1) :)! - TwistedSim
@TwistedSim 但是截至2018年,一些经验丰富的MATLAB用户更喜欢使用bsxfun而不是隐式扩展! :) - rahnema1
当你来自numpy背景时,使用广播仍然更有意义;). 现在我意识到我不是第一个说这个的人... oopsidoopsi - TwistedSim

1
rahnema1的答案类似,您也可以在应用accumarray之前使用toeplitz生成指数:
[r, c] = size(A);
index = toeplitz(c:(r+c-1), c:-1:1);
Y = accumarray(index(:), A(:)).';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接