Pivot de Gauss

On se restreint ici à la résolution de systèmes d’équations où le nombre d’inconnues
est ≤ au nombre d’équations.

On transforme la matrice augmentée du système en matrice échelonnée grâce à la méthode du pivot de Gauss, puis on substitue successivement de bas en haut pour obtenir la solution.

Algo de base

Déroulons sur un exemple l’implémentation du TP de l’algorithme de Gauss en utilisant la recherche naïve du pivot (pivot toujours à la ligne suivante).

Avec pivot partiel

Déroulons maintenant l’algo
en utilisant la méthode du pivot partiel
(la ligne du pivot est choisie pour que le pivot ait
la plus grande valeur absolue possible).

def Gauss(M,recherchePivot) :
    tol = 1e-9
    while h < m and k < n :                       
        ipivot = recherchePivot(M,h,k)            
        pivot = M[ipivot][k]
        if abs(pivot) < tol :                     
            k += 1
        else :       
            h +=1
def Gauss(M,recherchePivot) :
    while h < m and k < n :                       
        ipivot = recherchePivot(M,h,k)            
        pivot = M[ipivot][k]
        if abs(pivot) == 0 :                     
            k += 1
        else :       
            h +=1

Pourquoi ne pas avoir écrit ça à la place ?

>>> 0.1**2-0.01 == 0
False

Cette partie du code prouve que cette implémentation de l’algorithme est en fait seulement adaptée au pivot partiel.


Trouvez une situation simple (matrice $2\times 3$)
où l’algo n’aboutit pas à une matrice échelonnée
en ligne prouvant qu’il n’est pas correct
(correction partielle).

Intérêt du pivot partiel

Cherchons à résoudre le système suivant
en supposant que l’on soit limité
à 3 chiffres significatifs

$$ \begin{cases} 10^{-4}x &+ &y&=&1 \\ \hphantom{10^{-4}}x &+ &y &=&2 \\ \end{cases} $$

Sans pivot partiel

$$ \begin{cases} 10^{-4}x &+ &y&=&1 \\ \hphantom{10^{-4}}x &+ &y &=&2 \\ \end{cases} $$

$$ \begin{pmatrix} 10^{-4} & 1 & 1 \\ 1 & 1 & 2 \end{pmatrix} $$

$$ \begin{pmatrix} \color{red}{10^{-4}} & 1 & 1 \\ 1 & 1 & 2 \end{pmatrix} $$

$$ \begin{pmatrix} \color{red}{1} & 10^4 & 10^4 \\ 1 & 1 & 2 \end{pmatrix} $$

$$ \begin{pmatrix} \color{red}{1} & 10^4 & 10^4 \\ 1-1 & 1-10^4 & 2-10^4 \end{pmatrix} $$

$$ \begin{pmatrix} \color{red}{1} & 10^4 & 10^4 \\ 0 & -10^4 & -10^4 \end{pmatrix} $$

$$ \begin{pmatrix} 1 & 10^4 & 10^4 \\ 0 & \color{red}{-10^4} & -10^4 \end{pmatrix} $$

$$ \begin{pmatrix} 1 & 10^4 & 10^4 \\ 0 & \color{red}{1} & 1 \end{pmatrix} $$

$$ \begin{cases} 1 &x &+ &10^4&y&=&10^4 \\ &&&1&y &=&1 \\ \end{cases} $$

$$ \begin{cases} &x &= &0 \\ &y &= &1 \\ \end{cases} $$

Avec pivot partiel

$$ \begin{cases} 10^{-4}x &+ &y&=&1 \\ \hphantom{10^{-4}}x &+ &y &=&2 \\ \end{cases} $$

$$ \begin{pmatrix} 10^{-4} & 1 & 1 \\ 1 & 1 & 2 \end{pmatrix} $$

$$ \begin{pmatrix} 10^{-4} & 1 & 1 \\ \color{red}{1} & 1 & 2 \end{pmatrix} $$

$$ \begin{pmatrix} \color{red}{1} & 1 & 2 \\ 10^{-4} & 1 & 1 \end{pmatrix} $$

$$ \begin{pmatrix} \color{red}{1} & 1 & 2 \\ 10^{-4}-1\times 10^{-4} & 1-1\times 10^{-4} & 1-2\times 10^{-4} \end{pmatrix} $$

$$ \begin{pmatrix} \color{red}{1} & 1 & 2 \\ 0 & 1 & 1 \end{pmatrix} $$

$$ \begin{cases} 1 &x &+ &1&y&=&2 \\ &&&1&y &=&1 \\ \end{cases} $$

$$ \begin{cases} &x &= &1 \\ &y &= &1 \\ \end{cases} $$

WolframAlpha

En cliquant sur step-by-step solution,
que peut-on dire de la méthode utilisée ?

Un peu de théorie

On cherche à résoudre :

$$A\textbf{x}=\color{green}{\textbf{b}}$$

On passe à la matrice augmentée :

$$ \tilde{A}=\begin{bmatrix}A|\textbf{b}\end{bmatrix}=\begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} &|& \color{green}b_1 \\ a_{21} & a_{22} & \cdots & a_{2n} &|& \color{green}b_2 \\ \vdots & & & \vdots &|& \color{green}\vdots \\ a_{n1} & a_{n2} & \cdots & a_{nn} &|& \color{green}b_n \end{bmatrix} $$

On utilise “Gaussian elimination"
pour transformer $\tilde{A}$ en matrice échelonnée.

