SymPy Demo 5: Diagonalization#

Demo by Christian Mikkelstrup, Hans Henrik Hermansen, Karl Johan Måstrup Kristiansen, and Magnus Troen. Revised 11-11-24 by shsp.

from sympy import *
init_printing()

According to the course textbook, a matrix \(\mathbf A\) is diagonalizable if it has enough linearly independent eigenvectors to form a basis from. The diagonalization then takes place by switching to coordinates with respect to this eigenbasis:

\[\mathbf V^{-1}\,\mathbf A\,\mathbf V=\mathbf \Lambda.\]

Here \(\mathbf V\) contains the eigenbasis vectors as columns. The result will then always be a diagonal matrix, here denoted by \(\mathbf \Lambda\), containing the associated eigenvalues in the diagonal.

In this demo we will showcase how to find these components and carry out the diagonalization.

Simulated Manually#

As an example, we are given the following matrix \(\mathbf B\), which we wish to diagonalize:

B = Matrix([[0,1,0],[-2,3,0],[0,0,2]])
B
\[\begin{split}\displaystyle \left[\begin{matrix}0 & 1 & 0\\-2 & 3 & 0\\0 & 0 & 2\end{matrix}\right]\end{split}\]

The Diagonal Matrix \(\mathbf \Lambda\)#

We find the eigenvalues and eigenvectors by:

B.eigenvects()
\[\begin{split}\displaystyle \left[ \left( 1, \ 1, \ \left[ \left[\begin{matrix}1\\1\\0\end{matrix}\right]\right]\right), \ \left( 2, \ 2, \ \left[ \left[\begin{matrix}\frac{1}{2}\\1\\0\end{matrix}\right], \ \left[\begin{matrix}0\\0\\1\end{matrix}\right]\right]\right)\right]\end{split}\]

We see that the eigenvalue \(1\) has an algebraic multiplicity of \(1\) and has one corresponding eigenvector. The eigenvalue \(2\) has an algebraic multiplicity of \(2\) and two corresponding (linearly independent) eigenvectors. Since the sum of geometric multiplicities and the sum of algebraic multiplicities are equal, the matrix is diagonalizable (see the theorem in the course textbook). Hence, by simply placing the eigenvalues in the diagonal of a diagonal matrix which we can call \(\mathbf \Lambda\), then \(\mathbf \Lambda\) is the diagonalization of \(\mathbf B\):

Lambda = Matrix.diag([1,2,2])
Lambda
\[\begin{split}\displaystyle \left[\begin{matrix}1 & 0 & 0\\0 & 2 & 0\\0 & 0 & 2\end{matrix}\right]\end{split}\]

The Eigenbasis#

We do not know with respect to which ordered eigenbasis this is the case, though. So, let us find that eigenbasis and then confirm that the equation \(\mathbf V^{-1}\,\mathbf B\,\mathbf V=\mathbf \Lambda\) fits. First, we can write out the eigenspaces for an overview:

\[\begin{split} \begin{aligned} E_1 = & \text{span}\,((1,1,0))\\ E_2 = & \text{span}\,((1/2,1,0),(0,0,1)). \end{aligned} \end{split}\]

Let us define the eigenvectors:

v1 = Matrix([1,1,0])
v2 = Matrix([S(1)/2,1,0])
v3 = Matrix([0,0,1])
v1,v2,v3
\[\begin{split}\displaystyle \left( \left[\begin{matrix}1\\1\\0\end{matrix}\right], \ \left[\begin{matrix}\frac{1}{2}\\1\\0\end{matrix}\right], \ \left[\begin{matrix}0\\0\\1\end{matrix}\right]\right)\end{split}\]

A theorem in the course textbook ensures that the eigenvectors \(\mathbf v_1,\mathbf v_2,\mathbf v_3\) is a linearly independant sequence. Hence they constitute a basis, which is an eigenbasis. The theorem further ensures that \(\mathbf V = [\mathbf v_1\ \mathbf v_2\ \mathbf v_3]\) is invertible. Let us define \(\mathbf V\) and determine its inverse matrix \(\mathbf V^{-1}\):

