TP 4 : Résolution d’équation différentielle par la méthode d’Euler
Contents
TP 4 : Résolution d’équation différentielle par la méthode d’Euler#
La méthode d’Euler permet d’approximer une solution d’une équation différentielle.
Dans le TP, nous nous restreignons à une équation différentielle d’ordre, c’est-à-dire où seules apparaissent des dérivées premières.
Commencez par importer les modules nécessaires :
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["figure.figsize"] = (15, 8)
Équation différentielle d’ordre 1#
Cadre général#
Considérons une équation différentielle d’ordre 1 :
est la fonction inconnue : on cherche à détermine la valeur de pour , où est l’intervalle de définition de . est l’expression qui apparaît dans le second membre de l’équation différentielle, qui peut utiliser et (d’où une fonction de variables). est la condition initiale, garantissant l’unicité de la solution (théorème de Cauchy).
On cherche donc une fonction
Exemples d’équations différentielles#
Voici des exemples d’équations différentielles classiques avec la valeur correspondante de
Équation différentielle |
Second membre |
Solution |
---|---|---|
|
||
|
||
|
Exercice
Quelle fonction
def f(t, y):
return ... # utiliser y plutôt que y(t) ici
Solution
def f(t, y):
return t**3 - y**3
Méthode d’Euler#
Théorie#
La méthode d’Euler calcule des approximations de
Soit
Alors, par développement limité d’ordre
Comme
Ainsi, on peut approximer
De même, on peut approximer
Où
Remarque : Cette dernière formule n’est autre que l’expression bien connue en physique
Illustration#
On obtient chaque point d’approximation en se déplaçant de
Click to show
def f(t, y):
return np.cos(t)*t - 0.5
def arrow(p1, p2, double=False):
a = "<->" if double else "-|>"
plt.annotate("",
xytext=p1,
xy=p2,
arrowprops=dict(arrowstyle=f"{a},head_width=.5,head_length=1.5",
shrinkA=0,shrinkB=0))
t = [0]
y = [2]
h = 0.3
plt.axis([-0.1, 2.5, 0, 2.7])
for _ in range(10):
t.append(t[-1] + h)
y.append(y[-1] + h*f(t[-1], y[-1]))
arrow((t[-2], y[-2]), (t[-1], y[-1]))
plt.scatter(t, y, s=150)
for i in range(len(t) - 1):
plt.annotate(f"$y_{i}$", (t[i] - 0.025, y[i] + 0.1), fontsize=20)
plt.plot((t[2], t[2]), (0, y[2]), '--')
plt.plot((t[3], t[3]), (0, y[3]), '--')
plt.annotate("$t_2$", (t[2]-.08, 0.05), fontsize=20)
plt.annotate("$t_3$", (t[3]+.02, 0.05), fontsize=20)
plt.annotate(f"$y_{i}$", (t[i] - 0.025, y[i] + 0.1), fontsize=20)
arrow((t[2], 1), (t[3], 1), True)
plt.annotate("$h$", (t[2] + .4*h, 1.1), fontsize=20)
plt.show()

Programmation#
On calcule les approximations for
.
Les approximations
Voici un exemple d’équation différentielle avec le calcul des approximations par la méthode d’Euler :
y = [1] # la première approximation est la condition initiale
t = [0] # temps initial
h = 0.01 # pas d'approximation
n = 200 # nombre d'approximations
for k in range(n):
t.append(t[-1] + h)
y.append(y[-1] + h*y[-1]) # équation de récurrence
En fait, on connaît la solution exacte de l’équation différentielle :
y[50] # approximation de exp(50*h) = exp(0.5)
1.644631821843882
np.exp(0.5)
1.6487212707001282
L’approximation est effectivement assez proche de la solution. Plus
Exercice
Quelle approximation de
Solution
print("approximation : ", y[100])
print("vraie valeur : ", np.exp(1))
On a calculé
Exercice
Quel
Solution
Le dernier temps d’approximation est
Exercice
De manière générale, donner la valeur de
Solution
Affichage des approximations#
On peut afficher l’approximation obtenue, et la comparer avec la fonction exponentielle :
plt.plot(t, y, label="Méthode d'Euler")
plt.plot(t, np.exp(t), label="exp")
plt.legend()
plt.show()

Note
Si x
et y
sont deux listes, plt.plot(x, y)
relie les points dont les abscisses sont dans x
et les ordonnées dans y
, ce qui revient à afficher y
en fonction de x
.
Exercice
Afficher la courbe d’une soluton approchée de
Solution
y = [1]
t = [0]
h = 0.01
n = 300 # on choisit n pour que n*h = 3
for k in range(n):
t.append(t[-1] + h)
y.append(y[-1] + h*y[-1]) # équation de récurrence
plt.plot(t, y, label="Méthode d'Euler")
plt.plot(t, np.exp(t), label="exp")
plt.legend()
plt.show()
<Figure size 1500x800 with 1 Axes>
Exercice
Résoudre de façon approchée l’équation différentielle ci-dessous, sur
On pourra adapter le code précédent ci-dessous.
Vous devez obtenir un dessin ressemblant à :
y = [...] # on met initialement la condition initiale
t = [...] # temps initial
h = 0.01 # pas d'approximation
n = ... # nombre d'approximations
for k in range(n):
t.append(t[-1] + h)
y.append(y[-1] + h*...) # équation de récurrence, où il faut remplacer ... par le membre droit de l'équa diff
Solution
y = [-3]
t = [-1]
h = 0.01
n = 500
for k in range(n):
t.append(t[-1] + h)
y.append(y[-1] + h*(t[-1]**3 - y[-1]**3))
plt.plot(t, y)
plt.show()
<Figure size 1500x800 with 1 Axes>
Méthode d’Euler générique#
La fonction suivante permet d’appliquer la méthode d’Euler avec les paramètres suivants :
f
: fonction apparaissant dans le membre droit de l’équation différentielle.t0
: temps initial.y0
: valeur de la solution ent0
(condition initiale).h
: pas de l’approximation.n
: nombre d’approximations à calculer.
def euler(f, t0, y0, h, n):
y = [y0]
t = [t0]
for k in range(n):
t.append(t[-1] + h)
y.append(y[-1] + h*f(t[-1], y[-1]))
return t, y
f
doit être définie comme une fonction classique en Python (avec def ...
). On peut passer une fonction en argument à une autre fonction.
Par exemple, pour approcher une solution de euler
:
def f(t, y):
return y
t, y = euler(f, 0, 1, 0.1, 10)
plt.plot(t, y)
plt.show()

