Matlab 如何更改矩阵对角线列的值?

Matlab 如何更改矩阵对角线列的值?,matlab,Matlab,如何将值列表更改为all1?我需要右上角到左下角也以1结尾 rc = input('Please enter a value for rc: '); mat = ones(rc,rc); for i = 1:rc for j = 1:rc mat(i,j) = (i-1)+(j-1); end end final = mat final(diag(final)) = 1 % this won't work? 以下是一种方法: 假设我们有a方阵: a = ones

如何将值列表更改为all
1
?我需要右上角到左下角也以
1
结尾

rc = input('Please enter a value for rc: ');
mat = ones(rc,rc);
for i = 1:rc
    for j = 1:rc
        mat(i,j) = (i-1)+(j-1);
    end
end
final = mat
final(diag(final)) = 1 % this won't work?

以下是一种方法:

假设我们有
a
方阵:

a = ones(5, 5)*5

a =

     5     5     5     5     5
     5     5     5     5     5
     5     5     5     5     5
     5     5     5     5     5
     5     5     5     5     5
您可以删除对角线,然后创建对角线列表以替换它:

a = a - fliplr(diag(diag(fliplr(a)))) + fliplr(diag(ones(length(a), 1)))

a =

 5     5     5     5     1
 5     5     5     1     5
 5     5     1     5     5
 5     1     5     5     5
 1     5     5     5     5
diag(one(长度(a),1))
可以是任何向量,即
1->5

 a = a - fliplr(diag(diag(fliplr(a)))) + fliplr(diag(1:length(a)))

 a =    
     5     5     5     5     1
     5     5     5     2     5
     5     5     3     5     5
     5     4     5     5     5
     5     5     5     5     5

原始问题的代码-

final(1:size(final,1)+1:end)=1
<>解释:作为一个例子,考虑<代码> 5x5< /代码>最终矩阵,对角线元素将有索引为<代码>(1,1)< /代码>,<代码>(2,2)< /代码>…代码>(5,5)。将这些转换为线性索引-
1
7
等等,直到最后一个元素,这正是
1:size(final,1)+1:end
得到的结果


编辑:如果您想将对角线(从右上到左下元素)设置为
1
,一种方法是-

final(fliplr(eye(size(final)))==1)=1
说明:在这种情况下,我们也可以使用线性索引,但为了提高可读性和可能的趣味性,我们可以使用带有适当掩码的逻辑索引,该掩码是通过
fliplr(eye(size(final))==1创建的

但是,如果您关心性能,也可以在这里使用线性索引,如下所示-

final(sub2ind(size(final),1:size(final,1),size(final,2):-1:1))=1
说明:这里我们使用要设置的元素的
索引创建线性索引。这里的
是-
1:size(final,1)
size(final,2):-1:1
。我们将这两个输入到
sub2ind
,以获得线性索引,我们可以使用这些索引将其索引到
final
,并将其设置为
1

rc = input('Please enter a value for rc: ');
mat = ones(rc,rc);
for i = 1:rc
    for j = 1:rc
        mat(i,j) = (i-1)+(j-1);
    end
end
final = mat
final(diag(final)) = 1 % this won't work?
如果您想在此处挤出最大性能,请使用此原始版本的
sub2ind
-

final([size(final,2)-1:-1:0]*size(final,1) + [1:size(final,1)])=1

这里有一个简单的方法,我只需添加/减去适当的矩阵,就可以得到正确的结果:

final=mat-diag(diag(mat-1))+fliplr(diag([2-rc zeros(1,rc-2) 2-rc]))

到目前为止,所有指定的方法都是很好的方法,可以满足您的要求

然而,我想提供另一个观点和一些我在代码中注意到的东西,以及这个矩阵的一个有趣的属性,可能注意到也可能没有注意到。矩阵中的所有反对角线值的值都等于
rc-1

因此,如果您想将所有反对角线值设置为1,您可以作弊,只需找到那些等于
rc-1
的值,然后将它们设置为
1
。换言之:

final(final == rc-1) = 1;

关于效率的小说明 为了提高效率,您可以使用以下命令执行两个
for
循环在构造
mat
时所做的相同操作:

在这种情况下,
hankel
的工作原理是矩阵的第一行由
0:rc-1
的向量指定。之后,后面的每一行递增地向左移动值,向右添加递增值1。这会一直持续下去,直到你遇到第二个参数中的向量,在这一点上我们停止。换句话说,如果我们这样做了:

mat = hankel(0:3,3:6)
这就是我们得到的:

mat = 

 0     1     2     3
 1     2     3     4
 2     3     4     5
 3     4     5     6
因此,通过指定
rc=5
,这是我通过
hankel
得到的矩阵,它与代码生成的矩阵相同(在将反对角线设置为1之前):


把它都绑在一起 通过
hankel
和我提到的欺骗,我们可以用三行代码计算出你所要求的——第一行代码要求矩阵的维数:

rc = input('Please enter a value for rc: ');
mat = hankel(0:rc-1, rc-1:2*(rc-1));
mat(mat == rc-1) = 1;
mat
包含最终矩阵。因此,对于
rc=5
,这是我得到的矩阵:

mat =

     0     1     2     3     1
     1     2     3     1     5
     2     3     1     5     6
     3     1     5     6     7
     1     5     6     7     8

你能解释一下代码吗?1:size是什么?为什么我们要+1:end?对不起,我需要从右上到左下的1:end也以1ah结尾。。我明白了,谢谢你的解释你原来的问题在我看来是一个重复的案例,但我想你的新问题不是,我已经把它作为一个包含两个案例的答案的编辑发布了,另外,因为评论不会在这里停留太久。另外,我认为你应该将这个新问题添加到你的问题中作为编辑。我使用了右上/左下的元素是
rc-1
,所以我从中减去
rc-2
,得到一个:P,但在汉克尔矩阵上的位置不错!
mat =

     0     1     2     3     1
     1     2     3     1     5
     2     3     1     5     6
     3     1     5     6     7
     1     5     6     7     8