Séance 7#
Objectifs
Vecteurs
Matrices
Résolution de systèmes linéaires
Vecteurs et espaces vectoriels#
Commençons par essayer de représenter des espaces vectoriels (de dimension finie) et leurs éléments, des vecteurs.
Création et classe parente#
En mathématiques, un vecteur est un élément d’un espace vectoriel. L’espace vectoriel canonique est \(\mathbb{K}^n\), où \(\mathbb{K}\) est un corps (par exemple, \(\mathbb{K} = \mathbb{Q}, \mathbb{R}, \mathbb{C}\), etc.) et \(n \ge 1\) est un entier.
Avec Sagemath, on peut créer un objet de type vecteur avec la commande vector(). Cette commande prend comme arguments :
de manière optionnelle (mais fortement conseillée), le corps de définition des coefficients,
de manière obligatoire, la liste des coefficients du vecteur.
Par exemple, pour créer le vecteur \((1, \frac{1}{2}, -3) \in \mathbb{Q}^3\), on exécute
v = vector(QQ, [1, 1/2, -3])
print(v)
(1, 1/2, -3)
De même, pour créer le vecteur \((1.2, \pi/2, -\sqrt{2})\) dans le corps des nombres flottants (à \(53\) bits de précision), on peut écrire simplement :
w = vector(RR, [1.2, pi/2, -sqrt(2)])
print(w)
(1.20000000000000, 1.57079632679490, -1.41421356237310)
Remarque : il existe une fonction spéciale pour créer un vecteur nul, zero_vector, qui s’utilise ainsi (dans l’exemple, pour créer \(\mathbf{0} \in \mathbb{Q}^{20}\):
z = zero_vector(QQ, 20)
print(z)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
Observons que les classes parentes de ces éléments sont bien des espaces vectoriels.
print(parent(v))
print(parent(w))
Vector space of dimension 3 over Rational Field
Vector space of dimension 3 over Real Field with 53 bits of precision
Opérations élémentaires#
Avec Sagemath, on peut facilement manipuler les vecteurs. Les opérations usuelles de l’espace vectoriel (addition et multiplication scalaire) sont déjà écrites.
a = vector(QQ, [1, 1/2, -3])
b = vector(QQ, [0, -7/3, 2])
c = a + b
d = (-1/2)*a
print(c)
print(d)
(1, -11/6, -1)
(-1/2, -1/4, 3/2)
On retrouve également le produit scalaire entre les deux vecteurs a et b, sous la forme d’une méthode a.inner_product(b), mais également avec l’opérateur a * b. Il faudra néanmoins prendre garde à l’utilisation de l’opérateur * qui peut parfois être trompeuse, notamment si l’un des deux opérandes n’est pas un objet de type vecteur.
Notons enfin que la classe parente du résultat de ce calcul est bien le corps de définition des coefficients.
a = vector(QQ, [1, 1/2, -3])
b = vector(QQ, [0, -7/3, 2])
x = a.inner_product(b)
print(x)
print(x == a * b)
print(parent(x))
-43/6
True
Rational Field
On peut accéder aux coefficients d’un vecteur comme on le ferait avec une liste. Par exemple, pour avoir la deuxième coordonnée (celle d’indice \(1\)) du vecteur v, on entre v[1].
v = vector(QQ, [1, 1/2, -3])
print(v[1])
1/2
Espace vectoriel#
La classe parente des vecteurs pourra vous être utile, par exemple pour tirer aléatoirement des vecteurs, ou pour effectuer des coercions.
On peut directement créer un espace vectoriel grâce à la commande VectorSpace(K, n), qui prend en entrée un corps K et un entier positif n.
E = VectorSpace(QQ, 5)
print(E)
e = E.random_element()
print(e)
Vector space of dimension 5 over Rational Field
(0, -1/2, 2/3, 0, 1)
Matrices#
Passons désormais aux matrices.
Création et manipulation de matrices#
La création et la manipulation de matrices est assez similaire à celle des vecteurs. On utilise pour cela le constructeur matrix, qui prend comme argument :
de manière optionnelle, le corps (ou l’anneau) sur lequel sont définis les coefficients de la matrice à créer,
les coefficients de la matrice sous la forme d’une liste
Lde sous-listes toutes de même longueur, où la sous-listeL[i]deLcorrespond aux coefficients de la ligne d’indice \(i+1\) de la matrice.
Par exemple, si l’on souhaite créer la matrice :
on écrira
M = matrix(QQ, [ [1, 2, 3], [4, 5, 6] ] )
print(M)
[1 2 3]
[4 5 6]
Il existe une seconde manière de créer une matrice, toujours avec le mot-clef matrix. Cette fois-ci, on donne \(4\) arguments :
de manière optionnelle, le corps (ou l’anneau) de définition des coefficients,
le nombre \(m\) de lignes de la matrice,
le nombre \(n\) de colonnes de la matrice,
la liste des \(nm\) coefficients de la matrice, en commençant par les coefficients de la première ligne (décrits de gauche à droite), puis ceux de la deuxième, etc. jusqu’à la dernière.
En reprenant l’exemple précédent on obtient :
M = matrix(QQ, 2, 3, [ 1, 2, 3, 4, 5, 6 ] )
print(M)
[1 2 3]
[4 5 6]
Avec l’interface jupyter (mais pas sur le rendu de la page web), on peut obtenir un meilleur affichage des matrices avec la fonction show() :
# show(M)
Cela fonctionne également pour d’autres objets (polynômes, expressions symboliques, etc.). On peut également générer le code LaTeX correspondant à une matrice (ou un auttre objet), ce qui est pratique pour l’édition de documents scientifiques avec des objets mathématiques de grande taille.
latex(M)
\left(\begin{array}{rrr}
1 & 2 & 3 \\
4 & 5 & 6
\end{array}\right)
La classe parente des matrices est un espace de matrices nommé généralement MatrixSpace.
print(M.parent())
Full MatrixSpace of 2 by 3 dense matrices over Rational Field
Comme pour les vecteurs, on peut additionner ou soustraire deux matrices de même taille, et multiplier une d’entre elles par un scalaire :
M = matrix(QQ, 2, 3, [ 1, 2, 3, 4, 5, 6 ] )
N = matrix(QQ, 2, 3, [ 0, 1/2, -1, 2, 1/3, 0 ] )
print(M - 2*N)
[ 1 1 5]
[ 0 13/3 6]
On peut enfin les multiplier entre elles si leurs tailles concordent.
M = matrix(QQ, 2, 3, [ 1, 2, 3, 4, 5, 6 ] )
A = matrix(QQ, 3, 2, [ 0, 1/2, -1, 2, 1/3, 0 ] )
print("M = ")
print(M)
print("\nA = ")
print(A)
print("\nLe produit donne")
print(M * A)
M =
[1 2 3]
[4 5 6]
A =
[ 0 1/2]
[ -1 2]
[1/3 0]
Le produit donne
[ -1 9/2]
[ -3 12]
Il est également possible de calculer les puissances d’une matrice et son inverse :
A = matrix(QQ, 3, 3, [ 1, 1, 1, 0, 1, 2, 0, 1, 4 ] )
print("A = ")
print(A)
print("\nA^2 = ")
print(A**2)
print("\nA^10 = ")
print(A**10)
print("\nA^(-1) = ")
print(A**(-1))
A =
[1 1 1]
[0 1 2]
[0 1 4]
A^2 =
[ 1 3 7]
[ 0 3 10]
[ 0 5 18]
A^10 =
[ 1 414783 1477267]
[ 0 531243 1892050]
[ 0 946025 3369318]
A^(-1) =
[ 1 -3/2 1/2]
[ 0 2 -1]
[ 0 -1/2 1/2]
Accès aux coefficients, aux lignes et aux colonnes#
Pour accéder au coefficient situé sur la ligne d’indice \(i\) et la colonne d’indice \(j\) d’une matrice M, on utilisera la syntaxe M[i,j].
M = matrix(QQ, 2, 3, [ 1, 2, 3, 4, 5, 6 ] )
print("Sur la matrice M =")
print(M)
print("le coefficient de coordonnées (0,1) est :", M[0,1])
Sur la matrice M =
[1 2 3]
[4 5 6]
le coefficient de coordonnées (0,1) est : 2
Pour accéder à une ligne ou une colonne spécifique d’une matrice, il existe les méthodes row(i) et column(j), qui retournent la ligne ou la colonne attendue, sous la forme d’un vecteur (pour les colonnes, l’affichage se fait donc en ligne).
print(M.row(0))
print(M.column(1))
(1, 2, 3)
(2, 5)
Autres propriétés et opérations#
On peut obtenir différentes propriétés ou paramètres d’une matrice. Par exemple, son rang avec la méthode rank(), ou (si la matrice est carrée), son déterminant et sa trace avec les méthodes det() et rank() :
A = matrix(QQ, 3, 3, [ 1, 1, 1, 2, 2, 2, 3, 4, 5 ] )
print(A)
print("Rang :", A.rank())
print("Det :", A.det())
print("Trace :", A.trace())
[1 1 1]
[2 2 2]
[3 4 5]
Rang : 2
Det : 0
Trace : 8
Également, on obtient la transposée d’une matrice par la méthode .transpose().
print(A.transpose())
[1 2 3]
[1 2 4]
[1 2 5]
Espaces vectoriels associés#
Les espaces vectoriels engendrés par les lignes et les colonnes sont accessibles avec les commandes .row_space() et .column_space().
M = matrix(QQ, [[1, 2, 3], [4, 5, 6]])
print("M = ")
print(M)
V = M.row_space()
print("\n--- Espace lignes ---")
print(V)
W = M.column_space()
print("\n--- Espace colonnes ---")
print(W)
M =
[1 2 3]
[4 5 6]
--- Espace lignes ---
Vector space of degree 3 and dimension 2 over Rational Field
Basis matrix:
[ 1 0 -1]
[ 0 1 2]
--- Espace colonnes ---
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 longueur de ses vecteurs (en nombre de coordonnées) avec .degree()
print("Base de l'espace ligne :")
print(V.basis())
print("\nDimension et longueur des vecteurs :", (V.dimension(), V.degree()))
Base de l'espace ligne :
[
(1, 0, -1),
(0, 1, 2)
]
Dimension et longueur des vecteurs : (2, 3)
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 bien définie sur un corps (par exemple, QQ ou RR).
M = matrix(QQ, [[1,1,1,1], [2,2,2,2], [3,4,5,6]])
print(M)
[1 1 1 1]
[2 2 2 2]
[3 4 5 6]
Pour le noyau à gauche :
print(M.left_kernel())
Vector space of degree 3 and dimension 1 over Rational Field
Basis matrix:
[ 1 -1/2 0]
Pour le noyau à droite :
print(M.right_kernel())
Vector space of degree 4 and dimension 2 over Rational Field
Basis matrix:
[ 1 0 -3 2]
[ 0 1 -2 1]
Création de matrices spécifiques#
Quelques matrices spécifiques possèdent leurs constructeurs propres. Cela permet un gain de temps non-négligeable dans la construction de ces matrices.
La matrice nulle, avec matrix.zero(K, m, n) ou son alias zero_matrix(K, m, n), où K est le corps (ou l’anneau) de définition, m est le nombre de lignes et n le nombre de colonnes :
Z = zero_matrix(QQ, 3, 5)
print(Z)
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
La matrice pleine de \(1\), avec matrix.ones(K, m, n) ou son alias ones_matrix(K, m, n), où K est le corps (ou l’anneau) de définition, m est le nombre de lignes et n le nombre de colonnes :
J = ones_matrix(QQ, 2, 2)
print(J)
[1 1]
[1 1]
La matrice identité, avec matrix.identity(K, n) ou son alias identity_matrix(K, n), où K est le corps (ou l’anneau) de définition, et n est le nombre de lignes et de colonnes :
I = identity_matrix(QQ, 3)
print(I)
[1 0 0]
[0 1 0]
[0 0 1]
Résolution de systèmes linéaires#
Supposons que l’on souhaite résoudre, sur le corps \(\mathbb{Q}\), le système linéaire
Rappelons que, mathématiquement, la méthode générique est la suivante :
on construit la matrice \(A\) associée au système,
on construit le vecteur \(b\) associé au système,
on « résout » l’équation \(Au = b\) pour avoir une solution particulière \(u = (x, y, z)\) du système,
on cherche l’ensemble des solutions homogènes du système, c’est-à-dire le noyau à droite de la matrice \(A\).
Attention ! Par défaut, Sagemath écrit les vecteurs comme des vecteurs lignes. Si vous souhaitez afficher un vecteur v sous forme de colonne, tapez v.column().
La seule opération qui nous manque pour effectuer les \(4\) étapes ci-dessus est le calcul d’une solution particulière. Sagemath nous propose pour cela la méthode A.solve_right(b), qui s’applique sur une matrice A avec comme paramètre un vecteur b, et qui retourne un vecteur u tel que A * u == b.
Exemple ci-dessous :
A = matrix(QQ, [[1, 1, 1], [2, 1, -1], [3, 2, 0]])
b = vector(QQ, [0, 1, 1])
u = A.solve_right(b) # on peut aussi écrire : u = A \ b
V = A.right_kernel()
print("Les solutions du système sont les vecteurs de la forme u + v avec")
print(" u =", u)
print("et v un élément de l'espace vectoriel de dimension", V.dimension(), "dont une base est :")
print(V.basis())
Les solutions du système sont les vecteurs de la forme u + v avec
u = (1, -1, 0)
et v un élément de l'espace vectoriel de dimension 1 dont une base est :
[
(1, -3/2, 1/2)
]
On peut faire une petite vérification, par exemple que, si \(v\) est un vecteur de la base du noyau, alors \(u + 6v\) est bien une solution du système :
v = V.basis()[0]
A*(u + 6*v) == b
True
Récapitulatif des instructions à connaître#
Tableau récapitulatif des instructions à connaître sur les matrices :
Méthode, fonction, instruction |
Description |
|---|---|
|
Crée une matrice sur un corps |
|
Crée une matrice sur un corps |
|
Crée la matrice nulle de taille |
|
Crée la matrice idnetité de taille |
|
Accès au coefficient \((i,j)\) de |
|
Nombre de lignes de la matrice |
|
Nombre de colonnes de la matrice |
|
Liste des lignes et des colonnes de la matrice |
|
Liste des colonnes de la matrice |
|
Ligne numéro |
|
Colonne numéro |
|
Rang de la matrice |
|
Déterminant de la matrice |
|
Trace de la matrice |
|
Transposée de la matrice |
|
Noyau à gauche de la matrice |
|
Une solution \(x\) de l’équation \(Mx = y\) (où |
Tableau récapitulatif des instructions à connaître sur les vecteurs et espaces vectoriels :
Méthode, fonction, instruction |
Description |
|---|---|
|
Crée un vecteur sur un corps |
|
Crée le vecteur nul de l’espace vectoriel sur |
|
Produit scalaire des vecteurs |
|
Coefficient d’indice |
|
Crée l’espace vectoriel canonique sur |
|
Base de l’espace vectoriel |
|
Dimension de l’espace vectoriel |
|
Dimension de l’espace vectoriel dans lequel est plongé |
|
Espace vectoriel engendré par les lignes de |
|
Espace vectoriel engendré par les colonnes de |
|
Noyau à droite de la matrice |
|
Noyau à gauche de la matrice |
D’autres méthodes :
Méthode |
Description |
|---|---|
|
Teste si la matrice |
|
Teste si la matrice |
|
Forme échelonnée réduite (par les lignes) de la matrice |