\documentclass{article}% ===> this file was generated automatically by noweave --- better not edit it
%
% linalg.ltx
% Francois Maltey - janvier 2008
%
\usepackage[utf-8]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage[french]{babel}
\usepackage{xspace}
\newbox\thina
\newcommand{\axiom}
{\setbox\thina\hbox{.}\wd\thina=0mmax\raise-0.2em\box\thina{}iom\xspace}
\newcommand{\Axiom}
{\setbox\thina\hbox{.}\wd\thina=0mmAx\raise-0.2em\box\thina{}iom\xspace}
\binoppenalty=20000
\relpenalty=20000
\begin{document}
\title{Compléments d'algèbre linéaire}
\author{Fran\c{c}ois Maltey}
\maketitle
\tableofcontents
\begin{abstract}
De nombreuses manipulations d'algèbre linéaire en dimension finie se
traduisent par des systèmes d'équations linéaires.
La résolution de ceux-ci peut s'effectuer en éliminant
successivement les variables dans les équations
par la méthode du pivot de Gauss,
et correspond en fait à des opérations sur les lignes de la matrice
du système pour s'approcher d'une matrice triangulaire.
\par
La fonction \verb!rowEchelon! d'\axiom effectue cette transformation. Elle est
implantée dans le fichier \verb!matfuns.spad!. Les commandes
\verb!nullSpace!, \verb!rank! et \verb!nullity!
de recherche du noyau et du rang d'une matrice en dépendent ;
il en est de même des fonctions \verb!solve! et \verb!particularSolution! de
résolution des systèmes linéaires.
\par
Ce document présente la fonction \verb!rowEchelon! et les fonctions
associées pour les appliquer ensuite à la construction d'une base
d'un sous-espace vectoriel engendré par une famille de vecteurs,
et à la celle de bases de sommes et d'intersections de tels sous-espaces.
\end{abstract}
%%
%%
\section{Les fonctions d'\axiom}
\subsection{Matrice \'echelonn\'ee}
Cette présentation se limite aux espaces vectoriels sur
un corps~$\mathbb K$. Il est possible d'adapter cette théorie aux
modules sur des anneaux principaux.
\Axiom implante les deux méthodes.
\par
L'argument $A\in{\cal M}_{m,n}(\mathbb K)$
de la fonction \verb!rowEchelon!
est une matrice à $m \in {\mathbb N}^*$ lignes et $n \in {\mathbb N}^*$
colonnes ;
son résultat est une matrice échelonnée
$B$ de même type obtenue à partir d'opérations
élémentaires sur les lignes.
\par
Plus précisément ces
trois conditions définissent les matrices écholonnées :
\begin{itemize}
\item
Les lignes de coefficients tous nuls sont en dessous
des lignes non nulles ;
\item
le coefficient non nul le plus à gauche d'une ligne est strictement à droite
du coefficient non nul le plus à gauche de la ligne précédente ;
\item
et, pour chaque ligne le coefficient non nul le plus à gauche est $1$.
\end{itemize}
\par
Ces matrices sont des exemples de matrices échelonnées.
\begin{displaymath}
\begin{pmatrix} 1 & 2 \\ 0 & 1 \end{pmatrix}
\qquad \begin{pmatrix} 0 & 1 \\ 0 & 0 \end{pmatrix}
\qquad \begin{pmatrix} 1 & 2 \\ 0 & 0 \end{pmatrix}
\qquad
\begin{pmatrix}
0 & \underline 1 & 2 & 1 & 0 & 1 \\
0 & 0 & \underline 1 & 0 & 0 & 1 \\
0 & 0 & 0 & 0 & \underline 1 & 3 \\
0 & 0 & 0 & 0 & 0 & 0
\end{pmatrix}
\end{displaymath}
\par
La première colonne d'une matrice échelonnée est donc le vecteur nul
ou le premier vecteur de la base canonique de $\mathbb K^m$.
Une matrice triangulaire supérieure dont les termes diagonaux
sont unitaires est une matrice échelonnée. La matrice nulle est aussi une
matrice échelonnée.
\par
La commande \verb!rowEchelon A! d'\axiom transforme la matrice initiale
$A$ en une matrice échelonnée $B$ par
des opérations élémentaires sur les lignes de $A$ :
\begin{itemize}
\item
échange de deux lignes, ou
\item
ajout d'une combinaison linéaire des autres lignes à une ligne donnée.
\end{itemize}
Ces opérations sur les lignes de $A$
placent les termes nécessairement
nuls de la matrice $B$, et multiplient éventuellement une ligne dont le
premier terme non nul est $b \neq 0$ par
par $1/b$ de façon à obtenir un coefficient unitaire.
Toute matrice de ${\cal M}_{m,n}(\mathbb K)$ peut être réduite en une matrice
échelonnée et appliquant la méthode classique d'élimination des variables
par le pivot de Gauss, quitte a permuter deux lignes.
\par
Ensuite \axiom poursuit le processus pour placer
des coefficients nuls au dessus des principaux coefficients unitaires.
Dans cet exemple les coefficients sont de type
\verb!Fraction Integer! pour que le corps soit ${\mathbb K} = {\mathbb Q}$ :
\begin{verbatim}
MFI := Matrix Fraction Integer
A1 : MFI := matrix [[2,3,3],[3,4,5],[4,5,6]]
A2 : MFI := matrix [[2,3,4],[3,4,5],[4,5,6]]
[rowEchelon A1, rowEchelon A2]
\end{verbatim}
\begin{verbatim}
     +1  0  0+   +1  0  - 1+
   [ |0  1  0| , |0  1   2 | ]
     +0  0  1+   +0  0   0 +  Type: List Matrix Fraction Integer
\end{verbatim}
\par
La transformation d'\axiom est donc plus complète que la simple définition
des matrices échelonnées puisque les colonnes principales correspondent
aux vecteurs de la base canonique. \Axiom transforme la
matrice échelonnée précédente en une autre matrice échelonnée :
\begin{verbatim}
A3 : MFI := matrix
       [[0,1,2,1,0,1],[0,0,1,0,0,1],[0,0,0,0,1,3],[0,0,0,0,0,0]]
[A3, rowEchelon A3]
\end{verbatim}
\begin{verbatim}
         +0  1  2  1  0  1+   +0  1  0  1  0  - 1+
       [ |0  0  1  0  0  1| , |0  0  1  0  0   1 | ]
         |0  0  0  0  1  3|   |0  0  0  0  1   3 |
         +0  0  0  0  0  0+   +0  0  0  0  0   0 +
\end{verbatim}
\par
Réduire une matrice $A$
consiste donc à multiplier la matrice par une matrice
$P \in \mathcal{GL}_m(\mathbb K)$ inversible décrivant ces opérations sur
les lignes ; la matrice réduite est $B=PA$.
En particulier les matrices $A$ et $B$ sont de même rang, et les
noyaux des applications linéaires associées aux matrices $A$ et $PA$
sont égaux.
\par
Le système \axiom
applique algébriquement cette méthode sans comparer l'ordre
de grandeur des coefficients au contraire des méthodes numériques qui
privilégient les plus grands termes en valeur absolue pour
améliorer le conditionnemeent du système et diminuer l'influence des
erreurs d'arrondis.
\par
Les divisions intervenant lorsque les coefficients sont dans un corps
sont remplacées par la recherche des facteurs communs dans les anneaux
principaux.
%%
%%
\subsection{Noyau d'une application linéaire et rang}
L'algèbre linéaire identifie généralement l'application linéaire
$f : \mathbb K^n \mapsto \mathbb K^m$ et la matrice
$A \in {\cal M}_{m,n}(\mathbb K)$ par
$f(X)=AX$.
\par
Un vecteur $X \in \ker f$ du noyau de $f$ est caractérisé par
$f(X)=\mathbf 0$. Les opérations sur les lignes de $A$ appliquées
par \verb!rowEchelon! laissent invariant les vecteurs du noyau,
d'où l'abus de notation $\ker f =\ker A = \ker B$ :

\begin{displaymath}
P \in {\cal GL}_m({\mathbb K})
\qquad X \in \ker f
\Longleftrightarrow AX={\mathbf 0}
\Longleftrightarrow PAX={\mathbf 0}
\end{displaymath}
\par
La construction d'une base du noyau revient à rechercher
des relations de dépendance linéaire
sur les vecteurs-colonne de la matrice échelonnée. La structure même
de la matrice échelonnée calculée par \axiom énumère une base du noyau
à partir des coefficients des vecteurs-colonne
qui n'introduisent pas un coefficient unitaire
sur une ligne ou une autre.
\par
La commande \verb!nullSpace A! détermine de cette manière
une base du noyau de l'application
linéaire $f:X \mapsto AX$ définie par la matrice $A$.
Cependant, lorsque le noyau est le sous-espace nul, \axiom renvoie la liste
constituée du vecteur nul et non la liste vide qui correspond à la base du
sous-espace nul :
\begin{verbatim}
rowEchelon A2
nullSpace rowEchelon A2
nullSpace A2
\end{verbatim}
\begin{verbatim}
        +1  0  - 1+
        |0  1   2 |
        +0  0   0 +                Type: Matrix Fraction Integer
        [[1,- 2,1]]           Type: List Vector Fraction Integer
        [[1,- 2,1]]           Type: List Vector Fraction Integer
\end{verbatim}
\par
Une base de ce noyau est réduite à un seul vecteur.
La colonne $C_3$ de matrice échelonnée $B_2$ associée à la matrice $A_2$
est effectivement un vecteur du noyau, d'où ces
produits matriciels qu'\axiom vérifie par
\verb!A2*vector[1,-2,1]! :
\begin{displaymath}
B_2 = [C_1,C_2,C_3] =
\begin{pmatrix} 1 & 0 & -1 \\ 0 & 1 & 2 \\ 0 & 0 & 0 \end{pmatrix}
\qquad C_3=-C_1+2C_2 \qquad C_1-2C_2+C_3=\mathbf 0
\end{displaymath}
\begin{displaymath}
 \begin{pmatrix} 1 & 0 & -1 \\ 0 & 1 & 2 \\ 0 & 0 & 0 \end{pmatrix}
 \begin{pmatrix} 1 \\-2 \\ 1 \end{pmatrix}
= \begin{pmatrix} 0 \\ 0 \\ 0 \end{pmatrix}
\qquad
 \begin{pmatrix} 2 & 3 & 4 \\ 3 & 4 & 5 \\ 4 & 5 & 6 \end{pmatrix}
 \begin{pmatrix} 1 \\-2 \\ 1 \end{pmatrix}
= \begin{pmatrix} 0 \\ 0 \\ 0 \end{pmatrix}
\end{displaymath}
\par
Les résultats sont comparables avec la matrice $A_3$ ; les colonnes
d'indice un, quatre et six décrivent ainsi une base du noyau :
\begin{verbatim}
rowEchelon A3
nullSpace A3
\end{verbatim}
\begin{verbatim}
        +0  1  0  1  0  - 1+
        |0  0  1  0  0   1 |
        |0  0  0  0  1   3 |
        +0  0  0  0  0   0 +       Type: Matrix Fraction Integer
        [[1,0,0,0,0,0],[0,- 1,0,1,0,0],[0,1,- 1,0,- 3,1]]
\end{verbatim}
\par
Les vecteurs obtenus sont bien des vecteurs du noyau ; la méthode
est similaire pour montrer que ces vecteurs engendrent le noyau
et forment une famille libre. Ils constituent ainsi une base du noyau.
\par
La commande \verb!rank A! calcule le rang d'une matrice $A$ en
dénombrant les lignes non nulles de la matrice échelonnée associée à $A$.
La commande \verb!nullity A! renvoie la dimension du noyau $\dim \ker A$
de l'application linéaire $f$ associée à la matrice en appliquant le théorème
du rang à $f$ :
\begin{verbatim}
[rank A1, rank A2, rank A3]
[nullity A1, nullity A2, nullity A3]
\end{verbatim}
\begin{verbatim}
        [3,2,3]                       Type: List PositiveInteger
        [0,1,3]                       Type: List PositiveInteger
\end{verbatim}
%%
%%
\subsection{Résolution d'un système linéaire}
Les commandes \verb!particularSolution(A,b)! et \verb!solve(A,b)! résolvent
l'équa\-tion matricielle $AX=b$ d'inconnue $X \in {\mathbb K}^n$
où $A \in {\cal M}_{m,n} ({\mathbb K})$
et $b \in {\mathbb K}^m$.
\par
L'ensemble des solutions d'une telle équation est soit l'ensemble vide,
soit un sous-espace affine de la forme $U + \ker A$ où $U \in {\mathbb K}^m$
est une solution particulière.
\par
Le résultat de \verb!particularSolution(A,b)! et de \verb!solve(A,b)!
est \verb!"failed"! si le système l'a pas de solution.
La première commande renvoie sinon une solution, et la seconde
décrit l'ensemble des solutions sous la forme d'un
enregistrement dont le premier terme est une solution particulière, et le
second une base du noyau.
\par
La méthode de résolution consiste à concaténer le vecteur $b$ à
droite de la matrice $A$ du système, puis à étudier la matrice
échelonnée associée.
Le système n'a pas de solution si cette dernière colonne n'est pas une
combinaison linéaire des précédentes, et a au moins une solution sinon.
Ce critère se lit directement sur la matrice échelonnée :
\begin{displaymath}
\begin{cases} x + 2y = 5 \\2x+y=4 \\ {\phantom 2}x+y=3\end{cases}
\qquad
\begin{cases} x + 2y = 5 \\2x+y=5 \\ {\phantom 2}x+y=3\end{cases}
\end{displaymath}
La matrice~$A$ de cet exemple décrit le système précédent de trois équations
à deux inconnues :
\begin{verbatim}
A : MFI := matrix [[1,2],[2,1],[1,1]]
b1 : Vector Fraction Integer := vector [5,4,3]
b2 : Vector Fraction Integer := vector [5,4,4]
[rowEchelon horizConcat (A, b1), rowEchelon horizConcat (A, b2)]
particularSolution (A, b1)
particularSolution (A, b2)
\end{verbatim}
\begin{verbatim}
         +1  0  1+   +1  0  0+
       [ |0  1  2| , |0  1  0| ]
         +0  0  0+   +0  0  1+
       [1,2]       Type: Union(Vector Fraction Integer,"failed")
       "failed"    Type: Union(Vector Fraction Integer,"failed")
\end{verbatim}
La dernière colonne de la première matrice échelonnée
détermine le couple-solution $(x,y)=(1,2)$,
et celle de la seconde matrice justifie l'absence de solution du système.
%%
%%
%%
%%
\section{Recherche de bases}
\subsection{Base d'un sous-espace}
La fonction \verb!basis! ci-dessous extrait une base du sous-espace
vectoriel $F$ engendré par les colonnes d'une matrice $A$.
Les colonnes de $A$ génératrices de $F$ sont les mêmes que
les colonnes génératrices de la matrice échelonnée
\verb!rowEchelon A!.
Ces vecteurs sont ceux ayant un indice
$1$ sur une nouvelle ligne dans la matrice échelonnée.
\begin{verbatim}
basis mat ==
 mat2 := rowEchelon mat
 basis := []
 indrow : Integer := 1
 n : Integer := ncols mat
 m : Integer := nrows mat
 for k in 1..n repeat
   if indrow <= m and mat2.(indrow,k) ~= 0
     then
       basis := cons (column (mat, k), basis)
       indrow := indrow + 1
 reverse basis
\end{verbatim}
La dernière commande \verb!reverse! conserve l'ordre des vecteurs
extraits de la famille génératrice pour construire la base.
Les matrices échelonnées de $A_2$ et de $A_3$ précédemment calculées
justifient quels vecteurs interviennent dans les bases associées
à ces sous-espaces :
\begin{verbatim}
rowEchelon A2
basis A2
rowEchelon A3
basis A3
\end{verbatim}
\begin{verbatim}
        [[2,3,4],[3,4,5]]
        [[1,0,0,0],[2,1,0,0],[0,0,1,0]]
\end{verbatim}
La fonction \verb!basisLV! opère sur des listes de vecteurs
et construit la matrice associée quand les vecteurs sont de
même taille, et provoque une erreur sinon.
\begin{verbatim}
sameSizeVectors? Lb ==
 null Lb => true
 n := #(first Lb)
 every? (t +-> #t=n, rest Lb)
\end{verbatim}
\begin{verbatim}
basisLV Lv ==
 null Lv => []
 not (sameSizeVectors? Lv)
   => error "vectors have not the same size"
 basis transpose matrix Lv
\end{verbatim}
%%
%%
\subsection{Base d'une somme de sous-espaces}
Une base d'une somme de sous-espaces peut être extraite
à partir de la réunion des familles génératrices des sous-espaces.
\begin{verbatim}
sumBasis2 (Lv1, Lv2) == basisLV concat (Lv1, Lv2)
sumBasisLLV LLv == basisLV concat LLv
\end{verbatim}
La fonction \verb!sumBasis2! extrait une base de la réunion de deux
familles géné\-ra\-trices de vecteurs.
La fonction \verb!sumBasisLLV! extrait une base d'une somme de sous-espaces
dont les familles génératrices de vecteurs sont énumérées dans
la liste argument.
%%
%%
\subsection{Base d'une intersection de sous-espaces}
\begin{verbatim}
kernelMat mat ==
 lv := nullSpace mat
 #lv = 1 and lv.1 = 0*lv.1 => []
 lv
\end{verbatim}
La fonction \verb!kernelMat! reprend la fonction \verb!nullSpace!
mais renvoie dans tous les cas une base du noyau, et, au contraire de
\verb!nullSpace!, la liste vide lorsque le noyau est le sous-espace nul.
\par
La fonction \verb!subvector! extrait un sous-vecteur d'un vecteur et
\verb!linearVector! évalue une combinaison linéaire de vecteurs en
fonction de ses coefficients, à la façon d'un produit matriciel.
Ces fonctions interviennent ensuite dans la recherche d'une base
d'une intersection de sous-espaces vectoriels :
\begin{verbatim}
subVector (v, a, b) == vector (elt (entries v, a..b))
linearVector (t, Lv) == reduce (+, [t.i*Lv.i for i in 1..#t])
\end{verbatim}
La fonction suivante \verb!intBasis2! construit une base de l'intersection
de deux sous-espaces vectoriels à partir de leurs bases affectées
dans les variables \verb!Lb1! et \verb!Lb2!.
\par
Dans le cas où ni l'un ni l'autre des sous-espaces n'est
réduit au vecteur nul, les vecteurs de l'intersection sont construits
à partir de relations de dépendance linéaire de vecteurs des bases des
deux sous-espaces. Décomposer cette somme sur chaque sous-espace aboutit
donc à un vecteur de l'intersection.
\par
Les coefficients de cette dépendance linéaire sont
obtenus à partir des vecteurs d'une base du noyau de la matrice
dont les colonnes sont les vecteurs des bases de ces deux sous-espaces.
\begin{verbatim}
intBasis2 (Lv1, Lv2) ==
 Lb1 := basisLV Lv1
 Lb2 := basisLV Lv2
 null Lb1 => []
 null Lb2 => []
 #(first Lb1) ~= #(first Lb2)
   => error "vectors have not the same size"
 lkv := kernelMat transpose matrix concat (Lb2, Lb1)
 d1 := #Lb1
 d2 := #Lb2
 LcoeffV1 := [subVector (kv, d2+1, d1+d2) for kv in lkv]
 [linearVector (cc, Lb1) for cc in LcoeffV1]
\end{verbatim}
L'exemple suivant détaille la recherche d'une base de l'intersection
de deux plans de l'espace :
\begin{verbatim}
B1:List Vector Fraction Integer := [vector[1,2,2], vector[1,1,2]]
B2:List Vector Fraction Integer := [vector[-1,0,1],vector[1,1,1]]
intBasis2 (B1, B2)
\end{verbatim}
\begin{verbatim}
         [[2,3,4]]            Type: List Vector Fraction Integer
\end{verbatim}
L'intersection des deux plans est bien une droite vectorielle.
La matrice intermédiaire et son noyau sont ceux-ci :
\begin{verbatim}
M := transpose (matrix concat (B1, B2))::MFI
nullSpace M
\end{verbatim}
\begin{verbatim}
         +1  1  - 1  1+
         |2  1   0   1|
         +2  2   1   1+            Type: Matrix Fraction Integer
             1   1 1
         [[- -,- -,-,1]]
             3   3 3          Type: List Vector Fraction Integer
\end{verbatim}
Le noyau ne comporte qu'un vecteur d'où ces égalités :
\begin{displaymath}
{\mathbf u}_1 \begin{pmatrix} 1 \\ 2 \\ 2 \end{pmatrix}
{\mathbf u}_2 \begin{pmatrix} 1 \\ 1 \\ 2 \end{pmatrix}
{\mathbf v}_1 \begin{pmatrix} -1 \\ 0 \\ 1 \end{pmatrix}
{\mathbf v}_2 \begin{pmatrix} 1 \\ 1 \\ 1 \end{pmatrix}
\quad
- \frac 1 3 {\mathbf u}_1 - \frac 1 3 {\mathbf u}_2 +
\frac 1 3 {\mathbf u}_3 + {\mathbf u}_4 = \mathbf 0
\end{displaymath}
\begin{displaymath}
 \frac 1 3 {\mathbf u}_1 + \frac 1 3 {\mathbf u}_2 =
 \frac 1 3 {\mathbf u}_3 + {\mathbf u}_4
= \begin{pmatrix} 2/3 \\ 1 \\ 4/3 \end{pmatrix}
\end{displaymath}
Ce dernier vecteur est proportionnel à celui déterminé par \axiom.
\par
Cette méthode décrit donc une construction des vecteurs de l'intersection
de deux sous-espaces ;
en outre ces vecteurs forment une famille libre de vecteurs et réciproquement
tous les vecteurs de l'intersection sont une combinaison linéaire de ceux-ci.
\par
Cette dernière fonction \verb!intBasisLLV!
construit une base d'une intersection
d'une famille quelconques de sous-espaces.
\begin{verbatim}
intBasisLLV LLv ==
 #LLv = 0 => error "no space to intersect"
 #LLv = 1 => LLv.1
 intBasis2 (LLv.1, intBasisLLV rest LLv)
\end{verbatim}
\par
L'exemple suivant détermine de deux façons différentes le sous-espace
orthogonal à une famille de quatre vecteurs de ${\mathbb K}^6$.
L'égalité des deux bases résultats est une condition suffisante
d'égalité des deux sous-espaces, de dimension trois dans ce cas :
\begin{verbatim}
U1 : Vector Fraction Integer := [1,2,1,2,3,4]
U2 : Vector Fraction Integer := [1,-1,1,1,1,0]
U3 : Vector Fraction Integer := [0,1,0,2,1,1]
U4 := U3 - 2*U1
nullSpace matrix [U1,U2,U3,U4]
LV := [U1, U2, U3, U4]
intBasisLLV [nullSpace matrix [U] for U in LV]
\end{verbatim}
\begin{verbatim}
                             7   3     1         8   7   1
         [[- 1,0,1,0,0,0],[- -,- -,0,- -,1,0],[- -,- -,0,-,0,1]]
                             5   5     5         5   5   5
\end{verbatim}
%%
%%
\end{document}
\nwfilename{SandBoxComplementsdalgebrelineaire.pamphlet}
