PC 2016/2017
Corrigé de la séance Python 3 : algèbre linéaire
On commence par importer le module numpy :
1import numpy as np
1 Systèmes linéaires
1. Pour effectuer la transvection LiLi+cLj, on peut faire une boucle (indexée par k) qui effectue les
opérations A[i,k] = A[i,k] + c*A[j,k] (kvariant de 0àp1, où pest le nombre de colonnes de la
matrice, i.e. la longueur du tableau A[0] par exemple). On peut aussi modifier le tableau A[i] en une
seule étape :
1def tra nsve cLi gne (A ,i ,j , c ):
2""" effe ctue l op é ration L_i <- L_i + c* L_j sur A.
3Modifi e la matrice A et ne renvoie rien """
4A[i] = A[i] + c * A[j]
Pour la permutation, la même syntaxe nécessite d’utiliser des copies des lignes (sinon, on se retrouverait
avec une matrice ayant deux lignes égales). La solution consistant à utiliser une boucle ne nécessite
évidemment pas de copie.
1def p er mu tL ig ne (A , i1 , i2 ):
2""" permut e les lignes d indices i1 et i2 de A. """
3A [ i1 ] , A[ i2 ] = np . c opy ( A [ i2 ]) , np . copy ( A [ i1 ])
La dilatation :
1def d il at Li gn e (A ,i , c ):
2""" eff ect ue l ’op é rat ion L_i <- c * L_i sur A. """
3A[ i] *= c
Le principe est identique pour les colonnes, aux notations près : A[i] désigne la ligne d’indice i, alors
que A[:,j] désigne la colonne d’indice j.
1def t ra nsv ec Col (A ,i ,j , c ):
2""" eff ect ue l ’op é rat ion C_i <- C_i + c * C_j sur A . """
3A [: , i ] += c * A [: , j ]
4
5def p er mu tCo l (A , j1 , j2 ):
6""" permut e les colonn es d in dices j1 et j2 de A. """
7A [: , j1 ] , A [: , j2 ] = np . copy ( A [: , j2 ]) , np . c opy ( A [: , j1 ])
8
9def d il at Co l (A ,j , c ):
10 """ eff ect ue l ’ op é rati on C_i <- c * C_i sur A . """
11 A [: , j ] *= c
2. a) On commence par créer une copie de chacune des matrices Aet B, sur lesquelles on va travailler (en les
modifiant). Notons nle nombre de lignes de A(i.e. sa longueur). On commence par échelonner le système.
Pour cela, on traite d’abord la première colonne (d’indice j= 0), puis la deuxième... et enfin l’avant-
dernière (d’indice n2). Le traitement de la colonne d’indice jconsiste à utiliser le coefficient pivot Aj,j
pour annuler (par des transvections) les coefficients Ai,j pour i>j(chaque manipulation effectuée sur
les lignes de Adoit l’être aussi sur les lignes de B). Il faut donc écrire deux boucles imbriquées l’une dans
l’autre.
Une fois le système échelonné, il faut pratiquer la phase de «remontée» pour annuler les coefficients situés
au-dessus de la diagonale principale (chaque transvection pratiquée sur Adoit encore l’être sur B). Pour
cette phase de remontée, on commence par traiter la dernière colonne, puis l’avant dernière...
Après cette phase de remontée, le système est diagonal, de la forme a1,1x1=b1, . . . , an,nxn=bn. Reste à
faire une dilatation sur chacune des lignes pour obtenir la valeur des xi. Comme la matrice Ane servira
plus, on peut se dispenser de faire les dilatations sur Aet ne les faire que sur le second membre B. Dans
la version que nous proposons, cette dilatation est faite juste après avoir annulé tous les coefficients non
diagonaux d’une colonne donnée.
1
1def s ys tL in (A , B ):
2""" r é sout le syst è me AX = B ( B peut avoir plusieurs col onnes ) par
3pivot de G auss . """
4n = len(A)
5A1 = np . cop y ( A)
6B1 = np . cop y ( B)
7for jin range (n -1):
8for iin range ( j +1 , n ):
9c = A1 [i , j] / A1 [j , j]
10 t ra ns v ec Li g ne ( A1 , i ,j , - c)
11 t ra ns v ec Li g ne ( B1 , i ,j , - c)
12 for jin range (n -1 , -1 , -1):
13 for iin range (j -1 , -1 , -1):
14 c = A1 [i , j] / A1 [j , j]
15 t ra ns v ec Li g ne ( A1 , i ,j , - c)
16 t ra ns v ec Li g ne ( B1 , i ,j , - c)
17 di la tL ig ne ( B1 , j , 1./ A1 [ j ,j ])
18 return( B1 )
Si la matrice Bcomporte pcolonnes, l’inconnue Xdoit aussi en comporter p; la résolution du système
AX1· · · Xp=B1· · · Bpéquivaut à la résolution des psystèmes linéaires AXi=Bi. Lorsque
l’on prend B=In, la solution calculée est la matrice A1.
b) Chaque transvection sur une matrice effectue autant de multiplications que la matrice a de colonnes.
Dans la phase de descente, on effectue donc, pour chaque passage dans la boucle indexée par i, une
division et n+ 1 multiplications. Comme ivarie de j+ 1 àn1,ilya(n1) (j+ 1) + 1 = nj1
passages dans cette boucle. L’indice jvarie de 0àn1, donc il y a
n1
X
j=0
(nj1) =
n1
X
j0=0
j0=n(n1)
2
passages dans les boucles, pour un coût de n(n1)(n+2)
2opérations (multiplications ou divisions). La
phase de remontée comporte autant d’opérations, ainsi que quelques dilatations. Au total, le nombre
d’opérations est équivalent à n3.
En réalité, certaines des multiplications effectuées sont des multiplications pas 0 au cours des transvections
(on pourrait d’ailleurs réécrire la fonction de transvection de façon à n’effectuer que les modifications
utiles). Le nombre d’opérations autres que des opérations du type 0+0·0est en fait équivalent à 2
3n3.
3. a) Pour coder les matrices, il faut que les coefficients soient des flottants (du moins, au moins un : le type
étant homogène, si l’un des coefficient est un flottant et les autres des entiers, ils sont automatiquement
tous convertis en flottants).
1>>> A = np . array ([[1 e -20 ,1] ,[1 ,1]])
2>>> B = np . a rray ([[ 1.] , [2]] )
3>>> sy st Li n (A , B)
array ([[ 0.] ,
[ 1.]])
La résolution fournit x= 0 et y= 1. La véritable solution est en fait donnée par
x=
1 1
2 1
1020 1
1 1
=1
1020 1'1et y=
1020 1
1 2
1020 1
1 1
=2·1020 1
1020 1'1
b) On parcourt les différents coefficients en gardant en mémoire l’indice du plus grand (en valeur absolue)
rencontré depuis le début.
1def pi vot ( A ,j ):
2""" re nv oi e l ’ i nd ic e i du pl us g rand ( en v al eu r a bs ol ue )
3des c oe ff ic ie nt s A [j , j ], ... , A [n -1 , j ] " ""
4n = len(A)
5imax = j
6for iin range ( j +1 , n ):
7if abs ( A[i , j ]) > abs ( A [ imax , j ]):
2
8imax = i
9return( imax )
c) Le principe est le même que pour la fonction précédente, à ceci près que, à chaque fois que l’on va
traiter une colonne, on commence par chercher le plus grand pivot disponible et réaliser la permutation
correspondante (ceci, uniquement dans la phase de triangularisation du système).
1def systLinPivot(A,B):
2""" r é sout le syst è me AX = B ( B peut avoir plusieurs col onnes ) par
3pivot de Gauss en utilisant , dans chaque colonne ,
4le p lus grand pivot poss ibl e . """
5n = len(A)
6A1 = np . cop y ( A)
7B1 = np . cop y ( B)
8for jin range (n -1):
9im ax = pivot (A , j )
10 pe rm ut Li gn e ( A1 ,j , i max )
11 pe rm ut Li gn e ( B1 ,j , i max )
12 for iin range ( j +1 , n ):
13 c = A1 [i , j] / A1 [j , j]
14 t ra ns v ec Li g ne ( A1 , i ,j , - c)
15 t ra ns v ec Li g ne ( B1 , i ,j , - c)
16 for jin range (n -1 , -1 , -1):
17 for iin range (j -1 , -1 , -1):
18 c = A1 [i , j] / A1 [j , j]
19 t ra ns v ec Li g ne ( A1 , i ,j , - c)
20 t ra ns v ec Li g ne ( B1 , i ,j , - c)
21 di la tL ig ne ( B1 , j , 1./ A1 [ j ,j ])
22 return( B1 )
Pour le système linéaire testé plus haut, on obtient cette fois-ci un résultat satisfaisant :
1>>> s ys tL in Pi vo t (A , B)
2array ([[ 1.] ,
3[ 1.]])
4. On cherche encore à transformer la matrice Aen une matrice triangulaire, par la même méthode du pivot.
Cependant, chaque échange d’une ligne avec une autre change le signe du déterminant de la matrice ; il
faut garder trace du nombre de permutations effectuées (une variable signe, valant ±1, conservera cette
information). Si, après l’un des échanges de lignes pour utiliser le plus grand pivot disponible, celui-ci est
nul, c’est que la matrice n’est pas inversible ; son déterminant est nul.
1def d et er mi na nt ( A ):
2n = len(A)
3A1 = np . cop y ( A)
4signe = 1
5for jin range (n -1):
6imax = pivot ( A1 , j)
7if imax > j :
8signe = - s ig ne
9pe rm ut Li gn e ( A1 ,j , i max )
10 if A1 [ j ,j ] == 0:
11 return(0)
12 for iin range ( j +1 , n ):
13 c = A1 [i , j] / A1 [j , j]
14 t ra ns v ec Li g ne ( A1 , i ,j , - c)
15 produi t = signe
16 for jin range ( n ):
17 pro du it *= A1 [j , j]
18 return(produit)
3
2 Décomposition LU
2.1 Principe de la décomposition
1. L’algorithme, pratiqué à la main, fournit le couple
L=
1 0 0
2 1 0
37
21
et U=
1 4 2
02 5
0 0 17
2
pour la matrice A=
1 4 2
2 6 1
3 5 3
.
2.
1def LU ( A ):
2""" renvoi e le couple (L ,U ) de la dé c omp osition A = LU """
3n = len(A)
4L = np . d iag ( [1 .] * n )
5U = np . c opy ( A )
6for jin range (n -1):
7for iin range ( j +1 , n ):
8c = U[i , j ] / U[j , j ]
9t ra ns v ec Li g ne ( U ,i ,j , -c )
10 tr an sv ec Co l ( L ,j , i ,c )
11 return( L ,U )
Testons sur la matrice A(attention à bien la définir à coefficients flottants : sinon, le quotient non entier
7
2sera converti en 3...).
1>>> A = np . array ([[1. ,4 , -2] ,[2 ,6 ,1] ,[3 ,5 ,3]])
2>>> L ,U = LU ( A )
3>>> L ,U
4( array ([[ 1. , 0. , 0. ],
5[ 2. , 1. , 0. ],
6[ 3. , 3.5 , 1. ]]) ,
7array ([[ 1. , 4. , -2. ],
8[ 0. , -2. , 5. ] ,
9[ 0. , 0. , -8.5]]))
On peut vérifier que le produit est bien égal à A:
1>>> np . do t (L , U ) - A
2array ([[ 0. , 0. , 0.] ,
3[ 0. , 0. , 0.] ,
4[ 0. , 0. , 0 .]])
2.2 Algorithme de Thomas
3. Le produit de la kème ligne de Lpar la k+1ème colonne de Ufournit l’égalité βk×0+1×γk+0×αk+1 =ck
(pour k[[0, n 2]]), d’où γk=ck.
4. Les produits matriciels donnent
α0=b0et k[[1, n 1]], αk=bkβkck1, βk=ak
αk1
.
La résolution du système LZ =Ydonne alors
z0=y0et k[[1, n 1]], zk=ykβkzk1.
La résolution du système UX =Zdonne enfin
xn1=zn1
αn1
et k[[0, n 2]], xk=zkckxk+1
αk
.
5. On remarque qu’il n’est pas utile d’avoir deux tableaux xet z: un seul suffit, dans lequel on va d’abord
stocker les coefficients zk, puis les remplacer par les coefficients xk.
4
1def t hom as ( a ,b , c ,y ):
2n = len(a)
3alpha = [0.] * n
4beta = [0.] * n
5x = [0.] * n
6alpha [0] = b [0]
7for iin range (1 , n ):
8beta [i ] = a[i ] / alpha [i -1]
9alpha [ i ] = b[ i] - beta [i ] * c[i -1]
10 x [0] = y [0]
11 for iin range (1 , n ):
12 x[ i] = y [ i] - beta [i ] * x[i -1]
13 x[n -1] = x[n -1] / alpha [n -1]
14 for iin range (n -2 , -1 , -1):
15 x[ i] = ( x [i ] - c[ i ] * x[ i +1]) / alpha [i ]
16 return(x)
2.3 Le cas général : P A =LU
6.
1def PLU ( A ):
2n = len(A)
3P = np . d iag ( [1 .] * n )
4L = np . d iag ( [1 .] * n )
5U = np . c opy ( A )
6for jin range ( n ):
7im ax = pivot (U , j )
8if imax > j :
9pe rm ut Li gn e ( U ,j , im ax )
10 pe rm ut Col (L ,j , i max )
11 pe rm ut Li gn e ( L ,j , im ax )
12 pe rm ut Li gn e ( P ,j , im ax )
13 for iin range ( j +1 , n ):
14 c = U[i , j ] / U[j , j ]
15 t ra ns v ec Li g ne ( U ,i ,j , -c )
16 tr an sv ec Co l ( L ,j , i ,c )
17 return( P ,L , U )
Pour la même matrice Aque plus haut, on trouve
1>>> PLU ( A)
2( a rray ([[ 0. , 0. , 1.] ,
3[ 0. , 1. , 0.] ,
4[ 1. , 0. , 0.] ]) ,
5array ([[ 1. , 0. , 0. ],
6[ 0.66666667 , 1. , 0. ] ,
7[ 0.33333333 , 0.875 , 1. ]]) ,
8array ([[ 3. , 5. , 3. ],
9[ 0. , 2.66666667 , -1. ] ,
10 [ 0. , 0. , -2.125 ]]))
5
1 / 5 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !