【问题标题】:adding values to diagonals of matrix using element-wise addition in matlab使用matlab中的元素加法将值添加到矩阵的对角线
【发布时间】:2015-03-12 01:08:33
【问题描述】:

我正在编写一个对矩阵进行操作的脚本,我遇到了需要将前一个矩阵的对角线之和添加到新矩阵的对角线元素的问题。到目前为止,我对这个特定功能的代码(下面更详细地描述)是:

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 的第一个元素? (同时仍然适用于任何数组大小?)

这是一张描述我想要实现的目标的图片:

谢谢!

【问题讨论】:

  • 您可以编辑您的帖子以包含显示您想要的数字示例吗?我无法从你的问题中弄清楚你想做什么
  • 没问题!刚刚添加了一个带有我正在尝试做的图片的 imgur 链接。
  • 如果B3x3,那么d不应该是1x5吗?
  • 有趣的问题!并且描述得很好

标签: arrays matlab matrix


【解决方案1】:

您可以使用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));

【讨论】:

  • 由于我的其他解决方案被证明是错误的,并且 toeplitz 是唯一一个对所有形状的 M 真正可靠的解决方案,我将您的答案回滚了。
  • toeplitz 的优雅解决方案!
  • @Divakar 谢谢!这些对角线的东西非常方便的功能
  • 我实际上还有另一个问题 - 可以修改它以对矩阵的列进行元素添加吗?与我最初提出的问题非常相似,除了列而不是对角线?
  • @bieberman 没必要在那里用昂贵的repmat,就做bsxfun(@plus,B,d)
【解决方案2】:

假设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

【讨论】:

    【解决方案3】:

    代码:

    以下代码将A 的对角线之和与矩阵B 中的对应对角线相加。该代码适用于大小相等的矩阵AB,不一定是正方形。

    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
    

    然后我们通过accumarray计算sumsDiagsA作为对角线的总和:

    sumsDiagsA = accumarray(D(:), A(:));
    

    变量sumsDiagsA 就是您在代码中所指的d

    现在我们对包含和的向量使用索引并将它们添加到矩阵B

    C = B + sumsDiagsA(D);
    

    假设你已经计算了你的向量d,你不需要accumarray-step,你需要做的就是:

    D = bsxfun(@minus, size(B,2)+(1:size(B,1)).', 1:size(B,2)); %'
    C = B + d(D);
    

    【讨论】:

    • 我认为有两个输入 - 一个二维矩阵,例如 B 和一个一维数组 d,长度为 sum(size(B))-1
    • @Divakar:坦率地说,我不完全理解这个问题。我的第一个答案基于您的答案,但后来我只是按字面意思理解:“我正在编写一个对矩阵进行运算的脚本,我遇到了需要添加前一个矩阵的对角线之和的问题到一个新矩阵的对角元素。"
    • @knedlsepp 嗯,我基本上跳过了文本部分,直接进入图表部分,这对我来说很有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多