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