# Méthode de Brent

En analyse numérique, la méthode de Brent est un algorithme de recherche d'un zéro d'une fonction combinant la méthode de dichotomie, la méthode de la sécante et l’interpolation quadratique inverse. À chaque itération, elle décide laquelle de ces trois méthodes est susceptible d’approcher au mieux le zéro, et effectue une itération en utilisant cette méthode. L'idée principale est d'utiliser la méthode de la sécante ou d'interpolation quadratique inverse parce qu'elles convergent vite, et de revenir à la méthode de dichotomie si besoin est. L'idée d'allier ces méthodes différentes est due à Theodorus Dekker (en) (1969) et à Richard Brent (1973).
La méthode de Chandrupatla en est une variante plus simple et qui converge plus rapidement pour les fonctions plates au voisinage de leurs racines$^,$.

## Méthode de Dekker

L'idée de combiner les méthodes de dichotomie et de la sécante remonte à Dekker.
On suppose vouloir résoudre l'équation f(x) = 0. À l'image de la méthode de dichotomie, la méthode de Dekker est initialisée par deux points, notés a$_0$ et b$_0$, tels que f(a$_0$) et f(b$_0$) soient de signes opposés. Si f est continue sur [a$_0$, b$_0$], le théorème des valeurs intermédiaires indique l'existence d'une solution entre a$_0$ et b$_0$.
À chaque itération, trois points entrent en jeu:
* b$_k$ est l'itération courante, c'est-à-dire l'approximation courante de la racine de f;
* a$_k$ est le contrepoint, c'est-à-dire un point tel que f(a$_k$) et f(b$_k$) soient de signes opposés. Ainsi, l'intervalle [a$_k$ ; b$_k$] contient à coup sûr la solution. De plus, |f(b$_k$)| doit être plus petit (en valeur absolue) que |f(a$_k$)|, de telle sorte que b$_k$ soit une meilleure approximation de la racine que a$_k$;
* b$_{k−1}$ est l'itération précédente (pour la première itération, on pose b$_{k-1}$ = a$_0$).
Deux candidats à la prochaine itération sont calculés: le premier est obtenu par la méthode de la sécante
    $s=b_{k}-{\frac {b_{k}-b_{k-1}}{f(b_{k})-f(b_{k-1})}}f(b_{k}),$
et le second par la méthode de dichotomie
    $m={\frac {a_{k}+b_{k}}{2}}.$
Si le résultat de la méthode de la sécante, s, tombe entre b$_k$ et m, alors il peut devenir le prochain itéré (b$_{k+1}$ = s), et dans le cas contraire, le point milieu entre en jeu (b$_{k+1}$ = m).
Alors, la valeur du nouveau contrepoint est choisie de telle sorte que f(a$_{k+1}$) et f(b$_{k+1}$) soient de signes opposés. Si f(a$_k$) et f(b$_{k+1}$) sont de signes opposés, alors le contrepoint ne change pas : a$_{k+1}$ = a$_k$. Sinon, f(b$_{k+1}$) et f(b$_k$) sont de signes opposés et le nouveau contrepoint devient a$_{k+1}$ = b$_k$.
Finalement, si |f(a$_{k+1}$)| < |f(b$_{k+1}$)|, alors a$_{k+1}$ est probablement une meilleure approximation de la solution que b$_{k+1}$, et par suite, les valeurs de a$_{k+1}$ et b$_{k+1}$ sont échangées.
En arrivant à ce point, la méthode vient de réaliser une itération. La méthode est répétée jusqu'à convergence.

## Méthode de Brent

La méthode de Dekker est efficace si f se comporte raisonnablement bien. Toutefois, dans certaines circonstances, chaque itération emploie la méthode de la sécante mais la suite des b$_k$ converge très lentement (en particulier, |b$_k$ − b$_{k−1}$| peut devenir arbitrairement petit). Dans une telle configuration, la méthode de Dekker nécessite alors plus d'itérations que la méthode de dichotomie.
Brent propose une petite modification pour éviter ce problème: un test supplémentaire doit être vérifié avant que le résultat de la méthode de la sécante soit accepté comme la prochaine itération. En particulier, si l'étape précédente utilisait la méthode de dichotomie, l'inégalité
    $|s-b_{k}|<{\begin{matrix}{\frac {1}{2}}\end{matrix}}|b_{k}-b_{k-1}|$
