我正在编写一个对矩阵进行操作的脚本,我遇到了需要将前一个矩阵的对角线总和添加到新矩阵的对角线元素的问题。到目前为止,我对这个特定功能的代码(下面将详细介绍)是:
t = 1;
for k = (m-1):-1:-(m-1)
C = bsxfun(@plus, diag(B, k), d);
g(t) = sum(diag(B, k));
t = t + 1;
end
其中d是1x3数组,C应该是3x3数组;然而,C被输出为1x3阵列,使得第一对角线被求和并加到d,然后将主对角线求和并加到d,并且最终对角线被求和并加到d。
有没有办法可以得到C的值,使得第一个对角线是它添加到d的最后一个元素的各个元素的总和,主对角线的各个元素添加到d的中间元素,以及底部对角线的元素添加到d的第一个元素? (虽然仍然可以处理任何数组大小?)
这是描述我想要实现的目标的图片:
谢谢!
答案 0 :(得分:5)
您可以使用toeplitz
生成一个矩阵,其中包含需要添加到原始矩阵中的值:
M = [5 5 5; 7 7 7; 9 9 9]; %// data matrix
v = [1 11 4 3 2]; %// data vector
S = toeplitz(v);
S = S(1:(numel(v)+1)/2, (numel(v)+1)/2:end);
result = M+S;
或者,如@thewaywewalk所述,您可以更直接地执行此操作,如下所示:
M = [5 5 5; 7 7 7; 9 9 9]; %// data matrix
v = [1 11 4 3 2]; %// data vector
result = M + toeplitz(v(size(M,1):-1:1), v(size(M,2):end));
答案 1 :(得分:3)
假设B
是方形矩阵,本文中列出的是一种基于bsxfun
的矢量化方法。这是实施 -
N = size(B,1) %// Store size of B for later usage
%// Find a 2D grid of all indices with kth column representing kth diagonal of B
idx = bsxfun(@plus,[N-numel(B)+1:N+1:N]',[0:2*N-2]*N) %//'
%// Mask of all valid indices as we would see many from the 2D grid
%// going out of bounds of 2D array, B
mask = idx>numel(B) | idx<1
%// Set all out-of-bounds indices to one, so that in next step
%// we could index into B in a vectorized manner and sum those up with d
idx(mask)=1
sum1 = bsxfun(@plus,B(idx),d(:).') %//'
%// Store the summations at proper places in B with masking again
B(idx(~mask)) = sum1(~mask)
示例运行 -
B =
1 9 0
7 9 4
6 8 7
d =
4 9 5 8 2
B =
6 17 2
16 14 12
10 17 12
答案 2 :(得分:2)
以下代码将A
的对角线的总和添加到矩阵B
中的对应对角线。该代码适用于大小相同的矩阵A
,B
,不一定是正方形。
A = magic(4);
B = magic(4);
D = bsxfun(@minus, size(A,2)+(1:size(A,1)).', 1:size(A,2)); %'
sumsDiagsA = accumarray(D(:), A(:)); %// Compute sums of diagonals (your 'd')
B = B + sumsDiagsA(D); %// Add them to the matrix
首先,我们构建一个矩阵,对从最右边的对角线开始的所有对角线进行编号:
>> D = bsxfun(@minus, size(A,2)+(1:size(A,1)).', 1:size(A,2))
D =
4 3 2 1
5 4 3 2
6 5 4 3
7 6 5 4
然后我们通过sumsDiagsA
计算accumarray
作为对角线的总和:
sumsDiagsA = accumarray(D(:), A(:));
变量sumsDiagsA
就是您在代码中称为d
的内容。
现在我们对包含总和的向量使用索引并将它们添加到矩阵B
:
C = B + sumsDiagsA(D);
假设您已经计算了向量d
,则不需要accumarray
- 步骤,您需要做的就是:
D = bsxfun(@minus, size(B,2)+(1:size(B,1)).', 1:size(B,2)); %'
C = B + d(D);