Uge 4: Spektralsætningen, diagonalisering og Hermitiske matricer#
Demo af Christian Mikkelstrup, Hans Henrik Hermansen, Magnus Troen, Karl Johan Måstrup Kristensen og Jakob Lemvig
from sympy import *
from dtumathtools import *
init_printing()
Symmetriske og Hermitiske matricer#
I SymPy kan matricer checkes for symmetri og Hermetiske egenskaber:
Enten ved enten simuleret håndregning:
A = Matrix([[6,2,4],[2,9,-2],[4,-2,6]])
A, A.T, A - A.T
B = Matrix([[6,2+7*I,4-4*I],[2-7*I,9,-2],[4+4*I,-2,6]])
B, B.adjoint(), B.H, (B - B.adjoint(), B - B.H) # A.H and A.adjoint() returns the same output in python
Bemærk at fordi matricen konjugeres i operationen
Eller ved brug af
SymPy
funktionerne:
# For A
A.is_symmetric(), A.is_hermitian
(True, True)
# For B
B.is_symmetric(), B.is_hermitian
(False, True)
Vær her opmærksom på at
# A.is_symmetric
Her står der at det vi prøver at udføre er en “bound method”, altså en funktion. Derfor skal parenteserne tilføjes:
A.is_symmetric()
True
Det er sjældent nødvendigt at bruge .is_symmetric()
, da man jo ofte kan afgøre om en matrix er symmetrisk ved at kigge på den. Endelig kan man tjekke om definitionen på en symmetrisk matrix er opfyldt direkte, nemlig om
A == A.T
True
Spektralsætningen#
Spektralsætningen giver et godt eksempel på hvorfor hermitiske (og reelt symmetriske) matricer er så utroligt praktiske. Særligt når det kommer til diagonalisering.
Betragt for eksempel den reelle og symmetriske matrix
A = Matrix([[1,2,0],
[2,3,2],
[0,2,1]])
A
Først finder vi egenvektorerne
ev = A.eigenvects()
ev
Da vi har 3 egenværdier der alle opfylder
Hvor
Q = Matrix.hstack(*[ev[i][2][0].normalized() for i in range(3)])
Q
# Undgå at bruge lambda som variabelnavn, da det er et reserveret ord i python brug lamda i stedet
lamda = Q.T*A*Q
lamda
For matricer med komplekse værdier kan samme tilgang bruges, så længe der arbejdes med normale matricer. Altså matricer der opfylder
Bemærk at alle hermitiske matricer også er normale, da
medfører
Se for eksempel matricen:
A = Matrix([[1,2*I,0],
[-2*I,3,1+I],
[0,1-I,1]])
display(A, A.is_hermitian)
True
# egenvektorerne findes
ev = A.eigenvects()
ev
U = Matrix.hstack(*[ev[i][2][0].normalized() for i in range(3)])
# U er en unitær matrix
simplify(U*U.H), simplify(U.H*U)
simplify(U.H*A*U)
Diagonalisering af en symmetrisk matrix ved ortogonal substitution#
Hvis man løber ind i et tilfælde hvor en egenværdi for en symmetrisk matrix har
A = Matrix([[6,2,4],[2,9,-2],[4,-2,6]])
A
Her ser vi at en egenværdi har algebraisk multiplicitet 2 og to egenvektorer
A.eigenvects()
Så hvis vi, som før, nøjes med at normaliserer egenvektorene
v_1 = Matrix([-1,Rational(1,2),1])
v_2 = Matrix([Rational(1,2),1,0])
v_3 = Matrix([1,0,1])
[v.normalized() for v in [v_1,v_2,v_3]]
(Eller i et “go” uden at skulle skrive
V, Lamda = A.diagonalize()
[v_1,v_2,v_3] = [V.col(k) for k in range(3)] # hver søjle i V tilgås og gemmes som vektor
q_1, q_2, q_3 = [v.normalized() for v in [v_1, v_2, v_3]]
display([v_1,v_2,v_3])
print('\t | (normalize)')
print('\t q')
display([q_1,q_2,q_3])
| (normalize)
q
og opstiller den ønskede
Q = Matrix.hstack(q_1,q_2,q_3)
Q
kan vi se at matricen desværre ikke er reel ortogonal:
Q.T * Q
da de to sidste søjler i
Heldigvis kan vi dog bruge en metode i har lært, GramSchmidt-algoritmen i disse tilfælde. For egenvektorer med ens egenværdier udføres GramSchmidt, og egenvektorer hvor
q_1 = v_1.normalized()
q_2, q_3 = GramSchmidt([v_2, v_3], orthonormal=True)
Q = Matrix.hstack(q_1,q_2,q_3)
Q
Rækkefølgen af egenværdierne i diagonalmatricen
Lamda
Lad os tjekke at Gram-Schmidt ikke har ændret ved
Lamda == Q.T*A*Q
True
Som forventet er
Positiv (semi-)definite matricer#
Positivt (semi-)definite matricer har nogle egenskaber der gør dem endnu nemmere at regne med. De er desuden hermitiske og opfylder derfor alt der er gennemgået i denne demo. Det er mest noget man lægger mærke til ved manipulationer af matricer, og derfor ikke noget vi nødvendigvis bemærker når vi anvender SymPy
/CAS. SymPy
er dog udstyret med to funktioner der gør det nemt at finde ud af hvorvidt en matrix er positivt definit eller positivt semidefinit.
Betragt de to hermitiske matricer
A = Matrix([[5,8,4,1],
[8,17,8,2],
[4,8,5,0],
[1,2,0,1]])
B = Matrix([[1,-1,2,0],
[-1,4,-1,1],
[2,-1,6,-2],
[0,1,-2,4]])
A,B
A.is_positive_definite, B.is_positive_definite
(False, True)
Vi kunne også forsøge at bevise at SymPy
. I stedet vil thm 2.9.1 (ii) være lettere at arbejde med. Altså vil vi vise at
B.eigenvals()

Det er ikke særlig tydeligt at disse egenværdier skulle være positive, og de ser oven i købet ud til at være komplekse. Vi kan i stedet prøve at kigge på de nummeriske værdier.
for eigenval in B.eigenvals():
print(eigenval.evalf(15))
3.10533934717727 - 1.39585627777974e-29*I
0.0216077757381638 + 2.41351647874518e-30*I
8.26801827124053 + 3.58918706790694e-31*I
3.60503460584404 + 1.11861275922615e-29*I
Her kunne man argumentere for at imaginærdelene er så tilpas små at de kan antages at være 0, og være tilfreds. Det er dog hverken et særlig godt eller tydeligt bevis.
Man kan være heldig at have en matrix med pænere egenværdier. SymPy
s funktioner kan altså bruges til at kontrolere, men vi anbefaler at beviser udføres i hånden i stedet.