Support de cours semaine 7 : matrices et algèbre linéaire

Matrices

Création et manipulation de matrices

Il y a plusieurs manières de déclarer une matrice avec Sagemath. Supposons que l'on souhaite déclarer la matrice $$ M = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} $$

Première solution : avec une liste de listes, correspondant à la liste de ses lignes.

In [42]:
M = matrix( [ [1, 2, 3], [4, 5, 6] ] )
M
Out[42]:
[1 2 3]
[4 5 6]

Deuxième solution : avec une simple liste de coefficients, mais il faut alors préciser la taille de la matrice (nombre de lignes, puis nombre de colonnes) avant de donner la liste des coefficients.

In [43]:
M = matrix(2, 3, [1, 2, 3, 4, 5, 6])
M
Out[43]:
[1 2 3]
[4 5 6]

On peut également préciser à quelle structure les coefficients doivent appartenir (en premier argument de matrix()).

In [44]:
N = matrix(RR, 2, 3, [1, 2, 3, 4, 5, 6])
N
Out[44]:
[1.00000000000000 2.00000000000000 3.00000000000000]
[4.00000000000000 5.00000000000000 6.00000000000000]

Certaines matrices sont déjà prédéfinies : la matrice identité, la matrice nulle, la matrice pleine de $1$.

In [45]:
matrix.identity(4)
Out[45]:
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
In [46]:
matrix.zero(2, 3)
Out[46]:
[0 0 0]
[0 0 0]
In [47]:
matrix.ones(2, 3)
Out[47]:
[1 1 1]
[1 1 1]

Pour accéder au coefficient de ligne $i$ et colonne $j$ d'une matrice $M$ (attention, la première ligne/colonne commence à $0$) :

In [48]:
M = matrix(2, 3, [1, 2, 3, 4, 5, 6])
show(M)
i, j = 1, 2
M[i,j]
Out[48]:
6

Pour avoir la colonne $j$ entièrement :

In [49]:
M[:,2]
Out[49]:
[3]
[6]

Pour avoir la ligne $i$ entièrement :

In [50]:
M[1,:]
Out[50]:
[4 5 6]

Fonctionnalités sur des matrices quelconques

Les opérations élémenetaires sur les matrices sont bien implantées : addition, multiplication (par une matrice ou par un scalaire), mise à la puissance si c'est possible.

In [51]:
A = matrix(2, 2, [0, 1, 1, 0])
show(A, M)
In [52]:
X = A * M
show(X)
In [53]:
X + M
Out[53]:
[5 7 9]
[5 7 9]

Attention à ce que les opérations soient bien possibles :

In [54]:
# A + M
# M * A

Pour obtenir le rang d'une matrice :

In [55]:
M.rank()
Out[55]:
2

Pour calculer sa transposée

In [56]:
M.transpose()
Out[56]:
[1 4]
[2 5]
[3 6]

Fonctionnalités sur des matrices carrées

Pour calculer le déterminant d'une matrice :

In [57]:
M = matrix(ZZ, [[1, 1, 1], [1, 3, 7], [1, 9, 49]])
show(M)
M.determinant()
det(M)
Out[57]:
48

Pour calculer sa trace :

In [58]:
M.trace()
Out[58]:
53

Pour savoir si elle est inversible :

In [59]:
M.is_invertible()
Out[59]:
False

Attention, l'inversibilité dépend dans quel anneau les coefficients sont considérés (les matrices inversibles sur $\mathbb{Z}$ sont celles de déterminant $\pm 1$). Modifions cet anneau en QQ au lieu de ZZ.

In [60]:
M = M.change_ring(QQ)
M.is_invertible()
Out[60]:
True

Pour calculer son inverse :

In [61]:
M.inverse()
M**(-1)
Out[61]:
[ 7/4 -5/6 1/12]
[-7/8    1 -1/8]
[ 1/8 -1/6 1/24]

Pour calculer son polynôme caractéristique :

In [62]:
M.characteristic_polynomial()
Out[62]:
x^3 - 53*x^2 + 134*x - 48

Pour obtenir ses valeurs propres :

In [63]:
valeurs_propres = M.eigenvalues()
valeurs_propres
Out[63]:
[0.4311268220764297?, 2.210893890960519?, 50.35797928696306?]

Les valeurs propres étant des racines d'un polynôme de degré arbitraire, ils appartiennent au corps des éléments algébriques, noté AlgebraicField ou QQbar dans sagemath.