def Gauss(M,recherchePivot) :
    m = len(M)                                    
    n = len(M[0])                                 
    h = k = 0
    tol = 1e-9                        
    while h < m and k < n :                       
        ipivot = recherchePivot(M,h,k)            
        pivot = M[ipivot][k]
        if abs(pivot) < tol :                     
            k += 1
        else :
            if h != ipivot :
                M[h],M[ipivot] = M[ipivot],M[h]   
            for j in range(k,n) :
                M[h][j] /= pivot                  
            for i in range(h+1,m) :
                f = M[i][k]
                for j in range(k,n) :
                    M[i][j] -= M[h][j] * f
            h +=1
            k += 1

$$ \tilde{A}\rightarrow\begin{bmatrix} \color{red}{\rule{0.5em}{0.5em}}& * & * & * & * & * & \color{green}* \\ \color{blue}0&\color{blue}0&\color{red}\rule{0.5em}{0.5em} & * & * & * & \color{green}* \\ \color{blue}0&\color{blue}0&\color{blue}0&\color{red}\rule{0.5em}{0.5em}& * & * & \color{green}* \\ \color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0& \color{red}\rule{0.5em}{0.5em}& * & \color{green}* \\ \color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{red}\rule{0.5em}{0.5em}& \color{green}* \\ \color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0& \color{green}0 \\ \end{bmatrix} $$

Puis on utilise “back substitution"
pour obtenir la solution $\textbf{x}$.

Que vaut $x_2$ dans l’exemple précédent ?

Quel objet géométrique $\textbf{x}$ représente-t-il ?

Que vaut le rang de la matrice ?

Solution générale pour calculer
le rang d’une matrice ?

Pour réduire $\tilde{A}$,
on utilise “Gauss-Jordan elimination

On obtient alors :

$$ \tilde{A}\rightarrow\begin{bmatrix} \color{red}{\boxed{1}}& * & \color{blue}0 & \color{blue}0 & \color{blue}0 & \color{blue}0 & \color{green}* \\ \color{blue}0&\color{blue}0&\color{red}{\boxed{1}} & \color{blue}0 & \color{blue}0 & \color{blue}0 & \color{green}* \\ \color{blue}0&\color{blue}0&\color{blue}0&\color{red}{\boxed{1}}& \color{blue}0 & \color{blue}0 & \color{green}* \\ \color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0& \color{red}{\boxed{1}}& \color{blue}0 & \color{green}* \\ \color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{red}{\boxed{1}}& \color{green}* \\ \color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0& \color{green}0 \\ \end{bmatrix} $$

Seule une toute petite modification est nécessaire pour passer de Gauss à Gauss-Jordan :

def Gauss(M,recherchePivot) :
    m = len(M)                                    
    n = len(M[0])                                 
    h = k = 0
    tol = 1e-9                        
    while h < m and k < n :                       
        ipivot = recherchePivot(M,h,k)            
        pivot = M[ipivot][k]
        if abs(pivot) < tol :                     
            k += 1
        else :
            if h != ipivot :
                M[h],M[ipivot] = M[ipivot],M[h]   
            for j in range(k,n) :
                M[h][j] /= pivot                  
            for i in range(h+1,m) :
                f = M[i][k]
                for j in range(k,n) :
                    M[i][j] -= M[h][j] * f
            h +=1
            k += 1
def GaussJordan(M,recherchePivot) :
    m = len(M)                                    
    n = len(M[0])                                 
    h = k = 0
    tol = 1e-9                        
    while h < m and k < n :                       
        ipivot = recherchePivot(M,h,k)            
        pivot = M[ipivot][k]
        if abs(pivot) < tol :                    
            k += 1
        else :
            if h != ipivot :
                M[h],M[ipivot] = M[ipivot],M[h]   
            for j in range(k,n) :
                M[h][j] /= pivot                  
            for i in range(m) :
                if i != h :
                    f = M[i][k]
                    for j in range(k,n) :
                        M[i][j] -= M[h][j] * f      
            h +=1
            k += 1

En terme de calculs, Gauss-Jordan revient à ça :

Gauss-Jordan ajoute la phase retour à Gauss.
C’est elle qu’on doit comparer à back substitution.

Qui est le plus rapide pour résoudre un système ?


  • Gaussian elimination + back substitution

  • Gauss-Jordan elimination
from random import randint
n = 10
A = [[randint(-20,20) for j in range(n+1)] for i in range(n)]
%%timeit
Gauss(A,recherchePivotPartiel)
V = substitution(A)

115 µs ± 755 ns per loop
(mean ± std. dev. of 7 runs,
10000 loops each)

%%timeit
GaussJordan(A,recherchePivotPartiel)
Vp = [A[i][n] for i in range(n)]

155 µs ± 1.07 µs ns per loop
(mean ± std. dev. of 7 runs,
10000 loops each)

Pour finir, le one-liner permettant d’obtenir la rref (row-reduced echelon form) :

import sympy as sym
sym.Matrix(A).rref()
A = [[4,4,0,3,1,9,3],
     [8,8,4,2,8,6,4],
     [4,4,1,5,1,4,2],
     [4,4,2,1,4,3,2],
     [4,4,9,8,4,3,2],
     [4,4,0,2,2,6,8]]
     
sym.Matrix(A).rref()
(Matrix([
 [1, 1, 0, 0, 0, 0, -135/2],
 [0, 0, 1, 0, 0, 0,  -83/2],
 [0, 0, 0, 1, 0, 0,   83/2],
 [0, 0, 0, 0, 1, 0,     72],
 [0, 0, 0, 0, 0, 1,   17/2],
 [0, 0, 0, 0, 0, 0,      0]]), (0, 2, 3, 4, 5))

Retour site