# Méthode du gradient conjugué

En analyse numérique, la méthode du gradient conjugué est un algorithme pour résoudre des systèmes d'équations linéaires dont la matrice est symétrique définie positive. Cette méthode, imaginée en 1950 simultanément par Cornelius Lanczos, Eduard Stiefel et Magnus Hestenes, est une méthode itérative qui converge en un nombre fini d'itérations (au plus égal à la dimension du système linéaire). Toutefois, son grand intérêt pratique du point de vue du temps de calcul vient de ce qu’une initialisation astucieuse (dite « préconditionnement ») permet d'aboutir en seulement quelques passages à une estimation très proche de la solution exacte : c'est pourquoi, en pratique, on se borne à un nombre d'itérations bien inférieur au nombre d'inconnues.
La méthode du gradient biconjugué fournit une généralisation pour les matrices non symétriques.

## Principe

L'objectif est de minimiser la fonction $f:x\mapsto {\frac {1}{2}}(\mathbf {A} x,x)-(b,x)$ où A est une matrice carrée symétrique définie positive de taille n.
Le calcul montre qu'une solution du problème est la solution du système $\mathbf {A} x=b$ : en effet, on a $\nabla f\left(x\right)=\mathbf {A} x-b$.
Intuitivement, la fonction f peut donc être vue comme une primitive (littéralement un potentiel scalaire) du résidu $\mathbf {A} x-b$. En annulant le gradient de f, on obtient le vecteur x qui minimise l'erreur.

### La méthode du gradient conjugué vue comme une méthode directe

On rappelle que deux vecteurs non nuls u et v sont conjugués par rapport à A si
    $u^{\mathrm {T} }\mathbf {A} v=0.$
Sachant que A est symétrique définie positive, on en déduit un produit scalaire
    $\langle u,v\rangle _{\mathbf {A} }:=\langle \mathbf {A} {u},{v}\rangle =\langle {u},\mathbf {A} ^{\mathrm {T} }{v}\rangle =\langle {u},\mathbf {A} {v}\rangle ={u}^{\mathrm {T} }\mathbf {A} {v}.$
Ainsi, deux vecteurs sont conjugués s'ils sont orthogonaux pour ce produit scalaire.
La conjugaison est une relation symétrique : si u est conjugué à v pour A, alors v est conjugué à u.
Supposons que {p$_k$} est une suite de n directions conjuguées deux à deux. Alors les {p$_k$} forment une base de R$^n$, ainsi la solution x$_*$ de Ax= b dans cette base :
    $x_{*}=\sum _{i=1}^{n}\alpha _{i}p_{i}$
