La méthode d'Euler et les équations différentielles Grand Oral · mathématiques, physique-chimie, SVT Un support de connaissances pour construire sa propre question

← Tous les textes du Grand Oral

MathsPCSVT

Une tasse de café qui refroidit, un parachutiste qui tombe, une population de bactéries qui grandit, un condensateur qui se charge : dans chaque cas, on connaît la loi d'évolution (comment la grandeur varie à chaque instant) et l'on veut en déduire la grandeur elle-même. Mathématiquement, on connaît la dérivée d'une fonction en fonction de la fonction, et l'on cherche la fonction : c'est une équation différentielle.

Le cours de terminale apprend à résoudre exactement $y' = ay$ et $y' = ay + b$. Mais la plupart des équations utiles ne se résolvent pas avec des fonctions connues. En 1768, Leonhard Euler propose une idée très simple pour les résoudre de façon approchée : avancer à petits pas, en suivant à chaque pas la tangente. C'est encore, sous des formes perfectionnées, ce que font les ordinateurs qui calculent la météo ou la trajectoire d'une fusée.

Ce texte rassemble ces connaissances, avec les mathématiques de terminale : dérivation et tangente, suites géométriques, exponentielle, logarithme, limites, algorithmique. Il ne propose pas de Grand Oral tout fait : à chacun d'y choisir une direction et d'y construire sa question.

Sommaire
  1. Une équation dont l'inconnue est une fonction
  2. La méthode d'Euler pas à pas
  3. Quand le pas tend vers zéro : $(1 + a/n)^n$ et $\mathrm{e}^a$
  4. L'erreur et le pas
  5. L'équation $y' = ay + b$ : refroidissement et condensateur
  6. La chute d'un parachutiste
  7. Le modèle logistique de Verhulst
  8. Histoire et limites de la méthode
  9. Des directions pour construire sa question
Une équation dont l'inconnue est une fonction

Dans une équation ordinaire comme $3x + 2 = 8$, l'inconnue est un nombre. Dans une équation différentielle, l'inconnue est une fonction $y$, et l'équation relie $y$ à sa dérivée $y'$. Par exemple,

$$y' = y$$

demande de trouver les fonctions égales à leur propre dérivée. Le cours de terminale répond : ce sont les fonctions $x \mapsto C\,\mathrm{e}^{x}$, où $C$ est une constante réelle. Si l'on impose en plus la condition initiale $y(0) = 1$, il reste une seule solution : la fonction exponentielle.

Plus généralement, le cours établit que :

Ces équations sont les plus simples, et elles décrivent déjà beaucoup de phénomènes : la radioactivité, la cinétique d'ordre 1, le refroidissement, la charge d'un condensateur. Mais dès que la loi d'évolution contient un carré, comme $v' = g - c\,v^2$ pour une chute dans l'air, ou un produit, comme $P' = rP\left(1 - \frac{P}{K}\right)$ pour une population, le cours ne donne plus de méthode de résolution. C'est là qu'intervient la méthode d'Euler.

La méthode d'Euler pas à pas L'idée : suivre la tangente

Le cours de première l'enseigne : près d'un point d'abscisse $x$, la courbe d'une fonction dérivable est très proche de sa tangente. Pour un petit nombre $h$,

$$y(x + h) \approx y(x) + h\,y'(x).$$

Or l'équation différentielle donne justement $y'(x)$ à partir de $y(x)$. On peut donc partir de la condition initiale et avancer par pas de longueur $h$ : à chaque pas, on calcule la pente donnée par l'équation, et l'on suit la tangente sur une longueur $h$. On obtient des points $(x_0 ; y_0)$, $(x_1 ; y_1)$, $(x_2 ; y_2)$, etc., avec

$$x_{k+1} = x_k + h,$$

et

$$y_{k+1} = y_k + h \times (\text{pente en } x_k).$$

Le nombre $h$ s'appelle le pas. On remplace ainsi la courbe inconnue par une ligne brisée, et l'on espère que plus le pas est petit, plus la ligne brisée est proche de la courbe.

Un exemple à la main

Prenons $y' = y$ avec $y(0) = 1$, dont on sait que la solution est l'exponentielle, et cherchons une valeur approchée de $y(1) = \mathrm{e}$ avec un pas $h = 0{,}25$, donc en $4$ pas. Ici la pente en $x_k$ est $y_k$ elle-même, donc

$$y_{k+1} = y_k + 0{,}25\,y_k = 1{,}25\,y_k.$$
$k$$x_k$calcul$y_k$$\mathrm{e}^{x_k}$
$0$$0$condition initiale$1$$1$
$1$$0{,}25$$1 \times 1{,}25$$1{,}25$$1{,}284$
$2$$0{,}5$$1{,}25 \times 1{,}25$$1{,}5625$$1{,}649$
$3$$0{,}75$$1{,}5625 \times 1{,}25$$1{,}9531$$2{,}117$
$4$$1$$1{,}9531 \times 1{,}25$$2{,}4414$$2{,}718$

On trouve $y_4 \approx 2{,}44$ au lieu de $\mathrm{e} \approx 2{,}718$ : une erreur d'environ $10\,\%$. C'est grossier, mais on n'a fait que quatre multiplications. On remarque surtout que la suite $(y_k)$ est géométrique de raison $1{,}25$, donc $y_4 = 1{,}25^4 = \left(1 + \frac{1}{4}\right)^4$.

