2010-11-11 18 views
6

C'è un modo elegante per modificare le diagonali di una matrice in un nuovo elenco di valori, l'equivalente di Band con Sparray?Modifica delle diagonali di una matrice con Mathematica

Dire che ho la seguente matrice (vedi sotto)

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

e mi piacerebbe cambiare la diagonale principale al seguente per ottenere "nuovi mat" (vedi sotto)

newMainDiagList = [email protected][Subscript[new, ##] &, {1, 4}] 

So che è facile cambiare la diagonale principale con un valore dato usando ReplacePart. Ad esempio:

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

Vorrei anche non essere limitato alla diagonale principale (nello stesso modo in cui Band non è così limitato mediante SparseArray)

(Il metodo che uso al momento è di seguito!)

([email protected][Band[{1, 1}] -> newMainDiagList] + 
    ReplacePart[mat, {i_, i_} -> 0]) // MatrixForm 

(output desiderato è 'nuovo mat')

alt text

risposta

10

In realtà, non è necessario utilizzare Normal di sorta. A SparseArray più una matrice "normale" fornisce una matrice "normale". Utilizzando Band è, ispezione iniziale, l'approccio più flessibile, ma un efficace (e leggermente meno flessibile) alternativa è:

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

DiagonalMatrix accetta anche un secondo parametro intero che consente di specificare quali diagonale che newDiagList rappresenta con la diagonale principale rappresentato da 0.


il più elegante alternativa, tuttavia, è quello di utilizzare ReplacePart un po 'più efficace: la sostituzione Rule può essere un RuleDelayed, es

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

che sostituisce direttamente senza i passaggi intermedi.

Edit: per imitare il comportamento Band s', possiamo anche aggiungere le condizioni per il modello tramite /;. Ad esempio,

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

sostituisce la diagonale immediatamente sopra il principale (Band[{1,2}]), e

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

dovrebbe sostituire solo le ultime due elementi della diagonale principale di una matrice 4x4 (Band[{3,3}]). Ma è molto più semplice usare direttamente ReplacePart.

+0

Grazie! Ho imparato molto dalla tua risposta. Mi piace particolarmente ReplacePart [mat, {i_, i_}:> newDiagList [[i]]]. Mi piacciono molto anche i tuoi metodi per imitare il comportamento di Band, che trovo estremamente utile (per non dire altro). Suppongo che avrei dovuto individuare DiagonalMatrix. – tomd

+0

Su argomenti non correlati, il tuo nome utente suona come RickRoll'er. – Margus

+0

Leonid Shifrin utilizza MapTherad/ReplacePart, come segue: MapThread [ReplacePart, {mat, newMainDiagList, Range [4]}]. (Vedi Mathematica Programming. Un'introduzione avanzata, da LS a www.mathprogramming-intro.org/read_online.html) – tomd

Problemi correlati