Section B.8 Orthogonal/unitary diagonalization
Subsection B.8.1 Orthogonally diagonalizing a symmetric matrix
Here we will use Sage to carry out the calculations in Example 40.5.1. First let's load our matrix into Sage.xxxxxxxxxx
S = matrix([
[ 0, 1, 0, 1 ],
[ 1, 0, 1, 0 ],
[ 0, 1, 0, 1 ],
[ 1, 0, 1, 0 ]
])
print(S)
Eigenvalues and eigenvectors.
First we need to carry out the diagonalization procedure (see Subsection 25.4.3).xxxxxxxxxx
S.eigenvalues()
xxxxxxxxxx
(2*identity_matrix(4) - S).rref()
xxxxxxxxxx
p1 = vector((1,1,1,1))
print(p1)
print(S*p1)
xxxxxxxxxx
(-2*identity_matrix(4) - S).rref()
xxxxxxxxxx
p2 = vector((-1,1,-1,1))
print(p2)
print(S*p2)
xxxxxxxxxx
S.rref()
p3=(−1,0,1,0),p4=(0,−1,0,1).
xxxxxxxxxx
p3 = vector((-1,0,1,0))
p4 = vector((0,-1,0,1))
print(p3,p4)
print(S*p3,S*p4)
The transition matrix.
We want an orthogonal transition matrix, so let's check which of our eigenvectors are orthogonal to the others. We know that for a symmetric matrix like S, eigenvectors from different eigenspaces should automatically be orthogonal:xxxxxxxxxx
print(p1 * p3)
print(p1 * p4)
print(p2 * p3)
print(p2 * p4)
xxxxxxxxxx
p3 * p4
xxxxxxxxxx
P = column_matrix([
p1 / sqrt(p1*p1),
p2 / sqrt(p2*p2),
p3 / sqrt(p3*p3),
p4 / sqrt(p4*p4)
])
print(P)
xxxxxxxxxx
print("P.T * P =")
print(P.T * P)
print()
print("P.T * S * P =")
print(P.T * S * P)
Subsection B.8.2 Unitarily diagonalizing a normal matrix
Here we will use Sage to carry out the calculations in Example 40.5.4.Set up.
First, let's create a convenience inner product function to minimize having to typeconjugate
a lot.
xxxxxxxxxx
def inprod(u,v):
return v.conjugate() * u
print("inprod function loaded")
I
to represent the imaginary root of x2+1.
xxxxxxxxxx
N = matrix([
[ 2 + I, 1 - I, 1 + I ],
[ 1 - I, 2 + I, -1 - I ],
[ -1 - I, 1 + I, 2 + I ]
])
print(N)
conjugate_transpose
to compute adjoints. Rather than check entry-by-entry that NN∗ and N∗N are equal, we can subtract the two — if they are equal, their difference should be the zero matrix.
xxxxxxxxxx
N * N.conjugate_transpose() - N.conjugate_transpose() * N
Eigenvalues and eigenvectors.
Our first step is to carry out the diagonalization procedure (see Subsection 25.4.3).xxxxxxxxxx
N.eigenvalues()
xxxxxxxxxx
((3*I)*identity_matrix(3) - N).rref()
xxxxxxxxxx
u1 = vector((-I, I, 1))
print(u1)
print(N * u1)
xxxxxxxxxx
(3*identity_matrix(3) - N).rref()
u2=(1,1,0),u3=(i,0,1).
xxxxxxxxxx
u2 = vector((1,1,0))
u3 = vector((I,0,1))
print(u2,',',u3)
The transition matrix.
First let's form a transition matrix with the eigenvectors we currently have, to check that it diagonalizes.xxxxxxxxxx
U = column_matrix([u1,u2,u3])
U.inverse() * N * U
xxxxxxxxxx
U.conjugate_transpose() * U
xxxxxxxxxx
print(inprod(u1,u2))
print(inprod(u1,u3))
xxxxxxxxxx
inprod(u2,u3)
xxxxxxxxxx
v2 = u2
v3 = u3 - (inprod(u3,v2) / inprod(v2,v2)) * v2
print(v2,',',v3)
print(3*v3 - N*v3)
print(inprod(v2,v3))
xxxxxxxxxx
U = column_matrix([
u1 / sqrt(inprod(u1,u1)),
v2 / sqrt(inprod(v2,v2)),
v3 / sqrt(inprod(v3,v3))
])
print("U =")
print(U)
print()
print("U* U =")
print(U.conjugate_transpose() * U)
print()
print("U* N U =")
print(U.conjugate_transpose() * N * U)