gauss.pdf

December 30, 2017 | Author: Yassine Sadoudi | Category: Matrix (Mathematics), Functions And Mappings, Mathematical Concepts, Mathematical Objects, Linear Algebra
Share Embed Donate


Short Description

Download gauss.pdf...

Description

Gaudino, casier 5

Lycée Masséna

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 résolution des systèmes linéaires. Nous nous contenterons cette année de regarder un système linéaire de Cramer, pour lequel le pivot de Gauss peut être fait dans l’ordre 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 n’utiliserons pas vraiment la permutation (sauf à la fin). Nous savons que, comme le système est de Cramer, appliquer le pivot à la matrice augmentée du second membre donnera l’unique solution sur la dernière 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 liées 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 représente la matrice A = . Attention au piège : les listes sont numérotées à partir de 0, pas à partir de 1 ! ! ! 3 4 On rappelle aussi qu’une variable de type liste est un pointeur : une fonction peut la modifier, une copie se fait avec la commande deepcopy après import de copy. L’affichage par défaut n’est pas très beau. On peut améliorer légèrement cela en copiant : def affichage(A): "Affichage de la matrice" chaine = "" for x in A: chaine = chaine + str(x) + ’\n’ print(chaine) #fin def L’affichage 1 d’une 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 résoudre 2 le système 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 opérations du Pivot

Dans un premier temps, on ne demande pas de gérer le mauvais emploi d’un utilisateur qui donnerait un indice incorrect (par exemple qui demanderait de permuter les lignes 1 et 4 d’une matrice à trois lignes). Si il vous reste du temps à la fin, vous pourrez réfléchir à ce problème (test if, commande assert, . . .). Attention à la numérotation à 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 réservé par Python), et qui rend la matrice dont la ligne i est multipliée par lamda. Cette fonction, comme les deux suivantes, modifiera la matrice. 2. Faire de même 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 élégant de surcharger la fonction print. . . 2. L’unique solution est x = 1, y = 0, z = 1. Voilà, le TP est fini.

1

3. Faire de même pour la transvection (fonction transvect). Les arguments seront une matrice A, deux indices i et j, et un coefficent lamda. L’opération sera : Li ← Li + λLj .

IV.

Le pivot proprement dit

Attention à la numérotation à partir de 0 ! ` l’aide de transvections et de dilatations (on admet que les permutations sont inutiles dans cet exemple), 1. A résoudre ce système. 2. Automatiser cette méthode 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 méthode 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).   x − y − 4z + 13t = 1     x + 3y + z = 1 −x + 2y + 6z − 21t = −1 5. Résoudre le système 3 : , puis le système 4 : 5x + 4y + z = 1  2x − y − 4z + 12t = 2   x + 2y + z = 0  2x − 2z + 5t = 2 On admettra qu’ils sont de Cramer, et que les permutations sont inutiles. On doit comprendre sur ce dernier exemple qu’on ne coupera pas à une étude des erreurs d’arrondi. De plus, si on regarde le détail des calculs, on voit apparaitre les deux zéros (ce qui ne pose pas que le problème de la comparaison à 0) : +0 et −0.

Des erreurs d’arrondis : pivot partiel

V.

Le choix du pivot n’est pas anodin ! Si la matrice est telle qu’un pivot est nul, notre fonction marchera mal. On sait néanmoins que, dans le cas d’un système de Cramer, on peut toujours trouver un pivot non-nul quitte à échanger deux lignes. 1. Une première idée est de tester si le pivot est nul, et au besoin échanger deux lignes pour régler le problème. Pourquoi est-ce une mauvaise idée ? 2. Il faut en fait choisir un autre pivot non-nul. Pour minimiser les erreurs d’arrondi (inhérentes au type float), il faut choisir un pivot maximal en valeur absolue (dans une ligne non encore traitée). On aura besoin de |x|=math.fabs(x) avec le module math chargé. Comprendre l’intérêt de cette idée de pivot maximal. 3. Fabriquer une fonction pivotmax qui prend en arguments une matrice A, et un indice i, et qui retourne l’indice 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 optimisée pour que le choix du pivot vérifie ce critère. On devra utiliser les permutations. 5. Constater l’intérêt de ces modifications sur l’exemple suivant :  + z 0.01x 3x + 4y + z Essayer cela sur le système suivant, en le résolvant d’abord avec gauss2, puis avec gauss3 :  100x + 2y + z On trouve sans la version optimisée [0.9999999999999993, 5e − 16, −0.5], et avec la version optimisée [−0.005076399817249606, −0.2462053911366059, 1.0000507639981724] 100 4850 19700 qui est beaucoup plus proche de la solution exacte x = − ,y = − ,z = 19699 19699 19699 L’erreur ici trouvée est d’un facteur 1000 sur la valeur de x. Notez que l’exemple n’induit qu’un seul choix de pivot qui pose problème. Avec trois choix, les erreurs seraient encore plus multipliées. Vous pouvez le constater en modifiant les valeurs des coefficients (prendre des puissances de 10 pour bien le voir).

VI.

Compléxité de la méthode

´ Evaluer le nombre d’opérations par la méthode du pivot, par la méthode du pivot partiel. 3. d’unique solution  (1, 0, 0, 0).  1 7 4. d’unique solution − , 1, − . 4 4

2

= 1 = 0 = 0

VII.

Code

Un exemple de corrigé (ce n’est pas le meilleur code possible, c’est 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 n’est pas très 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) #Décommenter pour mieux suivre for j in range(0,i,1): transvect(A,j,-A[j][i],i) #affichage(A) #Décommenter pour mieux suivre #fin for for j in range(i+1,p,1): transvect(A,j,-A[j][i],i) #affichage(A) #Décommenter 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)) #Décommenter pour mieux suivre permut( A , i , pivotmax(A,i) ) #affichage(A) #Décommenter pour mieux suivre dilat(A,i,1/A[i][i]) #affichage(A) #Décommenter pour mieux suivre for j in range(0,i,1): transvect(A,j,-A[j][i],i) #affichage(A) #Décommenter pour mieux suivre #fin for for j in range(i+1,p,1): transvect(A,j,-A[j][i],i) #affichage(A) #Décommenter pour mieux suivre #fin for #fin for return [A[i][p] for i in range(0,p,1)] #fin def

4

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF