Vous êtes sur la page 1sur 4

Gaudino, casier 5

Lyce Massna

version 1.0

Pivot de Gauss

P.C.S.I.834

Le but du T.D. est la programmation du pivot de Gauss pour la rsolution des systmes linaires. Nous nous contenterons cette anne de regarder un systme linaire de Cramer, pour lequel le pivot de Gauss peut tre fait dans lordre
usuel suivant (exemple pour une 3 3) :

1 dilatation
5 transvection 8 transvection
2 transvection 4 dilatation
9 transvection
3 transvection 6 transvection 7 dilatation
En particulier, nous nutiliserons pas vraiment la permutation (sauf la fin).
Nous savons que, comme le systme est de Cramer, appliquer le pivot la matrice augmente du second membre
donnera lunique solution sur la dernire colonne.
Dans ce TD, :
nous travaillons avec des matrices de flottants ;
nous nous autorisons le transtypage int-float ;
jusqu indication du contraire, nous faisons fi des erreurs lies au type flottant.

Les matrices en Python

I.

Nous allons utiliser le formalisme


suivant : une matrice est la liste des listes de lignes. Par exemple A = [[1,2],[3,4]]


1 2
reprsente la matrice A =
. Attention au pige : les listes sont numrotes partir de 0, pas partir de 1 ! ! !
3 4
On rappelle aussi quune variable de type liste est un pointeur : une fonction peut la modifier, une copie se fait avec
la commande deepcopy aprs import de copy.
Laffichage par dfaut nest pas trs beau. On peut amliorer lgrement cela en copiant :
def affichage(A):
"Affichage de la matrice"
chaine = ""
for x in A:
chaine = chaine + str(x) + \n
print(chaine)
#fin def
Laffichage 1 dune matrice se fait alors avec la commande affichage(A) et non print(A).

II.

Le formalisme matriciel

Nous allons

1
A = 3
1

III.

2
4
0

x + 2y + z = 2
rsoudre 2 le systme 3x + 4y + z = 4 . On fait cela avec le formalisme matriciel augment :

x
+ z = 2

1 2
1 4 soit A = [[1,2,1,2],[3,4,1,4],[1,0,1,2]] .
1 2

Les oprations du Pivot

Dans un premier temps, on ne demande pas de grer le mauvais emploi dun utilisateur qui donnerait un indice
incorrect (par exemple qui demanderait de permuter les lignes 1 et 4 dune matrice trois lignes).
Si il vous reste du temps la fin, vous pourrez rflchir ce problme (test if, commande assert, . . .).
Attention la numrotation partir de 0 !
1. Programmer une fonction dilat qui prend en arguments une matrice A, un indice i et un coefficient lamda (et
pas lambda, qui est rserv par Python), et qui rend la matrice dont la ligne i est multiplie par lamda.
Cette fonction, comme les deux suivantes, modifiera la matrice.
2. Faire de mme pour la permutation (fonction permut ). Les arguments seront une matrice A et deux indices i
et j.
1. Il serait presque aussi simple et tellement plus lgant de surcharger la fonction print. . .
2. Lunique solution est x = 1, y = 0, z = 1. Voil, le TP est fini.

3. Faire de mme pour la transvection (fonction transvect). Les arguments seront une matrice A, deux indices i
et j, et un coefficent lamda. Lopration sera : Li Li + Lj .

IV.

Le pivot proprement dit

Attention la numrotation partir de 0 !


