用Mathematica改变矩阵的对角线

tom*_*omd 6 wolfram-mathematica

有没有一种优雅的方法可以将矩阵的对角线更改为新的值列表,相当于Band with SparseArray?

说我有以下矩阵(见下文)

(mat = Array[Subscript[a, ##] &, {4, 4}]) // MatrixForm
Run Code Online (Sandbox Code Playgroud)

并且我想将主对角线改为以下以获得"新垫子"(见下文)

newMainDiagList = Flatten@Array[Subscript[new, ##] &, {1, 4}]
Run Code Online (Sandbox Code Playgroud)

我知道使用ReplacePart将主对角线更改为给定值很容易.例如:

ReplacePart[mat, {i_, i_} -> 0]
Run Code Online (Sandbox Code Playgroud)

我也不想局限于主对角线(与Band不受SparseArray限制的方式相同)

(我现在使用的方法如下!)

(Normal@SparseArray[Band[{1, 1}] -> newMainDiagList] + 
   ReplacePart[mat, {i_, i_} -> 0]) // MatrixForm
Run Code Online (Sandbox Code Playgroud)

(期望输出是'新垫')

替代文字

rco*_*yer 10

实际上,你不需要使用Normal任何东西.一SparseArray加一"正常"的矩阵给你一个"正常"的矩阵.Band在初始检查时,使用是最灵活的方法,但有效(并且稍微不那么灵活)的替代方案是:

DiagonalMatrix[newDiagList] + ReplacePart[mat, {i_,i_}->0]
Run Code Online (Sandbox Code Playgroud)

DiagonalMatrix还接受第二个整数参数,该参数允许您指定newDiagList用0表示的主对角线表示的对角线.


然而,最优雅的选择是ReplacePart更有效地使用:替换Rule可以是RuleDelayed例如

ReplacePart[mat, {i_,i_} :> newDiagList[[i]] ]
Run Code Online (Sandbox Code Playgroud)

无需中间步骤即可直接更换.

编辑:为了模仿Band行为,我们还可以通过模式添加条件/;.例如,

ReplacePart[mat, {i_,j_} /; j==i+1 :> newDiagList[[i]]
Run Code Online (Sandbox Code Playgroud)

替换主要一个(Band[{1,2}])上面的对角线,和

ReplacePart[mat, {i_,i_} /; i>2 :> newDiagList[[i]]
Run Code Online (Sandbox Code Playgroud)

只会替换4x4矩阵(Band[{3,3}])中主对角线的最后两个元素.但是,ReplacePart直接使用它要简单得多.