USMA1Q — Méthodes Numériques¶
Séance 10 — Équations différentielles ordinaires I : fondamentaux¶
Conservatoire National des Arts et Métiers
01 Avril 2026
nicholas-anton.collins-craft@enpc.fr
Un lien vers Google Colab qui peut faire tourner le notebook qui contient les exercices se trouve ici :
https://colab.research.google.com/github/nickcollins-craft/USMA1Q-Methodes-Numeriques/blob/main/
Plan du cours¶
| Jour | Sujet |
|---|---|
| 03 mars | Fondamentaux de la programmation en Python |
| 04 mars (matin) | Fonctions, listes approfondies, fichiers et graphiques |
| 04 mars (après-midi) | Calcul numérique avec NumPy |
| 11 mars (matin) | Tableaux en mémoire, matrices & précision numérique |
| 11 mars (après-midi) | Résolution des systèmes linéaires |
| 18 mars (matin) | Interpolation & recherche des racines |
| 18 mars (après-midi) | Systèmes d'équations non linéaires |
| 25 mars (matin) | Intégration numérique I |
| 25 mars (après-midi) | Intégration numérique II (Monte Carlo) |
| 01 avril (matin) | Équations différentielles ordinaires I |
| 01 avril (après-midi) | Équations différentielles ordinaires II |
| 08 avril | Examen |
Plan de la séance (indicatif)¶
| Horaire | Sujet |
|---|---|
| 0:00 – 0:55 | Méthode d'Euler (explicite) |
| 0:55 – 1:50 | Méthodes de Runge-Kutta (RK2, RK4) |
| 1:50 – 2:00 | ☕ Pause |
| 2:00 – 2:30 | Pas adaptatif & scipy.integrate.solve_ivp |
| 2:30 – 3:40 | Stabilité : méthodes explicites vs implicites |
| 3:40 – 3:45 | Récapitulatif |
Motivation — pourquoi résoudre des EDO numériquement ?¶
De nombreux phénomènes en science des matériaux sont décrits par des équations différentielles ordinaires (EDO) :
| Phénomène | Équation différentielle |
|---|---|
| Refroidissement (loi de Newton) | \(\frac{\mathrm{d}T}{\mathrm{d}t} = -k(T - T_{\text{env}})\) |
| Cinétique de transformation (Avrami) | \(\frac{\mathrm{d}\xi}{\mathrm{d}t} = n k t^{n-1}(1-\xi)\) |
| Fluage (loi puissance) | \(\frac{\mathrm{d}\varepsilon}{\mathrm{d}t} = A\sigma^n e^{-Q/(RT)}\) |
| Oscillateur amorti | \(m\frac{\mathrm{d}^2x}{\mathrm{d}t^2} + c\frac{\mathrm{d}x}{\mathrm{d}t} + kx = 0\) |
Problème : la plupart de ces équations n'ont pas de solution analytique simple.
Il faut donc les résoudre numériquement.
Forme générale d'une EDO¶
Problème de valeur initiale (IVP — Initial Value Problem) :
$$\frac{\mathrm{d}y}{\mathrm{d}t} = f(t, y), \quad y(t_0) = y_0$$
- $y(t)$ : fonction inconnue (température, fraction transformée, déformation...)
- $f(t, y)$ : la dérivée de $y$ en fonction de $t$ et $y$ elle-même
- $y_0$ : condition initiale
Objectif : calculer $y(t)$ pour $t \in [t_0, t_f]$
1 · Méthode d'Euler (explicite)¶
Idée : approximer la dérivée par une différence finie, puis avancer pas à pas.
$$\frac{\mathrm{d}y}{\mathrm{d}t} \approx \frac{y_{n+1} - y_n}{h}$$
où $h$ est le pas de temps (time step), $y_{n}$ est la valeur actuelle, et $y_{n+1}$ est la valeur qu'on cherche.
En remplaçant dans l'EDO :
$$\frac{y_{n+1} - y_n}{h} = f(t_n, y_n)$$
d'où la formule d'Euler explicite :
$$\boxed{y_{n+1} = y_n + h \cdot f(t_n, y_n)}$$