` laide de transvections et de dilatations (on admet que les permutations sont inutiles dans cet exemple),
1. A
rsoudre ce systme.
2. Automatiser cette mthode pour une matrice trois lignes dans la fonction gauss. Le seul argument est la
matrice A.
3. Pour ceux qui sont en avance : adapter gauss pour avoir un bel affichage des solutions.
4. Automatiser cette mthode pour une matrice un nombre quelconque de lignes dans la fonction gauss2. Le seul

argument est la matrice A. Evidemment,


on cherchera taper le moins de code possible (= faire des boucles).

4z + 13t = 1

x + 3y + z = 1
x
+
2y
+
6z

21t
=
1
5. Rsoudre le systme 3 :
, puis le systme 4 : 5x + 4y + z = 1
2x y 4z + 12t = 2

x + 2y + z = 0

2x
2z + 5t = 2
On admettra quils sont de Cramer, et que les permutations sont inutiles.
On doit comprendre sur ce dernier exemple quon ne coupera pas une tude des erreurs darrondi. De plus,
si on regarde le dtail des calculs, on voit apparaitre les deux zros (ce qui ne pose pas que le problme de la
comparaison 0) : +0 et 0.

Des erreurs darrondis : pivot partiel

V.

Le choix du pivot nest pas anodin ! Si la matrice est telle quun pivot est nul, notre fonction marchera mal. On sait
nanmoins que, dans le cas dun systme de Cramer, on peut toujours trouver un pivot non-nul quitte changer deux
lignes.
1. Une premire ide est de tester si le pivot est nul, et au besoin changer deux lignes pour rgler le problme.
Pourquoi est-ce une mauvaise ide ?
2. Il faut en fait choisir un autre pivot non-nul.
Pour minimiser les erreurs darrondi (inhrentes au type float), il faut choisir un pivot maximal en valeur absolue
(dans une ligne non encore traite). On aura besoin de |x|=math.fabs(x) avec le module math charg.
Comprendre lintrt de cette ide de pivot maximal.
3. Fabriquer une fonction pivotmax qui prend en arguments une matrice A, et un indice i, et qui retourne lindice
de ligne (pas la valeur) du pivot maximal (en valeur absolue) de la colonne i sur les lignes i et suivantes.
4. Modifier la fonction gauss2 en une fonction gauss3 optimise pour que le choix du pivot vrifie ce critre. On
devra utiliser les permutations.
5. Constater lintrt de ces modifications sur lexemple suivant :

+ z
0.01x
3x
+ 4y + z
Essayer cela sur le systme suivant, en le rsolvant dabord avec gauss2, puis avec gauss3 :

100x + 2y + z
On trouve sans la version optimise [0.9999999999999993, 5e 16, 0.5],
et avec la version optimise [0.005076399817249606, 0.2462053911366059, 1.0000507639981724]
100
4850
19700
qui est beaucoup plus proche de la solution exacte x =
,y =
,z =
19699
19699
19699
Lerreur ici trouve est dun facteur 1000 sur la valeur de x. Notez que lexemple ninduit quun seul choix de
pivot qui pose problme. Avec trois choix, les erreurs seraient encore plus multiplies. Vous pouvez le constater
en modifiant les valeurs des coefficients (prendre des puissances de 10 pour bien le voir).

VI.

Complxit de la mthode

Evaluer
le nombre doprations par la mthode du pivot, par la mthode du pivot partiel.
3. dunique solution 
(1, 0, 0, 0). 
1
7
4. dunique solution , 1,
.
4
4

= 1
= 0
= 0

VII.

Code

Un exemple de corrig (ce nest pas le meilleur code possible, cest seulement un code possible).

import math
def affichage(A):
"Affichage de la matrice"
chaine = ""
for x in A:
chaine = chaine + str(x) + \n
print(chaine)
def dilat(A,i,lamba):
for j in range(0,len(A[i]),1):
A[i][j] = lamba * A[i][j]
def permut(A,i,j):
for k in range(0,len(A[i]),1):
memoire = A[i][k]
A[i][k] = A[j][k]
A[j][k] = memoire
def transvect(A,i,lamba,j):
for k in range(0,len(A[i]),1):
A[i][k] = A[i][k] + lamba * A[j][k]
def gauss(A):
dilat(A,0,1/A[0][0])
transvect(A,1,-A[1][0],0)
transvect(A,2,-A[2][0],0)
dilat(A,1,1/A[1][1])
transvect(A,0,-A[0][1],1)
transvect(A,2,-A[2][1],1)
dilat(A,2,1/A[2][2])
transvect(A,0,-A[0][2],2)
transvect(A,1,-A[1][2],2)
print([A[i][3] for i in range(0,3,1)])
#ce print nest pas trs malin !
#fin def
def gauss2(A):
p = len(A) #nombre de lignes
for i in range(0,p,1):
dilat(A,i,1/A[i][i])
#affichage(A) #Dcommenter pour mieux suivre
for j in range(0,i,1):
transvect(A,j,-A[j][i],i)
#affichage(A) #Dcommenter pour mieux suivre
#fin for
for j in range(i+1,p,1):
transvect(A,j,-A[j][i],i)
#affichage(A) #Dcommenter pour mieux suivre
#fin for
#fin for
return [A[i][p] for i in range(0,p,1)]
#fin def
3

def pivotmax(A,i):
p = len(A) #nombre de lignes
M = math.fabs(A[i][i])
position = i
for j in range(i+1,p,1):
if math.fabs(A[j][i]) > M:
M = math.fabs(A[j][i])
position = j
#fin si
#fin for
return position
#end def
def gauss3(A):
p = len(A) #nombre de lignes
for i in range(0,p,1):
#print(pivotmax(A,i)) #Dcommenter pour mieux suivre
permut( A , i , pivotmax(A,i) )
#affichage(A) #Dcommenter pour mieux suivre
dilat(A,i,1/A[i][i])
#affichage(A) #Dcommenter pour mieux suivre
for j in range(0,i,1):
transvect(A,j,-A[j][i],i)
#affichage(A) #Dcommenter pour mieux suivre
#fin for
for j in range(i+1,p,1):
transvect(A,j,-A[j][i],i)
#affichage(A) #Dcommenter pour mieux suivre
#fin for
#fin for
return [A[i][p] for i in range(0,p,1)]
#fin def