Avec $n$ pas de longueur $h = \frac{1}{n}$, le même raisonnement donne une suite géométrique de raison $1 + \frac{1}{n}$, et la valeur approchée de $\mathrm{e}$ obtenue est

$$y_n = \left(1 + \frac{1}{n}\right)^n.$$

La figure ci-dessous montre la ligne brisée d'Euler sur l'intervalle $[0 ; 2]$, pour un nombre de pas réglable.

var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var petit = {fontSize: 11, useKatex: false, parse: false, fixed: true, highlight: false}; var ax = {strokeColor: '#455a64', strokeWidth: 1, fixed: true, highlight: false, lastArrow: true}; board.create('segment', [[0, 0], [2.18, 0]], ax); board.create('segment', [[0, 0], [0, 8.3]], ax); for (var t = 0.5; t <= 2; t += 0.5) { board.create('segment', [[t, 0], [t, -0.12]], {strokeColor: '#455a64', fixed: true, highlight: false}); board.create('text', [t - 0.06, -0.45, String(t).replace('.', ',')], petit); } for (var u = 2; u <= 8; u += 2) { board.create('segment', [[0, u], [-0.03, u]], {strokeColor: '#455a64', fixed: true, highlight: false}); board.create('text', [-0.2, u, String(u)], petit); } board.create('text', [2.02, -0.95, 'x'], opt); var sn = board.create('slider', [[0.1, -1.75], [1.35, -1.75], [1, 4, 40]], {withLabel: false, snapWidth: 1}); function nombre(x, d) { return x.toFixed(d).replace('.', ','); } board.create('text', [1.45, -1.75, function () { return 'n = ' + Math.round(sn.Value()) + ' pas'; }], opt); board.create('functiongraph', [function (x) { return Math.exp(x); }, 0, 2.1], {strokeColor: '#c62828', strokeWidth: 2, highlight: false}); var c = board.create('curve', [[0], [0]], {strokeColor: '#1565c0', strokeWidth: 2, highlight: false}); c.updateDataArray = function () { var n = Math.round(sn.Value()), h = 2 / n, X = [0], Y = [1], y = 1, k; for (k = 1; k <= n; k++) { y = y + h * y; X.push(k * h); Y.push(y); } this.dataX = X; this.dataY = Y; }; function euler2() { var n = Math.round(sn.Value()); return Math.pow(1 + 2 / n, n); } board.create('text', [0.06, 8.0, function () { return 'pas h = ' + nombre(2 / Math.round(sn.Value()), 3); }], opt); board.create('text', [0.06, 7.35, function () { return 'Euler : y(2) ≈ ' + nombre(euler2(), 3); }], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); board.create('text', [0.06, 6.7, 'exacte : e² ≈ 7,389'], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#c62828'}); En rouge, la courbe de l'exponentielle, solution exacte de $y' = y$ avec $y(0) = 1$. En bleu, la ligne brisée d'Euler ; le curseur règle le nombre de pas sur $[0 ; 2]$. La ligne brisée reste toujours sous la courbe, et s'en rapproche quand le pas diminue.
Le même calcul en Python

Le programme suivant écrit la méthode d'Euler une fois pour toutes, pour une équation $y' = f(x, y)$ quelconque. On l'applique ici à $y' = y$ ; il suffit de changer la fonction f pour traiter une autre équation.

from math import exp def euler(f, x0, y0, h, n): x, y = x0, y0 for k in range(n): y = y + h * f(x, y) # on suit la tangente sur une longueur h x = x + h return y def f(x, y): return y # l'équation y' = y for n in [4, 10, 100, 1000, 10000]: approx = euler(f, 0, 1, 1 / n, n) print(n, "pas :", approx, " erreur :", exp(1) - approx)
Quand le pas tend vers zéro : $(1 + a/n)^n$ et $\mathrm{e}^a$

Pour l'équation $y' = ay$ avec $y(0) = 1$, la méthode d'Euler avec $n$ pas sur $[0 ; 1]$ donne de même $y_{k+1} = y_k + \frac{1}{n} \times a\,y_k = \left(1 + \frac{a}{n}\right)y_k$, donc une suite géométrique, et la valeur approchée de $y(1) = \mathrm{e}^a$ est $\left(1 + \frac{a}{n}\right)^n$. Pour savoir si la méthode « marche », il faut donc étudier la limite de cette suite.

Pour tout réel $a$, $\displaystyle\lim_{n \to +\infty} \left(1 + \frac{a}{n}\right)^n = \mathrm{e}^a$

Étape 1 : passer au logarithme. Si $a = 0$, la suite vaut $1$ et $\mathrm{e}^0 = 1$. Sinon, pour $n > |a|$, on a $1 + \frac{a}{n} > 0$, donc on peut écrire

$$u_n = \left(1 + \frac{a}{n}\right)^n = \mathrm{e}^{\,n \ln\left(1 + \frac{a}{n}\right)}.$$

Étape 2 : faire apparaître un taux d'accroissement. Posons $t = \frac{a}{n}$, qui tend vers $0$ quand $n$ tend vers $+\infty$. Comme $n = \frac{a}{t}$,

$$n \ln\left(1 + \frac{a}{n}\right) = a \times \frac{\ln(1 + t) - \ln 1}{t}.$$

Étape 3 : reconnaître un nombre dérivé. Le quotient $\dfrac{\ln(1 + t) - \ln 1}{t}$ est le taux d'accroissement de la fonction $\ln$ entre $1$ et $1 + t$. Quand $t$ tend vers $0$, il tend vers le nombre dérivé $\ln'(1) = \frac{1}{1} = 1$. Donc $n \ln\left(1 + \frac{a}{n}\right)$ tend vers $a \times 1 = a$.

Étape 4 : revenir à l'exponentielle. La fonction exponentielle est continue en $a$, donc $u_n = \mathrm{e}^{\,n \ln(1 + a/n)}$ tend vers $\mathrm{e}^a$.

En remplaçant $a$ par $ax$, on obtient de même que la méthode d'Euler appliquée à $y' = ay$ sur $[0 ; x]$ avec $n$ pas donne $\left(1 + \frac{ax}{n}\right)^n$, qui tend vers $\mathrm{e}^{ax}$ : quand le pas tend vers zéro, la méthode d'Euler donne la solution exacte. Pour cette équation, c'est un théorème ; pour les équations plus générales, il existe des théorèmes analogues, étudiés après le bac.

Cette limite a aussi une histoire indépendante : au XVIIe siècle, Jacques Bernoulli l'a rencontrée en se demandant ce que devient un placement à $100\,\%$ d'intérêts par an si l'on capitalise les intérêts tous les mois, tous les jours, à chaque instant. Avec $n$ capitalisations, un euro devient $\left(1 + \frac{1}{n}\right)^n$ euros, et jamais plus de $\mathrm{e} \approx 2{,}718$ euros.

L'erreur et le pas Euler sous-estime l'exponentielle

Sur la figure, la ligne brisée reste toujours sous la courbe. Ce n'est pas un hasard, et on peut le démontrer.

Pour tout entier $n \geqslant 1$, $\left(1 + \frac{1}{n}\right)^n < \mathrm{e}$

Étape 1 : une inégalité sur le logarithme. Soit $g$ la fonction définie sur $]-1 ; +\infty[$ par $g(t) = t - \ln(1 + t)$. Elle est dérivable et

$$g'(t) = 1 - \frac{1}{1 + t} = \frac{t}{1 + t}.$$

Comme $1 + t > 0$, $g'(t)$ a le signe de $t$ : $g$ est décroissante sur $]-1 ; 0]$ et croissante sur $[0 ; +\infty[$. Son minimum est $g(0) = 0$, et il n'est atteint qu'en $0$. Donc pour tout $t \neq 0$, $\ln(1 + t) < t$.

Étape 2 : conclure. Avec $t = \frac{1}{n}$ : $n \ln\left(1 + \frac{1}{n}\right) < n \times \frac{1}{n} = 1$. La fonction exponentielle étant strictement croissante,

$$\left(1 + \frac{1}{n}\right)^n = \mathrm{e}^{\,n\ln\left(1 + \frac{1}{n}\right)} < \mathrm{e}^1.$$

Géométriquement, l'inégalité $\ln(1 + t) \leqslant t$ équivaut à $\mathrm{e}^t \geqslant 1 + t$ : la courbe de l'exponentielle est au-dessus de ses tangentes, car la fonction est convexe. En suivant une tangente, on passe donc toujours sous la courbe, et l'on prend du retard à chaque pas.

Diviser le pas par 10 divise l'erreur par 10

Le programme Python précédent donne les valeurs suivantes de l'erreur $\mathrm{e} - \left(1 + \frac{1}{n}\right)^n$.

$n$pas $h$$\left(1 + \frac{1}{n}\right)^n$erreurerreur $\times\, n$
$10$$0{,}1$$2{,}593\,74$$0{,}124\,5$$1{,}245$
$100$$0{,}01$$2{,}704\,81$$0{,}013\,5$$1{,}347$
$1\,000$$0{,}001$$2{,}716\,92$$0{,}001\,36$$1{,}358$
$10\,000$$0{,}000\,1$$2{,}718\,15$$0{,}000\,136$$1{,}359$

La dernière colonne se stabilise vers $1{,}359$, qui est environ $\frac{\mathrm{e}}{2}$ : l'erreur est à peu près proportionnelle au pas, environ $\frac{\mathrm{e}}{2}\,h$. On dit que la méthode d'Euler est d'ordre 1. Pour gagner une décimale, il faut dix fois plus de pas, donc dix fois plus de calculs.

On peut le comprendre ainsi : à chaque pas, l'écart entre la tangente et la courbe est de l'ordre de $h^2$ (c'est la courbure qui le crée) ; sur un intervalle de longueur $1$, il y a $\frac{1}{h}$ pas, et les erreurs s'accumulent en environ $\frac{1}{h} \times h^2 = h$. C'est un raisonnement d'ordre de grandeur, pas une démonstration.

L'équation $y' = ay + b$ : refroidissement et condensateur La loi du refroidissement de Newton

En 1701, Isaac Newton publie anonymement une échelle de températures dans laquelle il énonce une loi : un corps chaud refroidit d'autant plus vite qu'il est plus chaud que l'air qui l'entoure. Si $T(t)$ est la température du corps à l'instant $t$ et $T_a$ celle de l'air,

$$T'(t) = -k\,\bigl(T(t) - T_a\bigr),$$

où $k$ est une constante positive qui dépend du corps (sa taille, sa matière, le récipient). C'est une équation $y' = ay + b$ avec $a = -k$ et $b = kT_a$. D'après le cours, ses solutions sont $T(t) = C\,\mathrm{e}^{-kt} + T_a$, et avec la condition initiale $T(0) = T_0$,

$$T(t) = T_a + (T_0 - T_a)\,\mathrm{e}^{-kt}.$$

On le vérifie en dérivant : $T'(t) = -k(T_0 - T_a)\,\mathrm{e}^{-kt}$, et $T(t) - T_a = (T_0 - T_a)\,\mathrm{e}^{-kt}$, donc on a bien $T' = -k(T - T_a)$. L'écart à la température de l'air décroît exponentiellement : il est divisé par deux toutes les $\frac{\ln 2}{k}$ unités de temps, comme pour une demi-vie radioactive.

Une tasse de café

Un café sort de la machine à $80\,°$C dans une pièce à $20\,°$C, avec $k = 0{,}05$ par minute (une valeur plausible pour une tasse, choisie pour l'exemple). Avec la méthode d'Euler et un pas de $1$ minute :

  • au départ, la pente vaut $-0{,}05 \times (80 - 20) = -3$ : après une minute, $T_1 = 80 - 3 = 77$ ;
  • puis la pente vaut $-0{,}05 \times 57 = -2{,}85$, donc $T_2 = 77 - 2{,}85 = 74{,}15$ ;
  • puis $T_3 = 74{,}15 - 0{,}05 \times 54{,}15 \approx 71{,}44$, et ainsi de suite.

La formule exacte donne, après $10$ minutes, $T(10) = 20 + 60\,\mathrm{e}^{-0{,}5} \approx 56{,}4\,°$C, et la méthode d'Euler $55{,}9\,°$C. Le café perd la moitié de son écart avec la pièce en $\frac{\ln 2}{0{,}05} \approx 14$ minutes.

Le tableur ci-dessous fait le calcul sur une demi-heure. Les cellules jaunes sont modifiables. La colonne « exacte » utilise le fait que, d'un pas au suivant, l'écart exact est multiplié par $\mathrm{e}^{-kh}$, tandis que la méthode d'Euler le multiplie par $1 - kh$ : si l'on change $k$ ou $h$, il faut recalculer $\mathrm{e}^{-kh}$ à la calculatrice et le saisir en B4.

Les deux suites sont géométriques (pour l'écart à $20\,°$C), de raisons $0{,}95$ et $\mathrm{e}^{-0{,}05} \approx 0{,}9512$ : comme $\mathrm{e}^{-kh} > 1 - kh$ (la convexité, encore), Euler refroidit le café un peu trop vite.

Dater un décès : la médecine légale

Le même modèle sert, en première approximation, à estimer l'heure d'un décès. Le corps est à $37\,°$C au moment de la mort, puis refroidit vers la température de la pièce. Supposons qu'un corps soit découvert dans une pièce à $18\,°$C, que sa température soit de $29\,°$C à la découverte et de $27\,°$C une heure plus tard.

Calcul de $k$. En prenant la découverte comme origine des temps, l'écart à la pièce passe de $11$ à $9$ en une heure : $9 = 11\,\mathrm{e}^{-k}$, donc $k = \ln\frac{11}{9} \approx 0{,}201$ par heure.

Calcul de l'heure du décès. À l'instant du décès $-d$ (en heures avant la découverte), l'écart valait $37 - 18 = 19$. Il est devenu $11$ en $d$ heures : $11 = 19\,\mathrm{e}^{-kd}$, donc

$$d = \frac{\ln(19/11)}{k} \approx \frac{0{,}547}{0{,}201} \approx 2{,}7 \text{ heures},$$

soit environ $2$ heures et $43$ minutes avant la découverte. En pratique, les médecins légistes savent que ce modèle est trop simple : la température reste à peu près stable pendant les premières heures (un « plateau »), puis décroît ; la masse du corps, les vêtements, l'humidité comptent. Ils utilisent des modèles plus fins, sous forme d'abaques (le nomogramme de Henssge en est un exemple), et donnent toujours un intervalle d'heures, jamais une heure exacte.

La charge d'un condensateur

En physique-chimie, un condensateur de capacité $C$ chargé à travers une résistance $R$ par un générateur de tension $E$ obéit à

$$RC\,u'(t) + u(t) = E,$$

soit

$$u' = -\frac{1}{RC}\,u + \frac{E}{RC}.$$

C'est encore une équation $y' = ay + b$. Avec $u(0) = 0$, sa solution est $u(t) = E\left(1 - \mathrm{e}^{-t/\tau}\right)$, où $\tau = RC$ est la constante de temps. Comme $1 - \mathrm{e}^{-1} \approx 0{,}63$, le condensateur est chargé à $63\,\%$ au bout de $\tau$, et à $1 - \mathrm{e}^{-5} \approx 99{,}3\,\%$ au bout de $5\tau$ : on dit qu'il est chargé « en pratique » après $5\tau$. Par exemple, avec $R = 10$ kΩ et $C = 100$ µF, $\tau = 1$ s. C'est le principe du flash d'un appareil photo, qui charge lentement un condensateur puis le décharge d'un coup dans la lampe.

La chute d'un parachutiste Un frottement proportionnel à la vitesse

Un objet de masse $m$ qui tombe subit son poids $mg$ et la résistance de l'air, dirigée vers le haut. Si l'on suppose cette résistance proportionnelle à la vitesse, égale à $\lambda v$, la deuxième loi de Newton donne, en orientant l'axe vers le bas,

$$m\,v' = mg - \lambda v, \quad\text{soit}\quad v' = g - \frac{\lambda}{m}\,v.$$

C'est une équation $y' = ay + b$. Avec $v(0) = 0$, on trouve $v(t) = v_\ell\left(1 - \mathrm{e}^{-\lambda t/m}\right)$ avec $v_\ell = \dfrac{mg}{\lambda}$. La vitesse tend vers la vitesse limite $v_\ell$ : quand la vitesse atteint cette valeur, la résistance de l'air compense exactement le poids, et la vitesse ne varie plus. On peut aussi trouver $v_\ell$ sans résoudre l'équation : c'est la valeur pour laquelle $v' = 0$.

Un frottement proportionnel au carré de la vitesse

Pour un objet rapide dans l'air, comme un parachutiste, les mesures montrent que la résistance est plutôt proportionnelle au carré de la vitesse :

$$v' = g - c\,v^2.$$

Cette équation n'est plus du type étudié en terminale : elle se résout avec une fonction hors programme (la tangente hyperbolique), mais la méthode d'Euler la traite sans rien savoir de plus. La vitesse limite s'obtient encore en écrivant $v' = 0$ : $v_\ell = \sqrt{g/c}$.

Un parachutiste à plat, en chute libre, atteint une vitesse limite d'environ $200$ km/h, soit à peu près $55$ m/s. On en déduit $c = \frac{g}{55^2} \approx 0{,}003\,24$ (en m−1). Avec un pas d'une seconde, chaque vitesse s'obtient en ajoutant la pente $g - c\,v^2$ à la précédente :

$$v_1 = 0 + (9{,}81 - c \times 0^2) = 9{,}81,$$ $$v_2 = 9{,}81 + (9{,}81 - c \times 9{,}81^2) \approx 19{,}31,$$ $$v_3 = 19{,}31 + (9{,}81 - c \times 19{,}31^2),$$

soit $v_3 \approx 27{,}91$, et ainsi de suite (avec un pas $h = 1$, multiplier la pente par $h$ ne la change pas).

La figure compare les deux modèles, avec la même vitesse limite, et la méthode d'Euler pour le second.

var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var petit = {fontSize: 11, useKatex: false, parse: false, fixed: true, highlight: false}; var ax = {strokeColor: '#455a64', strokeWidth: 1, fixed: true, highlight: false, lastArrow: true}; board.create('segment', [[0, 0], [20.6, 0]], ax); board.create('segment', [[0, 0], [0, 68]], ax); for (var t = 5; t <= 20; t += 5) { board.create('segment', [[t, 0], [t, -1.2]], {strokeColor: '#455a64', fixed: true, highlight: false}); board.create('text', [t - 0.5, -5, String(t)], petit); } for (var u = 20; u <= 60; u += 20) { board.create('segment', [[0, u], [-0.3, u]], {strokeColor: '#455a64', fixed: true, highlight: false}); board.create('text', [-2.6, u, String(u)], petit); } board.create('text', [-3.3, 71, 'v (m/s)'], petit); board.create('text', [18.4, -11, 't (s)'], opt); board.create('segment', [[0, 55], [20.4, 55]], {strokeColor: '#90a4ae', strokeWidth: 1, dash: 2, fixed: true, highlight: false}); var g = 9.81, vl = 55, cc = g / (vl * vl); board.create('functiongraph', [function (x) { return vl * (1 - Math.exp(-g * x / vl)); }, 0, 20.4], {strokeColor: '#607d8b', strokeWidth: 2, dash: 3, highlight: false}); board.create('functiongraph', [function (x) { var e = Math.exp(2 * g * x / vl); return vl * (e - 1) / (e + 1); }, 0, 20.4], {strokeColor: '#c62828', strokeWidth: 2, highlight: false}); var sh = board.create('slider', [[1, -21], [10, -21], [0.25, 1, 4]], {withLabel: false, snapWidth: 0.25}); function nombre(x, d) { return x.toFixed(d).replace('.', ','); } board.create('text', [11, -21, function () { return 'pas h = ' + nombre(sh.Value(), 2) + ' s'; }], opt); var c = board.create('curve', [[0], [0]], {strokeColor: '#1565c0', strokeWidth: 2, highlight: false}); c.updateDataArray = function () { var h = sh.Value(), X = [0], Y = [0], v = 0, k, n = Math.floor(20.4 / h); for (k = 1; k <= n; k++) { v = v + h * (g - cc * v * v); X.push(k * h); Y.push(v); } this.dataX = X; this.dataY = Y; }; board.create('text', [8, 26, 'rouge : frottement en v²'], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#c62828'}); board.create('text', [8, 18, 'gris : frottement en v'], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#607d8b'}); board.create('text', [8, 10, 'bleu : Euler, en v²'], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); La vitesse d'un parachutiste en chute libre pendant les $20$ premières secondes, pour une vitesse limite de $55$ m/s (en pointillés). Avec un frottement en $v^2$, la vitesse limite est approchée plus vite qu'avec un frottement en $v$. La ligne bleue est la méthode d'Euler pour le modèle en $v^2$, avec le pas réglé par le curseur : pour un grand pas, elle dépasse la vitesse limite puis oscille autour.

Avec un frottement en $v^2$, le parachutiste atteint $95\,\%$ de sa vitesse limite en une dizaine de secondes ; avec un frottement en $v$, il lui faudrait près de $17$ secondes. Les deux modèles donnent la même vitesse limite, mais pas la même chute.

Tout le saut, avec l'ouverture du parachute

Le programme suivant simule un saut depuis $4\,000$ m, avec ouverture de la voile à $1\,200$ m. La voile augmente brutalement le coefficient $c$ : la vitesse limite devient d'environ $5$ m/s ($18$ km/h). On calcule aussi l'altitude $z$, dont la dérivée est $-v$ : la méthode d'Euler s'applique aux deux grandeurs en même temps.

g = 9.81 h = 0.01 # pas de temps (s) t, v, z = 0, 0, 4000 # temps (s), vitesse (m/s), altitude (m) c = g / 55 ** 2 # chute libre : vitesse limite 55 m/s ouvert = False prochain = 0 while z > 0: if t >= prochain: print("t =", round(t), "s altitude :", round(z), "m vitesse :", round(v * 3.6), "km/h") prochain = prochain + 20 if z < 1200 and not ouvert: ouvert = True c = g / 5 ** 2 # voile ouverte : vitesse limite 5 m/s print("ouverture de la voile à t =", round(t), "s") v = v + h * (g - c * v * v) z = z - h * v t = t + h print("au sol après", round(t), "s, à", round(v * 3.6), "km/h")

On trouve une chute libre d'environ $55$ secondes et une descente sous voile de près de quatre minutes. Le modèle est simple : une voile réelle s'ouvre en quelques secondes et non d'un coup, et l'air est moins dense en altitude. C'est ce qui a permis à Felix Baumgartner, qui a sauté en 2012 d'un ballon à près de $39$ km d'altitude, de dépasser la vitesse du son en chute libre, à environ $1\,358$ km/h. Le pas compte aussi : avec $h = 0{,}1$ au lieu de $0{,}01$, le calcul de l'ouverture donne une vitesse négative absurde, car la pente est énorme à cet instant (on peut l'essayer dans le programme).

Le modèle logistique de Verhulst Une croissance qui ralentit

Le modèle $P' = rP$ décrit une population qui croît exponentiellement, sans limite. C'est réaliste au début (des bactéries dans une boîte de culture, une épidémie qui commence), mais pas longtemps : la nourriture et la place manquent. En 1838, le Belge Pierre-François Verhulst propose un modèle qui tient compte d'une population maximale $K$, appelée capacité d'accueil :

$$P' = rP\left(1 - \frac{P}{K}\right).$$

Tant que $P$ est petit devant $K$, le facteur $1 - \frac{P}{K}$ est proche de $1$ et la croissance est presque exponentielle. Quand $P$ approche $K$, ce facteur tend vers $0$ et la croissance s'arrête. Verhulst appliqua son modèle aux populations de la France, de la Belgique et de l'Angleterre ; il fut ensuite oublié, puis redécouvert dans les années 1920, notamment par les biologistes. Il décrit bien la croissance de certaines cultures de levures ou de bactéries, et sert en écologie et en épidémiologie.

La solution exacte

Cette équation contient un carré $\left(rP - \frac{r}{K}P^2\right)$ : elle n'est pas du type $y' = ay + b$. On peut pourtant vérifier qu'elle a une solution simple.

La fonction $P(t) = \dfrac{K}{1 + C\,\mathrm{e}^{-rt}}$ est solution, avec $C = \dfrac{K}{P_0} - 1$

Étape 1 : dériver. $P$ est de la forme $\frac{K}{u}$ avec $u(t) = 1 + C\,\mathrm{e}^{-rt}$, donc $u'(t) = -rC\,\mathrm{e}^{-rt}$ et

$$P'(t) = -\frac{K\,u'(t)}{u(t)^2} = \frac{rKC\,\mathrm{e}^{-rt}}{\left(1 + C\,\mathrm{e}^{-rt}\right)^2}.$$

Étape 2 : calculer le second membre. On a

$$1 - \frac{P}{K} = 1 - \frac{1}{1 + C\mathrm{e}^{-rt}},$$

donc, en réduisant au même dénominateur,

$$1 - \frac{P}{K} = \frac{C\,\mathrm{e}^{-rt}}{1 + C\,\mathrm{e}^{-rt}},$$

et, en multipliant par $rP = \dfrac{rK}{1 + C\,\mathrm{e}^{-rt}}$,

$$rP\left(1 - \frac{P}{K}\right) = \frac{rKC\,\mathrm{e}^{-rt}}{\left(1 + C\,\mathrm{e}^{-rt}\right)^2},$$

ce qui est exactement $P'(t)$.

Étape 3 : la condition initiale. $P(0) = \dfrac{K}{1 + C}$, et cela vaut $P_0$ si et seulement si $1 + C = \frac{K}{P_0}$, c'est-à-dire $C = \frac{K}{P_0} - 1$.

Comme $\mathrm{e}^{-rt}$ tend vers $0$ quand $t$ tend vers $+\infty$, $P(t)$ tend vers $K$ : la population se stabilise à la capacité d'accueil. La courbe a la forme d'un S, avec un point d'inflexion à la hauteur $\frac{K}{2}$, là où la croissance est la plus rapide.

Euler comparé à la solution exacte

Prenons $r = 0{,}5$ par jour, $K = 100$ (en milliers de bactéries, par exemple) et $P_0 = 5$, donc $C = 19$. La méthode d'Euler avec un pas $h$ s'écrit

$$P_{k+1} = P_k + h \times 0{,}5\,P_k\left(1 - \frac{P_k}{100}\right).$$
jour $t$$0$$2$$4$$6$$8$$10$$14$
Euler, $h = 1$$5$$10{,}8$$22{,}2$$41{,}5$$66{,}1$$86{,}0$$98{,}9$
exacte$5$$12{,}5$$28{,}0$$51{,}4$$74{,}2$$88{,}7$$98{,}3$

Avec un pas d'un jour, Euler retarde la croissance de près d'un jour, mais arrive au même palier. La figure permet d'augmenter le pas.

var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, fixed: true, highlight: false}; var petit = {fontSize: 11, useKatex: false, parse: false, fixed: true, highlight: false}; var ax = {strokeColor: '#455a64', strokeWidth: 1, fixed: true, highlight: false, lastArrow: true}; board.create('segment', [[0, 0], [41.5, 0]], ax); board.create('segment', [[0, 0], [0, 148]], ax); for (var t = 10; t <= 40; t += 10) { board.create('segment', [[t, 0], [t, -3]], {strokeColor: '#455a64', fixed: true, highlight: false}); board.create('text', [t - 1.5, -11, String(t)], petit); } for (var u = 50; u <= 100; u += 50) { board.create('segment', [[0, u], [-0.6, u]], {strokeColor: '#455a64', fixed: true, highlight: false}); board.create('text', [-6.5, u, String(u)], petit); } board.create('text', [37.5, -24, 't (j)'], opt); board.create('segment', [[0, 100], [41, 100]], {strokeColor: '#90a4ae', strokeWidth: 1, dash: 2, fixed: true, highlight: false}); board.create('functiongraph', [function (x) { return 100 / (1 + 19 * Math.exp(-0.5 * x)); }, 0, 41], {strokeColor: '#c62828', strokeWidth: 2, highlight: false}); var sh = board.create('slider', [[2, -40], [22, -40], [0.2, 1, 5.8]], {withLabel: false, snapWidth: 0.1}); function nombre(x, d) { return x.toFixed(d).replace('.', ','); } board.create('text', [24, -40, function () { return 'pas h = ' + nombre(sh.Value(), 1) + ' j'; }], opt); var c = board.create('curve', [[0], [0]], {strokeColor: '#1565c0', strokeWidth: 2, highlight: false}); c.updateDataArray = function () { var h = sh.Value(), X = [0], Y = [5], p = 5, k, n = Math.floor(41 / h); for (k = 1; k <= n; k++) { p = p + h * 0.5 * p * (1 - p / 100); X.push(k * h); Y.push(p); } this.dataX = X; this.dataY = Y; }; board.create('text', [1, 166, function () { return 'r × h = ' + nombre(0.5 * sh.Value(), 2); }], {fontSize: 12, useKatex: false, parse: false, fixed: true, highlight: false, color: '#1565c0'}); En rouge, la solution exacte du modèle logistique ($r = 0{,}5$, $K = 100$, $P_0 = 5$). En bleu, la méthode d'Euler avec le pas réglé par le curseur. Pour $r \times h$ supérieur à $1$, Euler dépasse la capacité d'accueil ; au-delà de $2$, il oscille sans se stabiliser ; vers $2{,}6$ et plus, ses valeurs deviennent désordonnées.

Avec un grand pas, la suite d'Euler ne ressemble plus du tout à la solution. On peut écrire $P_{k+1} = P_k + rh\,P_k\left(1 - \frac{P_k}{K}\right)$ : c'est une suite récurrente du type $u_{n+1} = f(u_n)$ avec $f$ un polynôme du second degré, la même famille que la célèbre suite logistique qui conduit au chaos. La solution exacte, elle, est parfaitement régulière : le désordre est créé par la méthode de calcul, pas par le phénomène.

Histoire et limites de la méthode Euler, 1768 À gauche, portrait au pastel de Leonhard Euler, en perruque et habit sombre ; à droite, page de titre en latin du premier volume des Institutionum calculi integralis, Saint-Pétersbourg, 1768. Leonhard Euler en 1753, et la page de titre du premier volume de son Calcul intégral (1768), où figure sa méthode d'intégration approchée. Portrait : Jakob Emanuel Handmann, Kunstmuseum de Bâle ; page de titre : bibliothèque numérique BEIC. Domaine public, Wikimedia Commons.

Leonhard Euler (1707-1783), né à Bâle, a travaillé à Saint-Pétersbourg puis à Berlin, avant de revenir en Russie. C'est l'un des auteurs les plus prolifiques de l'histoire des sciences ; il a continué à produire après avoir perdu la vue. On lui doit la notation $f(x)$, la lettre $\mathrm{e}$ et la diffusion du symbole $\pi$. Dans le premier volume de ses Institutionum calculi integralis (1768), il explique comment obtenir une solution approchée d'une équation différentielle en découpant l'intervalle en petits morceaux sur lesquels la pente est considérée comme constante. Il sait que la précision augmente quand on diminue les morceaux, mais ne le démontre pas : la preuve rigoureuse viendra au XIXe siècle, avec Cauchy.

L'idée de construire une courbe pas à pas en suivant une règle sur les tangentes a aussi servi aux ingénieurs. Pour la tour Eiffel, le profil a été déterminé par des méthodes graphiques, montant par montant, en respectant une règle sur les tangentes liée à l'action du vent, sans chercher d'équation : une démarche qui rappelle la méthode d'Euler.

Prévoir le temps

L'atmosphère obéit à des équations différentielles (vitesse du vent, pression, température, humidité en chaque point) que personne ne sait résoudre exactement. Pendant la Première Guerre mondiale, le Britannique Lewis Fry Richardson tente une prévision à la main, pas à pas, sur une région d'Europe : plusieurs semaines de calcul pour une prévision à six heures, et un résultat très faux, à cause des données initiales et du pas de temps. Il publie sa méthode en 1922 et imagine une « usine à prévisions » où des dizaines de milliers de calculateurs humains travailleraient ensemble. En 1950, la première prévision numérique est réalisée sur l'ordinateur ENIAC.

Aujourd'hui, les modèles de Météo-France découpent l'atmosphère en mailles de l'ordre du kilomètre et avancent par pas de quelques dizaines de secondes : des milliards de calculs du même esprit que la méthode d'Euler, mais avec des schémas plus précis. La difficulté n'est plus seulement la méthode : l'atmosphère est sensible aux conditions initiales (voir le texte sur la théorie du chaos), et une petite erreur de mesure finit par tout changer.

Un pas trop grand fait diverger

Le modèle logistique a montré qu'un grand pas peut créer des oscillations. Sur l'équation la plus simple, on peut le démontrer.

Pour $y' = -ky$ ($k > 0$), si $h > \frac{2}{k}$, la méthode d'Euler diverge

Étape 1. La méthode donne $y_{n+1} = y_n - hk\,y_n = (1 - kh)\,y_n$ : la suite est géométrique de raison $q = 1 - kh$, donc $y_n = y_0\,q^n$.

Étape 2. Si $h > \frac{2}{k}$, alors $kh > 2$, donc $q < -1$ et $|q| > 1$. Alors $|y_n| = |y_0|\,|q|^n$ tend vers $+\infty$ (pour $y_0 \neq 0$), en changeant de signe à chaque pas.

Étape 3. Or la solution exacte $y_0\,\mathrm{e}^{-kx}$ tend vers $0$ : la méthode donne un résultat complètement faux. Pour $\frac{1}{k} < h < \frac{2}{k}$, la suite tend vers $0$ mais change de signe à chaque pas, ce qui n'a pas de sens physique ; il faut $h < \frac{1}{k}$ pour une suite positive et décroissante.

Pour le café $(k = 0{,}05)$, il faudrait un pas de plus de $40$ minutes pour voir ce défaut. Mais certains phénomènes combinent des évolutions très rapides et très lentes (des réactions chimiques, des circuits électroniques) : le pas imposé par la plus rapide rend le calcul de la plus lente interminable. On les appelle des équations raides, et l'on utilise pour elles d'autres méthodes.

La plus célèbre des améliorations est la méthode de Runge-Kutta (Carl Runge en 1895, Wilhelm Kutta en 1901) : à chaque pas, au lieu d'une seule pente, on en calcule quatre (au début, deux fois au milieu, à la fin) et l'on en fait une moyenne pondérée. Elle est d'ordre 4 : diviser le pas par $10$ divise l'erreur par environ $10\,000$.

La méthode d'Euler dans d'autres textes

La méthode d'Euler apparaît dans plusieurs autres textes de ce site, chaque fois sur un problème réel :

Les limites des modèles Des directions pour construire sa question

Ce texte n'est pas un Grand Oral. Il rassemble des connaissances dans lesquelles chacun peut choisir une direction, la creuser et formuler sa propre question. Quelques directions possibles :

Pour l'échange avec le jury : les notions du cours à maîtriser

Le jury peut interroger sur les chapitres de spécialité mobilisés. Avec ce thème, il est utile de connaître parfaitement : les équations différentielles $y' = ay$ et $y' = ay + b$ et leurs solutions ; le nombre dérivé, la tangente et son équation ; la dérivation (quotient, composée avec l'exponentielle) ; les fonctions exponentielle et logarithme ; les suites géométriques et leur limite ; la convexité ; les boucles en Python.

Pour réviser ces chapitres, l'application Maths FlashBac reprend tout le cours de spécialité en cartes.

Pour aller plus loin