Exemple 1 : loi de refroidissement de Newton¶
Une pièce en acier refroidit depuis 800°C dans l'air à 25°C :
$$\frac{\mathrm{d}T}{\mathrm{d}t} = -k(T - T_{\text{env}}), \quad T(0) = 800\,\text{°C}$$
avec $k = 0.05\,\text{s}^{-1}$ et $T_{\text{env}} = 25\,\text{°C}$.
La solution analytique (qui permettre d'évaluer l'exactitude de notre solution numérique) :
$$T(t) = T_{\text{env}} + (T_0 - T_{\text{env}})e^{-kt} = 25 + 775\,e^{-0.05t}$$
import numpy as np
import matplotlib.pyplot as plt
# Paramètres
k = 0.05 # s^-1
T_env = 25.0 # °C
T0 = 800.0 # °C
# EDO : dT/dt = f(t, T)
def f_cooling(t, T):
return -k * (T - T_env)
# Solution analytique
def T_exact(t):
return T_env + (T0 - T_env) * np.exp(-k * t)
Implémentation de la méthode d'Euler¶
def euler_method(f, t0, tf, y0, h):
N = int((tf - t0) / h) + 1 # Nombre de points dans la grille
t = np.linspace(t0, tf, N) # Grille de temps
y = np.zeros(N) # Tableau pour stocker les solutions numériques
y[0] = y0 # Condition initiale
# Pour chaque point de la grille, calculer la solution numérique
for n in range(N - 1):
y[n + 1] = y[n] + h * f(t[n], y[n])
return t, y
# Résolution avec différents pas de temps
t0, tf = 0, 100 # secondes
t_euler_1, T_euler_1 = euler_method(f_cooling, t0, tf, T0, 1)
t_euler_5, T_euler_5 = euler_method(f_cooling, t0, tf, T0, 5)
t_euler_20, T_euler_20 = euler_method(f_cooling, t0, tf, T0, 20)

Observations¶
- Petit $h$ (h = 1 s) → solution proche de l'exacte, mais nombreuses étapes
- Grand $h$ (h = 20 s) → rapide mais erreur visible, la solution dérive
Compromis vitesse–précision : faut-il toujours choisir un $h$ très petit ?
L'erreur locale — l'erreur fait à chaque pas¶
Développement de Taylor de la vraie solution¶
Si on connaît $y(t_n)$ et qu'on veut calculer $y(t_{n+1}) = y(t_n + h)$, le développement de Taylor nous dit :
$$y(t_n + h) = y(t_n) + h \cdot y'(t_n) + \frac{h^2}{2} \cdot y''(t_n) + \frac{h^3}{6} \cdot y'''(t_n) + \ldots$$
Comme $y'(t_n) = f(t_n, y(t_n))$ (par définition de l'EDO), on peut réécrire :
$$y(t_n + h) = y(t_n) + h \cdot f(t_n, y(t_n)) + \frac{h^2}{2} \cdot y''(t_n) + \mathcal{O}(h^3)$$
Ce que fait Euler¶
La méthode d'Euler calcule :
$$y_{n+1}^{\text{Euler}} = y_n + h \cdot f(t_n, y_n)$$
Elle utilise seulement les deux premiers termes du développement de Taylor !
L'erreur de troncature locale¶
En comparant les deux :
$$\text{Erreur locale} = y(t_n + h) - y_{n+1}^{\text{Euler}} = \frac{h^2}{2} \cdot y''(t_n) + \mathcal{O}(h^3)$$
Le terme dominant est $\frac{h^2}{2} y''(t_n)$, donc l'erreur locale est $\mathcal{O}(h^2)$.
Interprétation géométrique¶
- Euler approxime par une droite : $y \approx y_n + h \cdot (\text{pente})$
- La vraie solution suit une parabole (au moins) : $y \approx y_n + h \cdot (\text{pente}) + \frac{h^2}{2} \cdot (\text{courbure})$
Intuition clé : Euler ignore la courbure de la solution (le terme en $y''$). Plus le pas $h$ est grand, plus cette approximation linéaire s'éloigne de la vraie courbe. L'écart grandit comme l'aire sous la parabole d'erreur, d'où le facteur $h^2$.
Note : C'est pour ça qu'on dit qu'Euler est une méthode d'ordre 1 : elle utilise un développement de Taylor d'ordre 1 (constant + linéaire), et l'erreur vient du premier terme négligé, qui est d'ordre 2.