V = Matrix.hstack(v1,v2,v3)
V, V.inv()
\[\begin{split}\displaystyle \left( \left[\begin{matrix}1 & \frac{1}{2} & 0\\1 & 1 & 0\\0 & 0 & 1\end{matrix}\right], \ \left[\begin{matrix}2 & -1 & 0\\-2 & 2 & 0\\0 & 0 & 1\end{matrix}\right]\right)\end{split}\]

Have we placed the vectors as columns in \(\mathbf V\) in the right order? Ja, because \(\mathbf v_1\) belongs to \(\lambda_1\), \(\mathbf v_2\) belongs to \(\lambda_2\), and \(\mathbf v_3\) belongs to \(\lambda_3\). Let’s us check if the equation is fulfilled:

V.inv()*B*V , Lambda
\[\begin{split}\displaystyle \left( \left[\begin{matrix}1 & 0 & 0\\0 & 2 & 0\\0 & 0 & 2\end{matrix}\right], \ \left[\begin{matrix}1 & 0 & 0\\0 & 2 & 0\\0 & 0 & 2\end{matrix}\right]\right)\end{split}\]
V.inv()*B*V==Lambda
True

As expected!

Note: the order of the vectors as columns in \(\mathbf V\) doesn’t matter, and we may choose this order (meaning, we may order the eigenbasis) as we wish. Similarly, the order of eigenvalues eigenvalues in the diagonal of \(\mathbf \Lambda\) doesn’t matter, meaning that there are several possible diagonal matrices that the matrix can be diagonalized to. But it is, though, important that their orders match between the two matrices! Meaning, the eigenvector that constitutes the first column in \(\mathbf V\) must be associated with the eigenvalue placed as the first diagonal element in \(\mathbf \Lambda\) and so on. Otherwise the equation will not hold true. See more in the course textbook.

Using SymPy Commands#

As an example, the following matrix \(\mathbf C\) is given:

C = Matrix([[6,2,4],[2,9,-2],[4,-2,6]])
C
\[\begin{split}\displaystyle \left[\begin{matrix}6 & 2 & 4\\2 & 9 & -2\\4 & -2 & 6\end{matrix}\right]\end{split}\]

We notice that \(\mathbf C\) is symmetric. Hence (according to a theorem in the course textbook) we immediately know that \(\mathbf C\) is diagonalizable. We can check with the following command, should we be in doubt:

C.is_diagonalizable()
True

Since \(\mathbf C\) is diagonalizable, then we can determine matrices \(\mathbf V\) and \(\mathbf \Lambda\) using .diagonalize():

V, Lambda = C.diagonalize()
V, Lambda
\[\begin{split}\displaystyle \left( \left[\begin{matrix}-2 & 1 & 1\\1 & 2 & 0\\2 & 0 & 1\end{matrix}\right], \ \left[\begin{matrix}1 & 0 & 0\\0 & 10 & 0\\0 & 0 & 10\end{matrix}\right]\right)\end{split}\]

Let us confirm that \(\mathbf C = \mathbf V\mathbf \Lambda \mathbf V^{-1}\) and that \(\mathbf \Lambda = \mathbf V^{-1} \mathbf C \mathbf V:\)

V * Lambda * V.inv() 
\[\begin{split}\displaystyle \left[\begin{matrix}6 & 2 & 4\\2 & 9 & -2\\4 & -2 & 6\end{matrix}\right]\end{split}\]
V * Lambda * V.inv()==C
True
V.inv() * C * V 
\[\begin{split}\displaystyle \left[\begin{matrix}1 & 0 & 0\\0 & 10 & 0\\0 & 0 & 10\end{matrix}\right]\end{split}\]
V.inv() * C * V==Lambda
True