Exercice
Dessiner des approximations de l’équation
On pourra utiliser euler
dans une boucle for
avec différentes valeurs de y_0
et utiliser plt.show()
une seule fois, à la fin (après le for
). Par exemple :
for y0 in [-3, -2, 0, 4]:
... # méthode d'Euler avec y0 comme condition initiale
Vous devez obtenir ce genre de dessin :
Solution
def f(t, y):
return t**3 - y**3
for y0 in [-3, -2, 0, 4]:
t, y = euler(f, -1, y0, 0.01, 500)
plt.plot(t, y)
plt.show()
<Figure size 1500x800 with 1 Axes>
Système d’équations différentielles#
Il est également possible de résoudre un système d’équation différentielles.
Réactions chimiques#
Par exemple, considérons deux réactions chimiques d’ordre 1 :
$
Les concentrations au cours du temps vérifient :
Dans ce cas, on applique la méthode d’Euler sur chaque équation différentielle :
h = 0.05
t = [0]
A = [1]
B = [0]
C = [0]
for k in range(100): # approximations sur [0, 5]
t.append(t[k] + h)
A.append(A[k] + h*(-A[k])) # application de la méthode d'Euler sur chaque équation
B.append(B[k] + h*(A[k] - B[k]))
C.append(C[k] + h*B[k])
plt.plot(t, A, 'r', label="[A]")
plt.plot(t, B, 'b', label="[B]")
plt.plot(t, C, 'g', label="[C]")
plt.legend()
plt.show()

Exercice
Interpréter le dessin ci-dessus.
Solution
La concentration de A diminue puisque A se transforme en B.
B augmente initialement (résultant de la production à partir de A) mais diminue ensuite (car se transforme en C).
À la fin, il n’y a plus que du C.
Évolution de population (Lokta-Volterra)#
Le système différentiel de Lotka-Volterra permet de modéliser l’évolution conjointe de populations de proies et de prédateurs :
: la population de proies au temps ; : la population de prédateurs au temps ; : le taux de reproduction des proies indépendamment des prédateurs rencontrés; : le taux de mortalité des proies dues aux prédateurs rencontrés; : le taux de mortalité des prédateurs indépendamment du nombre de proies : le taux de reproduction des prédateurs en fonction des proies mangées.
Exercice
Écrire les équations de récurrences vérifiées par les approximations
et de la méthode d’Euler, appliquée au système différentiel ci-dessus.Écrire des instructions Python pour stocker dans des listes
t
,x
ety
ces , et . On choisira l’intervalle de temps et le nombre d’approximations judicieusement et on prendra .Afficher
en fonction de et interpréter.Afficher
en fonction de et en fonction de , sur le même dessin et interpréter.Essayer de modifier les constantes
, …
Solution
a = b = c = d = 1
x = [1]
y = [2]
t = [0]
h = 0.01
for k in range(2000):
t.append(t[-1] + h)
x.append(x[-1] + h*x[-1]*(a - b*y[-1]))
y.append(y[-1] + h*y[-1]*(c*x[-1] - d))
plt.plot(t, x)
plt.plot(t, y)
plt.show()
<Figure size 1500x800 with 1 Axes>
Équation du second ordre#
Pour résoudre une équation différentielle d’ordre 2 du type
Par exemple, calculons une solution approchée de l’équation du pendule linéarise :
Cette équation est du second ordre, donc on ne peut pas appliquer directement la méthode d’Euler.
Par contre, si on pose pendule
) on peut réécrire cette équation du second ordre comme deux équations du premier ordre :
On applique alors la méthode d’Euler sur chaque équation, comme dans la section précédente :
h = 0.01
theta = [0]
z = [1]
t = [0]
for k in range(1000):
t.append(t[k] + h)
theta.append(theta[k] + h*z[k])
z.append(z[k] - h*theta[k])
plt.plot(t, theta)
plt.show()

Exercice
Quelle est la courbe obtenue ?
Solution
On sait résoudre l’équation différentielle : les solutions sont de la forme
Comme
Comme
Donc
Exercice
Adapter la résolution ci-dessus pour l’équation du pendule non-linéarise
Solution
h = 0.005
theta = [0]
z = [1]
t = [0]
for k in range(10000):
t.append(t[k] + h)
theta.append(theta[k] + h*z[k])
z.append(z[k] - h*np.sin(theta[k])) # changement
plt.plot(t, theta)
plt.show()
<Figure size 1500x800 with 1 Axes>