L'erreur globale — l'erreur cumulée sur tout l'intervalle $[t_0, t_f]$¶
Pour aller de $t_0$ à $t_f$, on doit faire $N = (t_f - t_0)/h$ pas. Les erreurs locales s'accumulent :
$$\text{Erreur globale} \approx N \times \text{(erreur locale)} \approx \frac{t_f - t_0}{h} \times h^2 = (t_f - t_0) \times h$$
Donc l'erreur globale est $\mathcal{O}(h)$ — ordre 1.
Conséquence pratique : si on divise $h$ par 2, on fait deux fois plus de pas, mais chaque pas est quatre fois plus précis → l'erreur globale est divisée par 2.
Convergence empirique¶
Vérification : traçons $\log(\text{erreur})$ en fonction de $\log(h)$.
Si l'erreur globale suit $\text{erreur} \approx C \times h$, alors : $$\log(\text{erreur}) = \log(C) + \log(h)$$
On doit obtenir une droite de pente 1 en échelle log-log.
# Calcul de l'erreur pour différents h
h_range = np.array([20, 10, 5, 2, 1, 0.5, 0.2])
errors = []
for h in h_range:
t_euler, T_euler = euler_method(f_cooling, t0, tf, T0, h)
T_exact_at_tf = T_exact(tf)
error = abs(T_euler[-1] - T_exact_at_tf)
errors.append(error)
errors = np.array(errors)

À vous de faire les exercices 1.1 et 1.2 !¶
2 · Méthodes de Runge-Kutta¶
Problème avec Euler : erreur globale $\mathcal{O}(h)$ — il faut un $h$ très petit pour être précis.
Idée des méthodes de Runge-Kutta : évaluer la pente $f(t, y)$ en plusieurs points dans l'intervalle $[t_n, t_{n+1}]$, puis faire une moyenne pondérée.
Cela améliore considérablement la précision !
Méthode du point milieu (RK2)¶
Au lieu d'utiliser la pente au début de l'intervalle, utilisons la pente au milieu :
Calculer un demi-pas d'Euler pour estimer $y$ au milieu : $$y_{\text{mid}} = y_n + \frac{h}{2}f(t_n, y_n)$$
Évaluer la pente au milieu : $$k_2 = f\left(t_n + \frac{h}{2}, y_{\text{mid}}\right)$$
Avancer d'un pas complet avec cette pente : $$\boxed{y_{n+1} = y_n + h \cdot k_2}$$
def rk2_method(f, t0, tf, y0, h):
"""
Résolution d'une EDO par la méthode de Runge-Kutta d'ordre 4.
"""
N = int((tf - t0) / h) + 1
t = np.linspace(t0, tf, N)
y = np.zeros(N)
y[0] = y0
for n in range(N - 1):
k1 = f(t[n], y[n])
k2 = f(t[n] + h/2, y[n] + h/2 * k1)
y[n + 1] = y[n] + h * k2
return t, y
Analyse d'erreur de RK2 (méthode du point milieu)¶
Pourquoi RK2 est-il plus précis qu'Euler ?¶
Rappel Euler : on utilise la pente au début de l'intervalle → erreur $\mathcal{O}(h^2)$ par pas
RK2 (point milieu) : on utilise la pente au milieu de l'intervalle → erreur $\mathcal{O}(h^3)$ par pas
L'intuition géométrique¶
Imaginez que vous voulez approximer une courbe :
- Euler : trace une droite depuis le point de départ avec la pente initiale
- RK2 : fait d'abord un petit saut au milieu pour "tester" la pente là-bas, puis utilise cette pente centrale
La pente au milieu de l'intervalle représente mieux la pente moyenne sur tout l'intervalle !