In [64]:
valeurs_propres[0].parent()
Out[64]:
Algebraic Field

Pour diagonaliser la matrice, en général on doit donc se placer dans ce corps des éléments algébriques :

In [65]:
M.diagonalization(QQbar)
Out[65]:
(
[0.4311268220764297?                   0                   0]
[                  0  2.210893890960519?                   0]
[                  0                   0  50.35797928696306?],

[  1.000000000000000?   1.000000000000000?   1.000000000000000?]
[-0.6729918517808461?   1.525747726992342?   6.374516852061232?]
[0.10411867385727582? -0.3148538360318228?   42.98346243490182?]
)

Algèbre linéaire

On peut créer un objet de type vecteur avec la commande vector() :

In [66]:
v = vector(QQ, [1, 2, 3, 4])
v
Out[66]:
(1, 2, 3, 4)

Les espaces vectoriels engendrés par les lignes et les colonnes sont accessibles avec les commandes .row_space() et .column_space()

In [67]:
M = matrix(QQ, [[1, 2, 3], [4, 5, 6]])
print("M = ")
show(M)

V = M.row_space()
print("V = ")
print(V)

W = M.column_space()
print("W = ")
print(W)
M = 
V = 
Vector space of degree 3 and dimension 2 over Rational Field
Basis matrix:
[ 1  0 -1]
[ 0  1  2]
W = 
Vector space of degree 2 and dimension 2 over Rational Field
Basis matrix:
[1 0]
[0 1]

On peut accéder à une base d'un espace vectoriel avec .basis(), à sa dimension avec .dimension(), et à la taille de ses vecteurs (en nombre de coordonnées) avec .degree()

In [68]:
V.basis()
Out[68]:
[
(1, 0, -1),
(0, 1, 2)
]
In [69]:
V.dimension(), V.degree()
Out[69]:
(2, 3)

Noyaux

On peut obtenir les noyaux à gauche et à droite d'une matrice $M$ avec .left_kernel() et .right_kernel(). Ce sont des espaces vectoriels si la matrice $M$ est définie sur un corps (par exemple, QQ ou RR).

In [70]:
M = matrix(QQ, [[1,1,1,1], [2,2,2,2], [3,4,5,6]])
show(M)
M.left_kernel()
Out[70]:
Vector space of degree 3 and dimension 1 over Rational Field
Basis matrix:
[   1 -1/2    0]
In [71]:
M.right_kernel()
Out[71]:
Vector space of degree 4 and dimension 2 over Rational Field
Basis matrix:
[ 1  0 -3  2]
[ 0  1 -2  1]

Vérifions le théorème du rang :

In [72]:
print(M.rank() + M.right_kernel().dimension() == M.ncols())
print(M.rank() + M.left_kernel().dimension() == M.nrows())
True
True

Systèmes linéaires

Supposons que l'on souhaite résoudre le système linéaire $$ \left\{\begin{array}{cccccccc} &x &+ & y &+ & z &= & 0 \\ &2x &+ &y &- &z &= &1 \\ &3x& + &2y&&& = &1 \end{array}\right. $$ On se place dans le corps QQ.

Méthode :

  1. on construit la matrice $A$ associée au système,
  2. on construit le vecteur $b$ associé au système,
  3. on "résout" l'équation $Au = b$ pour avoir une solution particulière $u = (x, y, z)$ du système
  4. on cherche la solution homogène du système, c'est-à-dire de noyau à droite de $A$

Attention ! Sagemath écrit les vecteurs comme des vecteurs lignes. Si vous souhaitez afficher un vecteur v sous forme de colonne, tapez v.column().

In [73]:
A = matrix(QQ, [[1, 1, 1], [2, 1, -1], [3, 2, 0]])
b = vector(QQ, [0, 1, 1])
u = A.solve_right(b)
V = A.right_kernel()

print("Les solutions du système sont les élément de la forme u + v avec\n")
print("  u =")
show(u.column())
print("  et v un élément de l'espace vectoriel de dimension", V.dimension(), "dont une base est")
show([v.column() for v in V.basis()])
v = V.basis()[0]

A*(u + 6*v) == b
Les solutions du système sont les élément de la forme u + v avec

  u =
  et v un élément de l'espace vectoriel de dimension 1 dont une base est
Out[73]:
True
In [ ]: