2010-11-11 15 views
6

¿Existe una forma elegante de cambiar las diagonales de una matriz a una nueva lista de valores, el equivalente de Band with SparseArray?Cambiar las diagonales de una matriz con Mathematica

Decir que tengo la siguiente matriz (véase más adelante)

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

y me gustaría cambiar la diagonal principal de la siguiente llegar "mat" (véase más adelante)

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

Sé que es fácil cambiar la diagonal principal a un valor determinado utilizando ReplacePart. Por ejemplo:

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

También me gustaría no estar restringido a la diagonal principal (de la misma manera que la banda no es tan restringido con SparseArray)

(el método que utilizo en este momento es la siguiente!)

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

(salida deseada es 'nueva estera')

alt text

Respuesta

10

En realidad, no necesita usar Normal en absoluto. Un SparseArray más una matriz "normal" le da una matriz "normal". Uso de Band es, en la inspección inicial, el enfoque más flexible, pero una cantidad eficaz (y un poco menos flexible) alternativa es:

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

DiagonalMatrix también acepta un segundo parámetro entero que le permite especificar qué diagonal que newDiagList representa con la diagonal principal representado por 0.


la alternativa más elegante, sin embargo, es utilizar ReplacePart un poco más efectiva: la sustitución Rule puede ser un RuleDelayed, por ejemplo,

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

que hace su reemplazo directamente sin los pasos intermedios.

Editar: para imitar el comportamiento Band 's, también podemos añadir condiciones a través del patrón /;. Por ejemplo,

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

sustituye a la diagonal inmediatamente por encima de la principal (Band[{1,2}]), y

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

sólo sería reemplazar los dos últimos elementos de la diagonal principal de una matriz 4x4 (Band[{3,3}]). Pero, es mucho más simple usando ReplacePart directamente.

+0

Gracias! Aprendí mucho de tu respuesta. Particularmente me gusta ReplacePart [mat, {i_, i_}:> newDiagList [[i]]]. También me gustan mucho sus métodos para imitar el comportamiento de Band, que considero extremadamente útil (por decir lo menos). Supongo que debería haber visto DiagonalMatrix. – tomd

+0

En un tema no relacionado, su nombre de usuario suena como RickRoll'er. – Margus

+0

Leonid Shifrin utiliza MapTherad/ReplacePart, de la siguiente manera: MapThread [ReplacePart, {mat, newMainDiagList, Range [4]}]. (Consulte la Programación de Mathematica. Una introducción avanzada, por LS en www.mathprogramming-intro.org/read_online.html) – tomd

Cuestiones relacionadas