Open In Colab

Eigendecomposition: Python Example¶

Example¶

In [ ]:
# import SymPy. It is a neat Python library for symbolic mathematics
from sympy import *
In [ ]:
# Define a 4x4 matrix
# You might also want to try other matrices.
A = Matrix([[2,-1,-1,0],[-1,3,-1,-1], [-1,-1,3,-1],[0,-1,-1,2]])
A
Out[ ]:
$\displaystyle \left[\begin{matrix}2 & -1 & -1 & 0\\-1 & 3 & -1 & -1\\-1 & -1 & 3 & -1\\0 & -1 & -1 & 2\end{matrix}\right]$
In [ ]:
A.eigenvects
Out[ ]:
sympy.matrices.matrices.MatrixEigen.eigenvects
def eigenvects(error_when_incomplete=True, iszerofunc=_iszero, **flags)
/usr/local/lib/python3.10/dist-packages/sympy/matrices/matrices.pyCompute eigenvectors of the matrix.

Parameters
==========

error_when_incomplete : bool, optional
    Raise an error when not all eigenvalues are computed. This is
    caused by ``roots`` not returning a full list of eigenvalues.

iszerofunc : function, optional
    Specifies a zero testing function to be used in ``rref``.

    Default value is ``_iszero``, which uses SymPy's naive and fast
    default assumption handler.

    It can also accept any user-specified zero testing function, if it
    is formatted as a function which accepts a single symbolic argument
    and returns ``True`` if it is tested as zero and ``False`` if it
    is tested as non-zero, and ``None`` if it is undecidable.

simplify : bool or function, optional
    If ``True``, ``as_content_primitive()`` will be used to tidy up
    normalization artifacts.

    It will also be used by the ``nullspace`` routine.

chop : bool or positive number, optional
    If the matrix contains any Floats, they will be changed to Rationals
    for computation purposes, but the answers will be returned after
    being evaluated with evalf. The ``chop`` flag is passed to ``evalf``.
    When ``chop=True`` a default precision will be used; a number will
    be interpreted as the desired level of precision.

Returns
=======

ret : [(eigenval, multiplicity, eigenspace), ...]
    A ragged list containing tuples of data obtained by ``eigenvals``
    and ``nullspace``.

    ``eigenspace`` is a list containing the ``eigenvector`` for each
    eigenvalue.

    ``eigenvector`` is a vector in the form of a ``Matrix``. e.g.
    a vector of length 3 is returned as ``Matrix([a_1, a_2, a_3])``.

Raises
======

NotImplementedError
    If failed to compute nullspace.

Examples
========

>>> from sympy import Matrix
>>> M = Matrix(3, 3, [0, 1, 1, 1, 0, 0, 1, 1, 1])
>>> M.eigenvects()
[(-1, 1, [Matrix([
[-1],
[ 1],
[ 0]])]), (0, 1, [Matrix([
[ 0],
[-1],
[ 1]])]), (2, 1, [Matrix([
[2/3],
[1/3],
[  1]])])]

See Also
========

eigenvals
MatrixSubspaces.nullspace
In [ ]:
# eigenvects() returns a list of tuples of the form (eigenvalue, algebraic_multiplicity, [eigenvectors])
# We will only need the eigenvalues and eigenvectors
eig_vecs = A.eigenvects()
eig_vecs[0]
Out[ ]:
(0,
 1,
 [Matrix([
  [1],
  [1],
  [1],
  [1]])])
In [ ]:
# Extract the eigenvectors from eig_vecs
v = [v for ev in eig_vecs for v in ev[-1]]
v
Out[ ]:
[Matrix([
 [1],
 [1],
 [1],
 [1]]),
 Matrix([
 [-1],
 [ 0],
 [ 0],
 [ 1]]),
 Matrix([
 [ 0],
 [-1],
 [ 1],
 [ 0]]),
 Matrix([
 [ 1],
 [-2],
 [ 0],
 [ 1]])]
In [ ]:
# Extract the eigenvalues from eig_vecs
λ = [ev[0] for ev in eig_vecs for _ in range(len(ev[-1]))]
λ
Out[ ]:
[0, 2, 4, 4]
In [ ]:
Q = Matrix.hstack(*v)
Q
Out[ ]:
$\displaystyle \left[\begin{matrix}1 & -1 & 0 & 1\\1 & 0 & -1 & -2\\1 & 0 & 1 & 0\\1 & 1 & 0 & 1\end{matrix}\right]$
In [ ]:
Λ = diag(*λ)
Λ
Out[ ]:
$\displaystyle \left[\begin{matrix}0 & 0 & 0 & 0\\0 & 2 & 0 & 0\\0 & 0 & 4 & 0\\0 & 0 & 0 & 4\end{matrix}\right]$
In [ ]:
# Use the relation we found above:
A_new = Q * Λ * Q**-1
A_new
Out[ ]:
$\displaystyle \left[\begin{matrix}2 & -1 & -1 & 0\\-1 & 3 & -1 & -1\\-1 & -1 & 3 & -1\\0 & -1 & -1 & 2\end{matrix}\right]$
In [ ]:
# Verify, that our 'new' matrix is in fact equal to the original one
A_new == A
Out[ ]:
True