开发者

Changing the Diagonals of a Matrix with Mathematica

Is there an elegant way to change the diagonals of a matrix to a new list of values, the equivalent of Band with SparseArray?

Say I have the following matrix (see below)

(mat = Array[Subscript[a, ##] &, {4, 4}]) // Matri开发者_JAVA技巧xForm

and I'd like to change the main diagonal to the following to get "new mat" (see below)

newMainDiagList = Flatten@Array[Subscript[new, ##] &, {1, 4}]

I know it is easy to change the main diagonal to a given value using ReplacePart. For example:

ReplacePart[mat, {i_, i_} -> 0]

I'd also like not to be restricted to the main diagonal (in the same way that Band is not so restricted with SparseArray)

(The method I use at the moment is the following!)

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

(Desired Output is 'new mat')

Changing the Diagonals of a Matrix with Mathematica


Actually, you don't need to use Normal whatsoever. A SparseArray plus a "normal" matrix gives you a "normal" matrix. Using Band is, on initial inspection, the most flexible approach, but an effective (and slightly less flexible) alternative is:

DiagonalMatrix[newDiagList] + ReplacePart[mat, {i_,i_}->0]

DiagonalMatrix also accepts a second integer parameter which allows you to specify which diagonal that newDiagList represents with the main diagonal represented by 0.


The most elegant alternative, however, is to use ReplacePart a little more effectively: the replacement Rule can be a RuleDelayed, e.g.

ReplacePart[mat, {i_,i_} :> newDiagList[[i]] ]

which does your replacement directly without the intermediate steps.

Edit: to mimic Band's behavior, we can also add conditions to the pattern via /;. For instance,

ReplacePart[mat, {i_,j_} /; j==i+1 :> newDiagList[[i]]

replaces the diagonal immediately above the main one (Band[{1,2}]), and

ReplacePart[mat, {i_,i_} /; i>2 :> newDiagList[[i]]

would only replace the last two elements of the main diagonal in a 4x4 matrix (Band[{3,3}]). But, it is much simpler using ReplacePart directly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