Diagonalisering#
Demo af Christian Mikkelstrup, Hans Henrik Hermansen, Karl Johan Måstrup Kristiansen og Magnus Troen. Revideret 11-11-24 af shsp.
from sympy import *
init_printing()
Jævnfør kursuslærebogen er en matrix \(\mathbf A\) diagonalisérbar, hvis den har tilstrækkeligt mange lineært uafhængige egenvektorer til, at en basis kan dannes af dem. Diagonaliseringen finder derefter sted ved at skifte til koordinater med hensyn til denne egenbasis:
Her indeholder \(\mathbf V\) egenbasisvektorerne som søjler. Resultatet vil altid være en diagonalmatrix, her betegnet ved \(\mathbf \Lambda\), som indeholder de tilhørende egenværdier i diagonalen.
I denne demo vil vi vise, hvordan man finder disse komponenter og udfører diagonalisering.
Ved simuleret håndregning#
Som et eksempel får vi givet følgende matrix \(\mathbf B\), som vi ønsker at diagonalisere:
B = Matrix([[0,1,0],[-2,3,0],[0,0,2]])
B
Diagonalmatricen \(\mathbf \Lambda\)#
Vi finder egenværdierne og egenvektorene ved:
B.eigenvects()
Vi ser her, at egenværdien \(1\) har en algebraisk multiplicitet på \(1\) samt én tilhørende egenvektor. Egenværdien \(2\) har en algebraisk multiplicitet på \(2\) og to tilhørende (lineært uafhængige) egenvektorer. Da summen af de geometriske multipliciteter og summen af de algebraiske multipliciteter er ens, er matricen diagonaliserbar (se den relevante sætning i lærebogen). Placerer vi derfor simpelthen egenværdierne i diagonalen i en diagonalmatrix, som vi kan kalde \(\mathbf \Lambda\), så er \(\mathbf \Lambda\) dermed diagonaliseringen af \(\mathbf B\):
Lambda = Matrix.diag([1,2,2])
Lambda
Egenbasis#
Vi ved dog ikke, med hensyn til hvilken ordnet egenbasis at ovenstående er tilfældet. Så lad os finde denne egenbasis og derefter bekræfte, at ligningen \(\mathbf V^{-1}\,\mathbf B\,\mathbf V=\mathbf \Lambda\) stemmer. Først kan vi opskrive egenrummene for at få et overblik:
Lad os definere egenvektorerne:
v1 = Matrix([1,1,0])
v2 = Matrix([S(1)/2,1,0])
v3 = Matrix([0,0,1])
v1,v2,v3
En sætning i lærebogen fortæller, at egenvektorerne \(\mathbf v_1,\mathbf v_2,\mathbf v_3\) udgør en lineært uafhængig sekvens. Derfor udgør de en basis, som altså er en egenbasis. Sætningen fortæller yderligere, at \(\mathbf V = [\mathbf v_1\ \mathbf v_2\ \mathbf v_3]\) er invertibel. Lad os definere \(\mathbf V\) og bestemme dens inverse matrix \(\mathbf V^{-1}\):
V = Matrix.hstack(v1,v2,v3)
V, V.inv()
Har vi sat vektorerne som søjler i \(\mathbf V\) i rigtig rækkefølge? Ja, for \(\mathbf v_1\) tilhører \(\lambda_1\), \(\mathbf v_2\) tilhører \(\lambda_2\), og \(\mathbf v_3\) tilhører \(\lambda_3\). Lad os tjekke, at ligningen er opfyldt:
V.inv()*B*V , Lambda
V.inv()*B*V==Lambda
True
Som forventet!
Bemærk: rækkefølgen af vektorerne som søjler i \(\mathbf V\) er ikke vigtig, og vi kan vælge denne rækkefølge (dvs. vi kan ordne vores egenbasis) som vi vil. Tilsvarende er rækkefølgen af egenværdierne i diagonalen i \(\mathbf \Lambda\) heller ikke vigtig, og der er dermed flere mulige diagonalmatricer, som matricen kan diagonaliseres til. Men det er dog vigtigt, at rækkefølgerne stemmer overens mellem de to matricer! Med andre ord skal egenvektoren, der udgør den første søjle i \(\mathbf V\), tilhøre den egenværdi, der er det første diagonalelement i \(\mathbf \Lambda\), og så videre. Ellers vil ligningen ikke være opfyldt. Se mere i lærebogen.
Ved brug af SymPy-kommandoer#
Som et eksempel får vi givet følgende matrix \(\mathbf C\):
C = Matrix([[6,2,4],[2,9,-2],[4,-2,6]])
C
Vi bemærker, at \(\mathbf C\) er symmetrisk. Jævnfør en sætning i lærebogen ved vi derfor med det samme, at \(\mathbf C\) er diagonaliserbar. Vi kan tjekke dette med følgende kommando, hvis vi skulle være i tvivl:
C.is_diagonalizable()
True
Da \(\mathbf C\) er diagonaliserbar, kan vi bestemme matricerne \(\mathbf V\) og \(\mathbf \Lambda\) ved hjælp af .diagonalize()
:
V, Lambda = C.diagonalize()
V, Lambda
Lad os bekræfte, at \(\mathbf C = \mathbf V\mathbf \Lambda \mathbf V^{-1}\), og at \(\mathbf \Lambda = \mathbf V^{-1} \mathbf C \mathbf V:\)
V * Lambda * V.inv()
V * Lambda * V.inv()==C
True
V.inv() * C * V , Lambda
V.inv() * C * V==Lambda
True