Erreur locale vs globale¶
Erreur de troncature locale : $\mathcal{O}(h^3)$ par pas
En utilisant la pente au point milieu, on capture mieux la courbure de la solution. L'erreur diminue comme $h^3$ au lieu de $h^2$.
Erreur globale : $\mathcal{O}(h^2)$
Sur l'intervalle $[t_0, t_f]$, il faut $N = (t_f - t_0)/h$ pas :
$$\text{Erreur globale} \approx N \times \text{(erreur locale)} \approx \frac{t_f - t_0}{h} \times h^3 = (t_f - t_0) \times h^2$$
Conséquence pratique : si on divise $h$ par 2, l'erreur est divisée par 4 !
C'est beaucoup mieux qu'Euler (division par 2 seulement).
Méthode de Runge-Kutta d'ordre 4 (RK4)¶
La méthode RK4 classique évalue la pente en quatre points :
$$\begin{align} k_1 &= f(t_n, y_n) \\ k_2 &= f\left(t_n + \frac{h}{2}, y_n + \frac{h}{2}k_1\right) \\ k_3 &= f\left(t_n + \frac{h}{2}, y_n + \frac{h}{2}k_2\right) \\ k_4 &= f(t_n + h, y_n + h k_3) \end{align}$$
Puis calcule une moyenne pondérée :
$$\boxed{y_{n+1} = y_n + \frac{h}{6}(k_1 + 2k_2 + 2k_3 + k_4)}$$
Avec le même logique d'analyse qu'avant, on obtient que le RK4 prends en compte des termes d'ordre supérieure, donc l'erreur locale devient $\mathcal{O}(h^{5})$. Par conséquence, l'erreur globale est $\mathcal{O}(h^4)$ — très précis !
Implémentation de RK4¶
def rk4_method(f, t0, tf, y0, h):
"""
Résolution d'une EDO par la méthode de Runge-Kutta d'ordre 4.
"""
N = int((tf - t0) / h) + 1
t = np.linspace(t0, tf, N)
y = np.zeros(N)
y[0] = y0
for n in range(N - 1):
k1 = f(t[n], y[n])
k2 = f(t[n] + h/2, y[n] + h/2 * k1)
k3 = f(t[n] + h/2, y[n] + h/2 * k2)
k4 = f(t[n] + h, y[n] + h * k3)
y[n + 1] = y[n] + (h / 6) * (k1 + 2*k2 + 2*k3 + k4)
return t, y

Comparaison Euler vs RK2 vs RK4¶
# Résolution avec le même pas de temps h = 10 s
h = 10
t_euler, T_euler = euler_method(f_cooling, t0, tf, T0, h)
t_rk2, T_rk2 = rk2_method(f_cooling, t0, tf, T0, h)
t_rk4, T_rk4 = rk4_method(f_cooling, t0, tf, T0, h)
print("Erreur Euler :", abs(T_euler[-1] - T_exact(tf)))
print("Erreur RK4 :", abs(T_rk4[-1] - T_exact(tf)))
Erreur Euler : 4.465072986791238 Erreur RK4 : 0.020714566028654957

Observation¶
Avec le même nombre de pas ($h = 10$ s), RK4 est très proche de la solution exacte et RK2 est peu éloigné alors qu'Euler dévie nettement.
Règle pratique : RK4 est le « cheval de bataille » pour les problèmes lisses. Pour une précision donnée, il nécessite beaucoup moins de pas qu'Euler.
À vous de faire les exercices 2.1 et 2.2 !¶
☕ Pause — 10 minutes¶
3 · Pas adaptatif et scipy.integrate.solve_ivp¶
Problème : choisir $h$ à la main est délicat.
- Trop grand → erreur importante
- Trop petit → calcul lent, inutilement précis
Solution : pas adaptatif — ajuster automatiquement $h$ en surveillant l'erreur.
Méthodes à pas adaptatif¶
Stratégie : comparer deux estimations de $y_{n+1}$ calculées avec des méthodes d'ordres différents.
Exemple : RK45 (Dormand-Prince)
- Calcule $y_{n+1}$ avec une méthode RK d'ordre 4 et une d'ordre 5
- Utilise les mêmes évaluations de fonction pour les deux
- Différence entre les deux = estimation de l'erreur
Si erreur > tolérance → réduire $h$
Si erreur < tolérance → augmenter $h$
scipy.integrate.solve_ivp¶
Python fournit un solveur d'EDO moderne avec pas adaptatif :
from scipy.integrate import solve_ivp
sol = solve_ivp(f, [t0, tf], [y0], method='RK45', rtol=1e-6, atol=1e-9, dense_output=True)
Paramètres importants :
f(t, y): fonction définissant $\mathrm{d}y/\mathrm{d}t = f(t, y)$[t0, tf]: intervalle de temps[y0]: condition initiale (toujours un array !)method:'RK45','RK23','Radau','BDF', etc.rtol,atol: tolérances relative et absoluedense_output=True: interpolation continue de la solution
Exemple avec solve_ivp¶
from scipy.integrate import solve_ivp
# Résolution du refroidissement avec solve_ivp
sol = solve_ivp(f_cooling, [t0, tf], [T0], method='RK45',
rtol=1e-6, atol=1e-9, dense_output=True)
print("Nombre de pas utilisés :", len(sol.t))
print("Temps final :", sol.t[-1])
print("T finale (numérique) :", sol.y[0, -1])
print("T finale (exacte) :", T_exact(tf))
print("Erreur :", abs(sol.y[0, -1] - T_exact(tf)))
Nombre de pas utilisés : 23 Temps final : 100.0 T finale (numérique) : 30.22192017312949 T finale (exacte) : 30.221908924291238 Erreur : 1.1248838251987081e-05

