【问题标题】:Indexing all diagonals of a matrix in MATLAB在MATLAB中索引矩阵的所有对角线
【发布时间】:2019-08-12 05:07:48
【问题描述】:

我正在尝试在 matlab 中索引(而不是获取)矩阵的对角线。

假设我有一个矩阵“M”,即 n × n。然后我想获得矩阵“M”中所有可能的对角线的所有索引。

我知道中心对角线的索引是

M(1:(n+1):end)

并且它上面的所有以下对角线都被索引为:

M((1+1*n):(n+1):end)
M((1+2*n):(n+1):end)...
M((1+n*n):(n+1):end)

现在我还想得到下面的对角线。但是,我终其一生都无法弄清楚该怎么做。

可重现的例子:

rng(1); % set seed
n = 4;
M = rand(n);

屈服

M =

   0.562408   0.947364   0.655088   0.181702
   0.960604   0.268834   0.469042   0.089167
   0.578719   0.657845   0.516215   0.419000
   0.226410   0.601666   0.169212   0.378740

我想索引下对角线的地方,例如次对角线:

0.960604 0.657845 0.169212

也就是说,我不需要通过例如得到对角线diags 函数,但访问索引(因为我最终想用对角线替换矩阵条目)。

【问题讨论】:

    标签: matlab matrix indexing


    【解决方案1】:

    正如您已经指出的,您可以使用diag 函数来获取主对角线和主对角线上方或下方的其他对角线,

    M = magic(4)    % Test data
    M =
        16     2     3    13
         5    11    10     8
         9     7     6    12
         4    14    15     1
    
    diag(M, -1)
    ans =
         5
         7
        15
    

    但您不能使用 diag 函数为对角线赋值:

    diag(M, -1) = [3; 2; 1]
    Index in position 2 is invalid. Array indices must be positive integers or logical values.
    

    相反,我们可以使用logical indexing,通过使用相同大小的逻辑矩阵索引数组M。我们可以使用diag 函数轻松创建此矩阵,方法是创建一个对角线矩阵,其中指定对角线上有一个:

    diag(ones(1, 3), -1)
    ans =
         0     0     0     0
         1     0     0     0
         0     1     0     0
         0     0     1     0
    

    要使用此矩阵进行逻辑索引,我们需要使用logical 函数将其从双精度转换为逻辑。

    M(logical(diag(ones(1, 3), -1)))
    ans =
         5
         7
        15
    

    或使用

    为其分配新值
    M(logical(diag(ones(1, 3), -1))) = [99, 98, 97]
    M =
        16     2     3    13
        99    11    10     8
         9    98     6    12
         4    14    97     1
    

    【讨论】:

      【解决方案2】:

      使用diag 获取对角线的索引有一种性能稍高的方法:

      n = 5;                  % matrix size
      M = reshape(1:n*n,n,n); % matrix with linear indices
      indices = diag(M, ii);  % indices to diagonal ii
      

      但是,直接计算正确的索引要容易得多。正如 OP 所发现的,上对角线元素由下式给出:

      indices = (1+ii*n):(n+1):(n*n);
      

      (请注意,括号不是必需的,因为冒号运算符的优先级最低。)

      下对角线元素由下式给出:

      indices = (1+ii):(n+1):((n-ii)*n);
      

      两个系列的主对角线相同,其中ii=0

      我们可以使用第一种方法来验证这些计算的正确性:

      n = 5;                  % matrix size
      M = reshape(1:n*n,n,n); % matrix with linear indices
      for ii=1:n-1
         indices = (1+ii*n):(n+1):(n*n);
         assert(isequal(indices, diag(M, ii).'))
         indices = (1+ii):(n+1):((n-ii)*n);
         assert(isequal(indices, diag(M, -ii).'))
      end
      

      【讨论】:

        猜你喜欢
        • 2011-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-16
        • 1970-01-01
        • 2021-11-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多