doit être vraie, sinon le point milieu m devient le prochain itéré. Si l'étape précédente utilisait l'interpolation, alors l'inégalité
    $|s-b_{k}|<{\begin{matrix}{\frac {1}{2}}\end{matrix}}|b_{k-1}-b_{k-2}|$
est utilisée à la place. Cette modification permet de remplacer la méthode de la sécante par la méthode de dichotomie lorsque la première progresse trop lentement. Brent a prouvé que cette méthode requiert au plus N$^2$ itérations, où N représente le nombre d'itérations pour la méthode de dichotomie. Si la fonction f se comporte bien, la méthode de Brent utilise au choix l'interpolation quadratique inverse ou l'interpolation linéaire, auquel cas la vitesse de convergence est superlinéaire.
La méthode de Brent se base sur l'interpolation quadratique inverse plutôt que l'interpolation linéaire (qui apparaît dans la méthode de la sécante) si f(b$_k$), f(a$_k$) et f(b$_{k−1}$) sont distincts. Ceci améliore significativement l'efficacité. Par conséquent, la condition pour accepter la valeur d'interpolation s est modifiée: s doit tomber entre (3a$_k$ + b$_k$) / 4 et b$_k$.

## Exemple

On cherche à identifier une racine de f(x) = (x + 3)(x − 1)$^2$. On prend [a$_0$; b$_0$] = [−4; 4/3] comme intervalle initial. On a f(a$_0$) = −25 et f(b$_0$) = 0,48148 (tous les nombres de cette section sont tronqués); ainsi les conditions f(a$_0$) f(b$_0$) < 0 et |f(b$_0$)| ≤ |f(a$_0$)| sont vérifiées. Nous allons détailler l'utilisation de Brent, qui utilise soit l'interpolation linéaire (abrégée en IL) soit l'interpolation quadratique inverse (IQI).
* Dans la première itération, on utilise une IL entre (b$_{−1}$; f(b$_{−1}$)) = (a$_0$; f(a$_0$)) = (−4; −25) et (b$_0$; f(b$_0$)) = (1,33333; 0,48148), ce qui conduit à s = 1,23256. Cette valeur tombe entre (3a$_0$ + b$_0$) / 4 et b$_0$ et, par conséquent, cette valeur est acceptée. En outre, f(1,23256) = 0,22891, ce qui donne a$_1$ = a$_0$ et b$_1$ = s = 1,23256;
* Dans la deuxième itération, une IQI entre (a$_1$; f(a$_1$)) = (−4; −25) et (b$_0$; f(b$_0$)) = (1,33333; 0,48148) et (b$_1$; f(b$_1$)) = (1,23256; 0,22891) donne 1,14205; cette valeur est entre (3a$_1$ + b$_1$) / 4 et b$_1$. De plus, l'inégalité |1,14205 − b$_1$| ≤ |b$_0$ − b$_{−1}$| / 2 est satisfaite; cette valeur est donc retenue. Enfin, comme f(1,14205) = 0,083582, on pose a$_2$ = a$_1$ et b$_2$ = 1,14205;
* Dans la troisième itération, on utilise une IQI entre (a$_2$; f(a$_2$)) = (−4; −25) et (b$_1$; f(b$_1$)) = (1,23256; 0,22891) et (b$_2$; f(b$_2$)) = (1,14205; 0,083582), ce qui donne 1,09032. Cette valeur est entre (3a$_2$ + b$_2$) / 4 et b$_2$;mais la condition supplémentaire de Brent bloque: en effet, l'inégalité |1,09032 − b$_2$| ≤ |b$_1$ − b$_0$| / 2 n'est pas vérifiée: la valeur en cours est donc rejetée. À la place, on calcule le point milieu de l'intervalle [a$_2$; b$_2$]: m = −1,42897. On a f(m) = 9,26891; on pose alors a$_3$ = a$_2$ et b$_3$ = −1,42897;
* Dans la quatrième itération, la valeur −1,15448 est obtenue par IQI entre (a$_3$; f(a$_3$)) = (−4; −25) et (b$_2$; f(b$_2$)) = (1,14205; 0,083582) et enfin (b$_3$; f(b$_3$)) = (−1,42897; 9,26891). Cette valeur ne tombe pas entre (3a$_3$ + b$_3$) / 4 et b$_3$). Par conséquent, on calcule à la place le milieu m = −2,71449; on a f(m) = 3,9393. On pose finalement a$_4$ = a$_3$ et b$_4$ = −2,71449;
* Dans la cinquième itération, une IQI donne −3,45500, qui tombe dans l'intervalle requis. Toutefois, l'itération précédente était une étape de dichotomie et l'inégalité |−3,45500 − b$_4$| ≤ |b$_4$ − b$_3$| / 2 doit être satisfaite, ce qui n'est pas le cas. On utilise alors le point milieu m = −3,35724, pour lequel f(m) = −6,78239. Ainsi, m devient le nouveau contrepoint: a$_5$ = −3,35724 et b$_5$ = b$_4$;
* Dans la sixième itération, l'IQI est interdite car b$_5$ = b$_4$. Par conséquent, on la remplace par une IL entre (a$_5$; f(a$_5$)) = (−3,35724; −6,78239) et (b$_5$; f(b$_5$)) = (−2,71449; 3,93934). Il en résulte s = −2,95064, qui satisfait toutes les conditions. On calcule f(s) = 0,77032 et on pose a$_6$ = a$_5$ et b$_6$ = −2,95064;
* Dans la septième itération, on utilise encore une IQI ce qui donne s = −3,00219, qui vérifie toutes les conditions. Maintenant, f(s) = −0,03515, et on pose donc a$_7$ = b$_6$ et b$_7$ = −3,00219 (a$_7$ et b$_7$ sont échangés afin que |f(b$_7$)| ≤ |f(a$_7$)| soit vraie);
* Dans la huitième itération, on ne peut considérer une IQI parce que a$_7$ = b$_6$. L'IL donne à la place s = −2,99994, valeur qui est acceptée;
* Dans les itérations suivantes, la racine x = −3 est approchée rapidement: b$_9$ = −3 + 6 × 10$^{−8}$ et b$_{10}$ = −3 – 3 × 10$^{−15}$.