Les coefficients sont donnés par
    ${b}=\mathbf {A} {x}_{*}=\sum _{i=1}^{n}\alpha _{i}\mathbf {A} {p}_{i}.$
    ${p}_{k}^{\mathrm {T} }{b}={p}_{k}^{\mathrm {T} }\mathbf {A} {x}_{*}=\sum _{i=1}^{n}\alpha _{i}{p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{i}=\alpha _{k}{p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{k}.$ (car $\forall i\neq k,p_{i},p_{k}$ sont conjugués deux à deux)
    $\alpha _{k}={\frac {{p}_{k}^{\mathrm {T} }{b}}{{p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{k}}}={\frac {\langle {p}_{k},{b}\rangle }{\,\,\,\langle {p}_{k},{p}_{k}\rangle _{\mathbf {A} }}}={\frac {\langle {p}_{k},{b}\rangle }{\,\,\,\|{p}_{k}\|_{\mathbf {A} }^{2}}}.$
On a ainsi l'idée directrice de la méthode pour résoudre le système Ax=b : trouver une suite de n directions conjuguées, et calculer les coefficients α$_k$.

### La méthode du gradient conjugué vue comme une méthode itérative

En choisissant correctement les directions conjuguées p$_k$, il n'est pas nécessaire de toutes les déterminer pour obtenir une bonne approximation de la solution x$_*$. Il est ainsi possible de considérer la méthode du gradient conjugué comme une méthode itérative. Ce choix permet ainsi de considérer la résolution de systèmes de très grande taille, où le calcul de l'ensemble des directions aurait été très long.
On considère ainsi un premier vecteur x$_0$, qu'on pourra supposer nul (sinon, il faut considérer le système Az=b − Ax$_0$). L'algorithme va consister, partant de x$_0$, à se « rapprocher » de la solution x$_*$ inconnue, ce qui suppose la définition d'une métrique. Cette métrique vient du fait que la solution x$_*$ est l'unique minimiseur de la forme quadratique :
    $f(\mathbf {x} )={\frac {1}{2}}x^{\mathrm {T} }\mathbf {A} x-x^{\mathrm {T} }b,\quad x\in \mathbb {R} ^{n}.$
Ainsi, si f(x) diminue après une itération, alors on s'approche de x$_*$.
Ceci suggère donc de prendre la première direction p$_1$ comme l'opposé du gradient de f à x=x$_0$. Le gradient vaut Ax$_0$ – b= – b, d'après notre première hypothèse. Les vecteurs suivants de la base seront ainsi conjugués au gradient, d'où le nom « méthode du gradient conjugué ».
Soit r$_k$ le résidu à la ke itération :
    $r_{k}=b-\mathbf {A} x_{k}.\,$
Notons que r$_k$ est l'opposé du gradient de f en x=x$_k$, ainsi, l'algorithme du gradient indique d'évoluer dans la direction r$_k$. On rappelle que les directions p$_k$ sont conjuguées deux à deux. On veut aussi que la direction suivante soit construite à partir du résidu courant et des directions précédemment construites, ce qui est une hypothèse raisonnable en pratique.
La contrainte de conjugaison est une contrainte d'orthonormalité, aussi le problème partage des similitudes avec le procédé de Gram-Schmidt.
On a ainsi
    ${p}_{k}={r}_{k}-\sum _{i\leq k-1}{\frac {{p}_{i}^{\mathrm {T} }\mathbf {A} {r}_{k}}{{p}_{i}^{\mathrm {T} }\mathbf {A} {p}_{i}}}{p}_{i}$
Suivant cette direction, le point suivant est donné par
    ${x}_{k+1}={x}_{k}+\alpha _{k}{p}_{k}$
    où le pas $\alpha _{k}$ est déterminé de manière à minimiser $g(\alpha )=f({x}_{k}+\alpha {p}_{k})={\frac {1}{2}}\alpha ^{2}{p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{k}+\alpha {p}_{k}^{\mathrm {T} }(\mathbf {A} {x}_{k}-b)+constante$;
    le minimum de g est atteint pour ${\frac {\mathrm {d} g}{\mathrm {d} \alpha }}(\alpha _{k})=0$ et comme A est définie positive, ${p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{k}>0$ ,
    on a donc : $\alpha _{k}={\frac {{p}_{k}^{\mathrm {T} }(b-\mathbf {A} {x}_{k})}{{p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{k}}}={\frac {{p}_{k}^{\mathrm {T} }{r}_{k}}{{p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{k}}}$
    Une analyse plus détaillée de cette algorithme (un raisonnement par récurrence) montre que $\mathbf {r} _{i}$ est orthogonal à $\mathbf {r} _{j}$, i.e. $\mathbf {r} _{i}^{\mathsf {T}}\mathbf {r} _{j}=0$ pour $i\neq j$ (voir ci-après) et que $\mathbf {p} _{i}$ est $\mathbf {A}$-orthogonal à $\mathbf {p} _{j}$ , i.e. $\mathbf {p} _{i}^{\mathsf {T}}\mathbf {A} \mathbf {p} _{j}=0$ , pour $i\neq j$.

### Algorithme

Pour amorcer la récurrence, il faut partir d’une estimation initiale x$_0$ du vecteur x recherché ; et le nombre d'itérations N nécessaire pour que $\|x_{N}-x\|<\varepsilon$ (où ε est un nombre positif arbitrairement proche de zéro) dépend du x$_0$ choisi. Malheureusement, les méthodes de « préconditionnement » à la fois sûres et générales (c'est-à-dire efficaces pour toutes sortes de matrices symétriques positives) pour former un x$_0$ correct sont aussi elles-mêmes coûteuses en temps de calcul. En pratique, l'intuition physique, guidée par la nature physique du problème à résoudre, suggère parfois une initialisation efficace : ces idées ont donné lieu depuis plus de trente ans à une littérature spécialisée abondante.

#### Algorithme itératif en pseudo-code

L'algorithme ci-dessous résout Ax = b, où A est une matrice réelle, symétrique, et définie positive. Le vecteur d'entrée x$_0$ peut être une approximation de la solution initiale ou 0. Cette algorithme est issu de la méthode itérative exacte présentée dans le paragraphe précédent, les valeurs des coefficients $\alpha _{k}$ semblent différentes mais en utilisant les relations de l'algorithme ci-dessous, en particulier : $\mathbf {p} _{k}=\mathbf {r} _{k}+\beta _{k-1}\mathbf {p} _{k-1}$, et le fait que les résidus $\mathbf {r} _{k}$ et $\mathbf {r} _{k-1}$ soient orthogonaux , on peut montrer par récurrence que l'on a bien : $\alpha _{k}={\frac {{p}_{k}^{\mathrm {T} }{r}_{k}}{{p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{k}}}={\frac {r_{k}^{\mathrm {T} }{r}_{k}}{{p}_{k}^{\mathrm {T} }\mathbf {A} {p}_{k}}}$. Ci-dessous le coefficient $\alpha _{k}$ est choisi pour que les résidus $\mathbf {r} _{k+1}$ et $\mathbf {r} _{k}$ soient orthogonaux et non pas minimiser g comme dans le paragraphe précédent, mais en fait les deux approches reviennent à la même formule pour $\alpha _{k}$ et le coefficient $\beta _{k}$ est choisi pour que $\mathbf {p} _{k+1}$ soit A-conjugué de $\mathbf {p} _{k}$.
    ${\begin{aligned}&\mathbf {r} _{0}:=\mathbf {b} -\mathbf {Ax} _{0}\\&\mathbf {p} _{0}:=\mathbf {r} _{0}\\&k:=0\\&{\hbox{répéter}}\\&\qquad \alpha _{k}:={\frac {\mathbf {r} _{k}^{\mathsf {T}}\mathbf {r} _{k}}{\mathbf {p} _{k}^{\mathsf {T}}\mathbf {Ap} _{k}}}\\&\qquad \mathbf {x} _{k+1}:=\mathbf {x} _{k}+\alpha _{k}\mathbf {p} _{k}\\&\qquad \mathbf {r} _{k+1}:=\mathbf {r} _{k}-\alpha _{k}\mathbf {Ap} _{k}\\&\qquad {\hbox{si }}r_{k+1}{\hbox{ est suffisamment petit, alors on sort de la boucle}}\\&\qquad \beta _{k}:={\frac {\mathbf {r} _{k+1}^{\mathsf {T}}\mathbf {r} _{k+1}}{\mathbf {r} _{k}^{\mathsf {T}}\mathbf {r} _{k}}}\\&\qquad \mathbf {p} _{k+1}:=\mathbf {r} _{k+1}+\beta _{k}\mathbf {p} _{k}\\&\qquad k:=k+1\\&{\hbox{fin de répéter}}\\&{\hbox{Le résultat est }}\mathbf {x} _{k+1}\end{aligned}}$
    Cet algorithme du gradient conjugué est celui qui est très souvent utilisé. Il est intéressant de constater que le coefficient $\beta _{k}$ de cet algorithme a la même expression que celui qui est utilisé dans la méthode 'Fletcher-Reeves' du gradient conjugué non-linéaire.
    On peut également remarquer que $x_{1}$ est déduit de $x_{0}$ en utilisant la méthode du gradient et que prendre $\beta _{k}=0$, revient à appliquer la méthode du gradient et peut donc être utilisé pour réinitialiser un calcul de gradient conjugué en cours. Réinitialiser un calcul en cours peut ralentir la convergence, mais peu également en augmenter la stabilité en particulier en réduisant les erreurs dus à l'accumulation d'imprécisions numériques (round-off errors).
    Les formules $\mathbf {x} _{k+1}:=\mathbf {x} _{k}+\alpha _{k}\mathbf {p} _{k}$ et $\mathbf {r} _{k}:=\mathbf {b} -\mathbf {Ax} _{k}$, qui sont exactes, impliquent que les deux formules $\mathbf {r} _{k+1}:=\mathbf {r} _{k}-\alpha _{k}\mathbf {Ap} _{k}$ et $\mathbf {r} _{k+1}:=\mathbf {b} -\mathbf {Ax} _{k+1}$ sont mathématiquement équivalentes. La première formule $\mathbf {r} _{k+1}:=\mathbf {r} _{k}-\alpha _{k}\mathbf {Ap} _{k}$ est utilisé dans l'algorithme pour éviter une multiplication supplémentaire par $\mathbf {A}$ car le vector $\mathbf {Ap} _{k}$ est déjà calculé pour évaluer $\alpha _{k}$. La deuxième formule $\mathbf {r} _{k+1}:=\mathbf {b} -\mathbf {Ax} _{k+1}$ peut par contre être plus précise car elle réduit l'accumulation des imprécisions numérique et elle est donc parfois recommandée.

### Exemple numérique

Considérons le système linéaire Ax = b suivant :
    $\mathbf {A} \mathbf {x} ={\begin{bmatrix}4&1\\1&3\end{bmatrix}}{\begin{bmatrix}x_{1}\\x_{2}\end{bmatrix}}={\begin{bmatrix}1\\2\end{bmatrix}},$
Deux itérations de l'algorithme du gradient conjugué vont être réalisées pas à pas à en partant du vecteur initial
    $\mathbf {x} _{0}={\begin{bmatrix}2\\1\end{bmatrix}}$
    Il est rappelé, que s'il n'y avait pas d'imprécision numérique dans les calculs le présent exemple est résolu en seulement n = 2 itérations, puisque ici la matrice est de dimension 2x2 et donc que x$_2$ devrait aux erreurs numériques près retrouver la solution exacte.

#### Solution

La solution exacte de ce système linéaire est obtenu en inversant simplement la matrice A :
    $\mathbf {A} ^{-1}={\begin{bmatrix}3&-1\\-1&4\end{bmatrix}}/11$ et $\mathbf {x} =\mathbf {A} ^{-1}{\begin{bmatrix}1\\\\2\end{bmatrix}}={\begin{bmatrix}{\frac {1}{11}}\\\\{\frac {7}{11}}\end{bmatrix}}\approx {\begin{bmatrix}0.0909\\\\0.6364\end{bmatrix}}$
Les valeurs initiales de l'algorithme itératifs sont :
    $\mathbf {r} _{0}=\mathbf {b} -\mathbf {A} \mathbf {x} _{0}={\begin{bmatrix}1\\2\end{bmatrix}}-{\begin{bmatrix}4&1\\1&3\end{bmatrix}}{\begin{bmatrix}2\\1\end{bmatrix}}={\begin{bmatrix}-8\\-3\end{bmatrix}}=\mathbf {p} _{0}.$
    $\alpha _{0}={\frac {\mathbf {r} _{0}^{\mathsf {T}}\mathbf {r} _{0}}{\mathbf {p} _{0}^{\mathsf {T}}\mathbf {Ap} _{0}}}={\frac {{\begin{bmatrix}-8&-3\end{bmatrix}}{\begin{bmatrix}-8\\-3\end{bmatrix}}}{{\begin{bmatrix}-8&-3\end{bmatrix}}{\begin{bmatrix}4&1\\1&3\end{bmatrix}}{\begin{bmatrix}-8\\-3\end{bmatrix}}}}={\frac {73}{331}}\approx 0.2205$
Lors de la première itération la valeur x$_1$ est une meilleur approximation de la solution exacte:
    $\mathbf {x} _{1}=\mathbf {x} _{0}+\alpha _{0}\mathbf {p} _{0}={\begin{bmatrix}2\\1\end{bmatrix}}+{\frac {73}{331}}{\begin{bmatrix}-8\\-3\end{bmatrix}}\approx {\begin{bmatrix}0.2356\\0.3384\end{bmatrix}}.$
et le résidu associé r$_1$ est égal à :
    $\mathbf {r} _{1}=\mathbf {r} _{0}-\alpha _{0}\mathbf {A} \mathbf {p} _{0}={\begin{bmatrix}-8\\-3\end{bmatrix}}-{\frac {73}{331}}{\begin{bmatrix}4&1\\1&3\end{bmatrix}}{\begin{bmatrix}-8\\-3\end{bmatrix}}\approx {\begin{bmatrix}-0.2810\\0.7492\end{bmatrix}}.$
Ce résidu est encore grand et donc il est nécessaire de poursuivre la deuxième itération et donc de calculer les paramètres qui vont être utile pour calculer x$_2$: (i) d'abord β$_0$ puis (ii) la nouvelle direction de recherche p$_1$ et ensuite (iii) α$_1$ :
$\beta _{0}={\frac {\mathbf {r} _{1}^{\mathsf {T}}\mathbf {r} _{1}}{\mathbf {r} _{0}^{\mathsf {T}}\mathbf {r} _{0}}}\approx {\frac {{\begin{bmatrix}-0.2810&0.7492\end{bmatrix}}{\begin{bmatrix}-0.2810\\0.7492\end{bmatrix}}}{{\begin{bmatrix}-8&-3\end{bmatrix}}{\begin{bmatrix}-8\\-3\end{bmatrix}}}}=0.0088.$
    $\mathbf {p} _{1}=\mathbf {r} _{1}+\beta _{0}\mathbf {p} _{0}\approx {\begin{bmatrix}-0.2810\\0.7492\end{bmatrix}}+0.0088{\begin{bmatrix}-8\\-3\end{bmatrix}}={\begin{bmatrix}-0.3511\\0.7229\end{bmatrix}}.$
    $\alpha _{1}={\frac {\mathbf {r} _{1}^{\mathsf {T}}\mathbf {r} _{1}}{\mathbf {p} _{1}^{\mathsf {T}}\mathbf {Ap} _{1}}}\approx {\frac {{\begin{bmatrix}-0.2810&0.7492\end{bmatrix}}{\begin{bmatrix}-0.2810\\0.7492\end{bmatrix}}}{{\begin{bmatrix}-0.3511&0.7229\end{bmatrix}}{\begin{bmatrix}4&1\\1&3\end{bmatrix}}{\begin{bmatrix}-0.3511\\0.7229\end{bmatrix}}}}=0.4122.$
    $\mathbf {x} _{2}=\mathbf {x} _{1}+\alpha _{1}\mathbf {p} _{1}\approx {\begin{bmatrix}0.2356\\0.3384\end{bmatrix}}+0.4122{\begin{bmatrix}-0.3511\\0.7229\end{bmatrix}}={\begin{bmatrix}0.0909\\0.6364\end{bmatrix}}.$
x$_2$ est une bien meilleur approximation de la solution que x$_1$ et x$_0$ et cela est numériquement déterminé en évaluant le résidu r$_2$.
$\mathbf {r} _{2}=\mathbf {r} _{1}-\alpha _{1}\mathbf {A} \mathbf {p} _{1}={\begin{bmatrix}-0.2810\\0.7492\end{bmatrix}}-0.4122{\begin{bmatrix}4&1\\1&3\end{bmatrix}}{\begin{bmatrix}-0.3511\\0.7229\end{bmatrix}}\approx {\begin{bmatrix}-0.00009\\-0.00001\end{bmatrix}}.$
Il est également intéressant de vérifier que : $\mathbf {r} _{1}^{\mathsf {T}}\mathbf {r} _{1}=\mathbf {p} _{1}^{\mathsf {T}}\mathbf {r} _{1}$ :
$\mathbf {r} _{1}^{\mathsf {T}}\mathbf {r} _{1}={\begin{bmatrix}-0.2810&0.7492\end{bmatrix}}{\begin{bmatrix}-0.2810\\0.7492\end{bmatrix}}=0.6402$ et
$\mathbf {p} _{1}^{\mathsf {T}}\mathbf {r} _{1}={\begin{bmatrix}-0.3511&0.7229\end{bmatrix}}{\begin{bmatrix}-0.2810\\0.7492\end{bmatrix}}=0.6402$

### Convergence

On peut montrer le résultat suivant sur la convergence de l'algorithme :
    $\|x^{*}-x_{k}\|_{\mathbf {A} }\leqslant 2\left({\frac {{\sqrt {\kappa (\mathbf {A} )}}-1}{{\sqrt {\kappa (\mathbf {A} )}}+1}}\right)^{k}\|x^{*}-x_{0}\|_{\mathbf {A} },$
où ${\sqrt {\kappa (\mathbf {A} )}}$ désigne le conditionnement de la matrice et $\|z\|_{\mathbf {A} }={\sqrt {z^{T}\mathbf {A} z}}.$
La méthode du gradient conjugué a donc une convergence superlinéaire, qui peut être mise à mal par un mauvais conditionnement de la matrice. Elle reste toutefois meilleure que les algorithmes à direction de plus forte pente.

## Solveur

* (en) M1CG1 - A solver of symmetric linear systems by conjugate gradient iterations, using/building a BFGS/ℓ-BFGS preconditioner. Écrit en Fortran-77. Le solveur a l'intérêt d'offrir la possibilité de construire un préconditionneur BFGS ou ℓ-BFGS (en), qui pourra être utile pour la résolution d'un système linéaire avec une matrice proche et un second membre différent.