Le module sympy permet de faire du calcul formel avec le langage de programmation Python alors que le module Numpy est utilisé pour le calcul numérique.
On importe le module:
import sympy as s
On crée la matrice $J=\left(\begin{array}{ccc}1&1&1\\1&1&1\\ 1&1&1\end{array}\right)$.
J=s.Matrix([[1,1,1],[1,1,1],[1,1,1]]) # Matrix et non pas matrix
J # on demande la valeur de la variable J
On remarque que l'affichage dans le notebook est élégant. Pour faire la même chose dans la console de Spyder il faut exécuter l'instruction:
s.init_printing()
Tous les calculs usuels vus en mathématiques peuvent être effectués facilement avec Sympy.
L'image s'obtient avec la méthode ${\tt columnspace()}$. On obtient une base $\hbox{Im}(J)$ sous forme d'une liste.
J.columnspace()
Une base du noyau s'obtient avec la méthode ${\tt nullspace()}$.
J.nullspace()
Le rang s'obtient avec la méthode ${\tt rank()}$.
J.rank()
Le déterminant s'obtient avec la méthode ${\tt det()}$.
J.det()
Les valeurs propres sont calculées avec la méthode ${\tt eigenvals()}$. Elles sont donnée sous la forme d'un dictionnaire dont les clés sont les valeurs propres et les valeurs sont les multiplicités.
J.eigenvals()
Les vecteurs propres sont obtenus avec la méthode ${\tt eigenvects()}$. Elles sont données sous la forme d'une liste de tuples. Chaque tuple a 3 composantes: la valeur propre, sa multiplicité et une base de l'espace propre associé donnée sous forme d'une liste.
J.eigenvects()
Le polynôme caractéristique est obtenu avec la méthode ${\tt charpoly()}$. Par défaut la variable est $\lambda$.
J.charpoly()
Les racines se calculent avec la fonction ${\tt roots()}$. Elles sont données sous la forme d'un dictionnaire dont les clés sont les racines et les valeurs leur multiplicité.
p=J.charpoly()
s.roots(p) # roots est une fonction et pas une méthode donc roots(p) et pas p.roots()
Pour diagonaliser il suffit d'utiliser la méthode ${\tt diagonalize()}$. Elle donne un tuple de deux matrices $P$ et $D$: $P$ est la matrice de passage et $D$ et la matrice diagonale.
J.diagonalize()
Pour définir les matrices P et D on exécute:
P,D = J.diagonalize()
P
D
On vérifie:
P*D*P**(-1)
On retrouve bien la matrice $J$.
On teste avec une matrice non diagonalisable.
M = s.Matrix([[0,1],[0,0]])
M
M.diagonalize()
--------------------------------------------------------------------------- MatrixError Traceback (most recent call last) /tmp/ipykernel_24155/2701378947.py in <cell line: 1>() ----> 1 M.diagonalize() ~/env/lib/python3.10/site-packages/sympy/matrices/matrices.py in diagonalize(self, reals_only, sort, normalize) 386 387 def diagonalize(self, reals_only=False, sort=False, normalize=False): --> 388 return _diagonalize(self, reals_only=reals_only, sort=sort, 389 normalize=normalize) 390 ~/env/lib/python3.10/site-packages/sympy/matrices/eigen.py in _diagonalize(M, reals_only, sort, normalize) 719 720 if not is_diagonalizable: --> 721 raise MatrixError("Matrix is not diagonalizable") 722 723 if sort: MatrixError: Matrix is not diagonalizable
On utilise le sous-module d'algèbre linéaire ${\tt numpy.linalg}$.
import numpy as np
import numpy.linalg as alg
On crée la matrice $J=\left(\begin{array}{ccc}1&1&1\\1&1&1\\ 1&1&1\end{array}\right)$.
J=np.matrix([[1,1,1],[1,1,1],[1,1,1]]) # cett fois c'est matrix et non pas Matrix
J
matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
Le rang s'obtient avec la fonction ${\tt matrix}\_{\tt rank()}$.
alg.matrix_rank(J)
1
Une valeur approchée du déterminant s'obtient avec la fonction ${\tt det()}$.
alg.det(J)
La fonction ${\tt eigvals()}$ renvoie des valeurs approchées des valeurs propres de la matrice. Elles sont données sous forme d'un tableau Numpy et les valeurs propres multiples apparaissent autant de fois que leur multiplicité.
alg.eigvals(J)
array([-2.22044605e-16, 3.00000000e+00, 0.00000000e+00])
Pour obtenir en plus des valeurs approchés des vecteurs propres associés, il faut employer la fonction ${\tt eig()}$. On obtient un tuple de deux éléments: le premier est un tableau numpy des valeurs propres, le seconde une matrice numpy des vecteurs propres associés en colonne.
alg.eig(J)
(array([-2.22044605e-16, 3.00000000e+00, 0.00000000e+00]), matrix([[-0.81649658, 0.57735027, 0. ], [ 0.40824829, 0.57735027, -0.70710678], [ 0.40824829, 0.57735027, 0.70710678]]))