Observation¶
solve_ivpajuste automatiquement $h$ : au début (où $T$ change rapidement), les pas sont petits- Plus tard (où $T$ évolue lentement), les pas sont grands
- Cela optimise précision et vitesse sans intervention manuelle
Interpolation dense de la solution¶
Avec dense_output=True, on obtient une fonction sol.sol(t) qui interpole la solution entre les pas.
# Évaluer la solution à des temps arbitraires
t_dense = np.linspace(t0, tf, 1000)
T_dense = sol.sol(t_dense)[0]

À vous de faire les exercices 3.1 et 3.2 !¶
4 · Stabilité : méthodes explicites vs implicites¶
Pourquoi ne pas toujours utiliser RK4 avec un grand $h$ ?
Certaines EDO sont raides (stiff) — les méthodes explicites deviennent instables si $h$ est trop grand.
Exemple d'instabilité¶
Considérons :
$$\frac{\mathrm{d}y}{\mathrm{d}t} = -1000\,y, \quad y(0) = 1$$
Solution exacte : $y(t) = e^{-1000t}$ — décroissance très rapide.
Essayons Euler avec $h = 0.003$ s :
# EDO raide
lam = -1000
def f_stiff(t, y):
return lam * y
# Euler avec h = 0.003
t0_stiff, tf_stiff = 0, 0.01
y0_stiff = 1.0
h_unstable = 0.003
t_unstable, y_unstable = euler_method(f_stiff, t0_stiff, tf_stiff, y0_stiff, h_unstable)
print("y(tf) numérique :", y_unstable[-1])
print("y(tf) exact :", np.exp(lam * tf_stiff))
y(tf) numérique : -8.0 y(tf) exact : 4.5399929762484854e-05

Que se passe-t-il ?¶
La méthode d'Euler explose ! Les valeurs oscillent et divergent.
Raison : Euler explicite a une région de stabilité limitée.
Pour $\frac{\mathrm{d}y}{\mathrm{d}t} = \lambda y$, Euler est stable seulement si :
$$|1 + h\lambda| < 1$$
Pour $\lambda = -1000$, il faut $h < 0.002$ s.
Notons que le pas $h$ qu'il faut pour la stabilité ne garantie pas que la solution est precise, seulement qu'elle n'explose pas.
# Avec h = 0.001 (stable)
h_stable = 0.001
t_stable, y_stable = euler_method(f_stiff, t0_stiff, tf_stiff, y0_stiff, h_stable)
t_exact_stiff = np.linspace(t0_stiff, tf_stiff, 500)
y_exact_stiff = np.exp(lam * t_exact_stiff)

