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直接使用它要简单得多.