Changing the diagonals of a matrix with math

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

Say I have the following matrix (see below)

(mat = Array[Subscript[a, ##] &, {4, 4}]) // MatrixForm 

and I would like to change the main diagonal to the next to get a "new rug" (see below)

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

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

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

I would also like to not be limited to the main diagonal (just like Band is not limited to SparseArray)

(The method I'm currently using is as follows :)

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

(The desired conclusion is a new matte)

alt text

+6
wolfram-mathematica
source share
1 answer

In fact, you do not need to use Normal . A SparseArray plus a "normal" matrix gives you a "normal" matrix. Using Band during initial testing is the most flexible approach, but an effective (and slightly less flexible) alternative:

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

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


The most elegant alternative, however, is to use ReplacePart more efficiently: replacing Rule can be RuleDelayed , for example

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

which performs your replacement directly without intermediate steps.

Edit : to simulate Band behavior, we can also add conditions to the pattern via /; , For example,

 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]] 

will replace only the last two elements of the main diagonal in the 4x4 matrix ( Band[{3,3}] ). But it’s much easier to use ReplacePart .

+10
source share