在MATLAB中索引矩阵的所有对角线

时间:2019-08-12 05:07:48

标签: matlab matrix indexing

我正在尝试在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函数,但访问索引(因为我最终想用对角线替换矩阵条目)。

2 个答案:

答案 0 :(得分:4)

您已经注意到,可以使用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.

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

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

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

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

答案 1 :(得分:1)

使用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