您收到错误的原因是diag(P,j) 不是对P 对角线的引用,它是一个返回该对角线上值的函数。因此,您所做的是将值 A(k,2) 分配给函数的返回值,并且由于它从未分配给变量名,因此该值丢失并且没有任何变化。
要修复您的循环,您需要在P 中提供索引并分配给这些索引。一种方法是使用逻辑索引告诉 MATLAB P 中的哪些值要更改。例如,
P = zeros(4)
M = logical(diag([1,1,1], -1))
P(M) = 3
给我们
P =
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
M =
0 0 0 0
1 0 0 0
0 1 0 0
0 0 1 0
P =
0 0 0 0
3 0 0 0
0 3 0 0
0 0 3 0
不幸的是,我们无法同时指定要创建的对角线和结果矩阵的大小,因此我们必须在创建之前计算对角线上的元素数量.
A=[-3 -2 -1 0 1 2 3;0.1 0.2 0.2 0.5 0.6 -0.1 0].'
n=4; % Number of rows/columns in P...
% If we want a non-square matrix, we'll have to do more math
P=zeros(n);
for k=1:2*n-1 % Remove hardcoded values to make the code more general.
j=A(k,1);
diag_length = n-abs(j);
M=diag(true(1,diag_length),j); % Create logical array with true on jth diagonal
P(M)=A(k,2);
end
结果是:
P =
0.5000 0.6000 -0.1000 0
0.2000 0.5000 0.6000 -0.1000
0.2000 0.2000 0.5000 0.6000
0.1000 0.2000 0.2000 0.5000
另一种方法是使用spdiags。 spdiags 的用途之一是获取一个矩阵的列,并使用它们来构建输出矩阵的对角线。您传递要设置的对角线的索引、每个对角线的值矩阵以及矩阵大小。
如果我们只为每个对角线传递一个值,spdiags 将只设置一个值,因此我们将不得不复制输入向量 n 次。 (spdiags 会很乐意丢弃值,但不会填充它们。)
A=[-3 -2 -1 0 1 2 3;0.1 0.2 0.2 0.5 0.6 -0.1 0].'
n = 4;
diag_idx = A(:,1).'; % indices of diagonals
diag_val = A(:,2).'; % corresponding values
diag_val = repmat(diag_val, n, 1); % duplicate values n times
P = spdiags(diag_val, diag_idx, n, n);
P = full(P);
最后一行是因为spdiags 创建了一个稀疏矩阵。 full 将其转换为常规矩阵。 P 的最终值是您所期望的:
P =
0.5000 0.6000 -0.1000 0
0.2000 0.5000 0.6000 -0.1000
0.2000 0.2000 0.5000 0.6000
0.1000 0.2000 0.2000 0.5000
当然,如果您喜欢单行,您可以将所有这些命令组合在一起。
P = full(spdiags(repmat(A(:,2).', n, 1), A(:,1).', n, n));