Problèmes raides (stiff)¶
Un problème est raide quand il contient des échelles de temps très différentes :
- Des phénomènes rapides (transitoires)
- Des phénomènes lents (évolution à long terme)
Les méthodes explicites (Euler, RK4) sont inefficaces : elles nécessitent $h$ très petit pour rester stables, même quand la solution évolue lentement.
Solution : méthodes implicites.
Méthode d'Euler implicite (backward)¶
Au lieu d'évaluer $f$ au point $n$ (connu), on l'évalue au point $n+1$ (inconnu) :
$$\boxed{y_{n+1} = y_n + h \cdot f(t_{n+1}, y_{n+1})}$$
C'est une équation implicite pour $y_{n+1}$ — il faut la résoudre à chaque pas !
Avantage : stable pour tout $h$ (A-stable). Permet d'utiliser des pas plus grands sur les problèmes raides.
Inconvénient : plus coûteux par pas (résolution d'équation non linéaire).

Implémentation d'Euler implicite¶
Pour une fonction non linéaire, on est obligé d'utiliser une méthode itérative (comme Newton-Raphson) à chaque pas (pourquoi on a étudié telles méthodes !).
def euler_backward(f, t0, tf, y0, h, tol=1e-8, max_iter=50):
N = int((tf - t0) / h) + 1 # Nombre de points dans la grille
t = np.linspace(t0, tf, N) # Grille de temps
y = np.zeros(N) # Tableau pour stocker les solutions numériques
y[0] = y0 # Condition initiale
eps = 1e-8 # Utilise différences finies pour approximer la dérivée du résidu
for n in range(N - 1):
y_new = y[n] + h * f(t[n], y[n]) # Prédiction initiale (Euler explicite)
# Newton-Raphson : résout g(y_{n+1}) = y_{n+1} - y_n - h*f(t_{n+1}, y_{n+1}) = 0
for iteration in range(max_iter): # Fait des itérations de Newton-Raphson
g = y_new - y[n] - h * f(t[n + 1], y_new) # Résidu
# Dérivée de g par rapport à y_new g'(y) = 1 - h*f'(y), où f'(y) est la derivée de f par rapport à y_new
f_y = (f(t[n + 1], y_new + eps) - f(t[n + 1], y_new)) / eps # Approximation avec différences finies
g_prime = 1 - h * f_y
# Mise à jour de y_new avec la formule de Newton-Raphson
y_new = y_new - g / g_prime
# Si le résidu est suffisamment petit, on peut arrêter les itérations
if abs(g) < tol:
break
# Enregistre la solution et passe au point suivant
y[n + 1] = y_new
return t, y
# Résolution avec Euler implicite, h = 0.005 (plus grand que la limite de stabilité explicite)
h_backward = 0.005
t_backward, y_backward = euler_backward(f_stiff, t0_stiff, tf_stiff, y0_stiff, h_backward)
print("y(tf) numérique :", y_backward[-1])
print("y(tf) exact :", np.exp(lam * tf_stiff))
y(tf) numérique : 0.02777777777777778 y(tf) exact : 4.5399929762484854e-05

Méthodes implicites dans solve_ivp¶
Pour les problèmes raides, utilisez :
method='Radau': méthode implicite de Runge-Kutta (ordre 5)method='BDF': Backward Differentiation Formulas (ordre variable, jusqu'à 5)
Ces méthodes détectent et gèrent automatiquement la raideur.
# Résolution avec RK45 (explicite) — observe la difficulté
sol_explicit = solve_ivp(f_stiff, [t0_stiff, tf_stiff], [y0_stiff], method='RK45', rtol=1e-6, atol=1e-9)
# Résolution avec BDF (implicite)
sol_implicit = solve_ivp(f_stiff, [t0_stiff, tf_stiff], [y0_stiff], method='BDF', rtol=1e-6, atol=1e-9)
print("RK45 (explicite) — nombre de pas :", len(sol_explicit.t))
print("BDF (implicite) — nombre de pas :", len(sol_implicit.t))
print("RK45 (explicite) — nombre d'évaluations de f :", sol_explicit.nfev)
print("BDF (implicite) — nombre d'évaluations de f :", sol_implicit.nfev)
RK45 (explicite) — nombre de pas : 41 BDF (implicite) — nombre de pas : 107 RK45 (explicite) — nombre d'évaluations de f : 248 BDF (implicite) — nombre d'évaluations de f : 214
Observation¶
- RK45 doit prendre beaucoup de petits pas pour rester stable → coûteux
- BDF peut utiliser des pas plus grands → moins d'évaluations de fonction
Règle pratique : si
solve_ivpprend un nombre anormalement élevé de pas, essayez une méthode implicite (BDFouRadau).
À vous de faire les exercices 4.1 et 4.2 !¶
Points clés de la séance¶
| Méthode | Ordre | Stabilité | Usage |
|---|---|---|---|
| Euler explicite | $\mathcal{O}(h)$ | Limitée | Problèmes simples où avec un petit pas de temps inhérent |
| RK4 | $\mathcal{O}(h^4)$ | Bonne pour problèmes lisses | Cheval de bataille général |
| RK45 adaptatif | $\mathcal{O}(h^5)$ | Automatique | solve_ivp par défaut |
| Euler implicite | $\mathcal{O}(h)$ | A-stable | Problèmes raides, plasticity |
| BDF, Radau | Ordre élevé | A-stable | Problèmes raides complexes |