## Algorithme

* Entrée de a, b, un pointeur vers une sous-routine pour f, e une précision désirée
* calculer f(a)
* calculer f(b)
* si f(a) f(b) >= 0 alors sortie (erreur) fin si
* si |f(a)| < |f(b)| alors échanger (a,b) fin si
* c := a
* mflag := vrai
* tant que f(b) != 0 ou |b − a|>e (condition de convergence)
** si f(a) ≠ f(c) et f(b) ≠ f(c) alors
*** $s:={\frac {af(b)f(c)}{(f(a)-f(b))(f(a)-f(c))}}+{\frac {bf(a)f(c)}{(f(b)-f(a))(f(b)-f(c))}}+{\frac {cf(a)f(b)}{(f(c)-f(a))(f(c)-f(b))}}$ (interpolation quadratique inverse)
** sinon
*** $s:=b-f(b){\frac {b-a}{f(b)-f(a)}}$ (règle de la sécante)
** fin si
** si s n'est pas entre (3a + b)/4 et b ou (mflag est vrai et |s−b| ≥ |b−c| / 2) ou (mflag est faux et |s−b| ≥ |c−d| / 2) alors
*** $s:={\frac {a+b}{2}}$
*** mflag := vrai
** sinon
*** mflag := faux
** fin si
** calculer f(s)
** d := c
** c := b
** si f(a) f(s) < 0 alors b := s sinon a := s fin si
** si |f(a)| < |f(b)| alors échange (a,b) fin si
* fin tant que
* sortir b (renvoi de la racine)

## Implémentations

Brent (1973) a publié une implémentation en Algol 60. La bibliothèque Netlib contient une implémentation en Fortran. La fonction MATLAB nommée fzero ou la fonction solve de PARI/GP sont d'autres exemples d'implémentation de la méthode de Brent.