CM4 - La đșboĂźte de Pandoređș des approximations
Selon HĂ©siode, lorsque PromĂ©thĂ©e dĂ©roba le feu du ciel, Zeus, le roi des dieux, se vengea en offrant Pandore Ă ĂpimĂ©thĂ©e, le frĂšre de PromĂ©thĂ©e. Pandore, poussĂ©e par la curiositĂ©, ouvrit une jarre qui lui avait Ă©tĂ© confiĂ©e, libĂ©rant ainsi la maladie, la mort et dâinnombrables maux dans le monde. En refermant prĂ©cipitamment le rĂ©cipient, elle dĂ©couvrit quâune seule chose y demeurait : lâespoir. Câest de cette lĂ©gende quâest nĂ©e lâexpression « ouvrir la boĂźte de Pandore », symbolisant le fait de dĂ©clencher une sĂ©rie de problĂšmes imprĂ©vus et incontrĂŽlables.
De maniĂšre similaire, le domaine des approximations numĂ©riques peut ĂȘtre perçu comme une boĂźte de Pandore. En sâaventurant dans ce champ, on se confronte Ă une multitude de dĂ©fis, tels que la stabilitĂ©, les problĂšmes raides et les systĂšmes mal conditionnĂ©s. Chacun de ces aspects reprĂ©sente un dĂ©fi Ă surmonter pour obtenir des rĂ©sultats fiables et prĂ©cis.
Ce chapitre est divisé en deux parties principales :
- PARTIE 1ïžâŁ PropriĂ©tĂ©s du problĂšme de Cauchy :
- existence et unicité de la solution,
- dépendance continue par rapport aux données initiales,
- conditionnement (et lien avec des problĂšmes stiffs) ;
- PARTIE 2ïžâŁ PropriĂ©tĂ©s des schĂ©mas numĂ©riques :
- convergence (et ordre de convergence) Ă travers les deux notions de
- consistance (et ordre de consistance),
- zéro-stabilité (stabilité sur un intervalle de temps fini)
- absolue-stabilité (stabilité sur un intervalle de temps infini) et lien avec les problÚmes stiffs.
- convergence (et ordre de convergence) Ă travers les deux notions de
1 PARTIE 1ïžâŁ - propriĂ©tĂ©s du problĂšme de Cauchy : bien posĂ©s (mathĂ©matiquement et numĂ©riquement), bien conditionnĂ©s
En gĂ©nĂ©ral, il ne suffit pas quâun schĂ©ma numĂ©rique soit convergent pour quâil donne de bons rĂ©sultats sur nâimporte quelle Ă©quation diffĂ©rentielle. DĂšs quâon tente dâapprocher une solution, de nombreux facteurs peuvent en fait nous en Ă©loigner : une Ă©tude mathĂ©matique sophistiquĂ©e doit alors ĂȘtre envisagĂ©e. En particulier, il faut que le problĂšme de Cauchy soit
- mathématiquement bien posé : sa solution existe et est unique,
- numĂ©riquement bien posĂ© : sa solution nâest pas trop perturbĂ©e par une erreur initiale ou des perturbations du second membre,
- bien conditionnĂ© (= non raide) : les mĂ©thodes numĂ©riques usuelles peuvent calculer une solution approchĂ©e raisonnable en un nombre raisonnable dâitĂ©rations.
Ces définitions sont celles adoptés aux pages 235-236 dans le livre de Jean-Pierre DEMAILLY, Analyse Numérique et équations différentielles.
1.1 ProblÚme mathématiquement bien posé : existence et unicité de la solution
Définition de problÚme mathématiquement bien posé
On dit quâun problĂšme de Cauchy est mathĂ©matiquement bien posĂ© sâil existe une et une seule solution.
Si ce nâest pas le cas, on dit quâil est mathĂ©matiquement mal posĂ©.
Exemple de problÚme mathématiquement MAL posé
Le problĂšme de Cauchy
\( \begin{cases} y'(t) = \sqrt[3]{y(t)}, & \text{pour } t>0,\\ y(0) = 0. \end{cases} \)
ne satisfait pas les hypothĂšses du thĂ©orĂšme de Cauchy-Lipschitz, car la fonction \(\varphi(t,y)=\sqrt[3]{y}\) nâest pas lipschitzienne par rapport Ă la deuxiĂšme variable en \(y=0\) (on a \(\partial_y \varphi(t,y)=\frac{1}{3\sqrt[3]{y^2}} \xrightarrow[y\to0]{}+\infty\)).
On ne peut donc pas garantir lâunicitĂ© de la solution et, en effet, il est simple de vĂ©rifier que, pour tout \(t\ge0\), les trois fonctions
- \(y_1(t)=0\) pour tout \(t\)
- \(y_{2,3}(t)=\pm\sqrt{\frac{8}{27}t^3}=\pm\frac{2\sqrt{2}}{3\sqrt{3}}\sqrt{t^3}=\pm\frac{2\sqrt{6}}{9}\sqrt{t^3}\)
sont solution du problÚme de Cauchy donné.
Dans ce cas, lorsquâon utilise une mĂ©thode numĂ©rique, on ne peut pas savoir quelle solution ce schĂ©ma approche et diffĂ©rents schĂ©mas peuvent approcher diffĂ©rentes solutions.
Code
# Remaruqe : si on demande Ă sympy de calculer toutes les solutions, il ne trouve pas la solution constante = 0
t = sym.Symbol('t')
y = sym.Function('y')
edo = sym.Eq( sym.diff(y(t),t) , y(t)**(1/sym.S(3)) )
display(edo)
solgenLIST = sym.dsolve(edo,y(t))
display(solgenLIST)
for solgen in solgenLIST:
t0, y0 = 0, 0
consts = sym.solve( [solgen.rhs.subs(t,t0)-y0 ], dict=True)[0]
solpar = solgen.subs(consts).simplify()
display(solpar)
\(\displaystyle \frac{d}{d t} y{\left(t \right)} = \sqrt[3]{y{\left(t \right)}}\)
\(\displaystyle \left[ y{\left(t \right)} = - \frac{2 \sqrt{6} \left(C_{1} + t\right)^{\frac{3}{2}}}{9}, \ y{\left(t \right)} = \frac{2 \sqrt{6} \left(C_{1} + t\right)^{\frac{3}{2}}}{9}\right]\)
\(\displaystyle y{\left(t \right)} = - \frac{2 \sqrt{6} t^{\frac{3}{2}}}{9}\)
\(\displaystyle y{\left(t \right)} = \frac{2 \sqrt{6} t^{\frac{3}{2}}}{9}\)
Exercice : problÚme MAL posé mathématiquement
- Montrer que le problÚme de Cauchy suivant admet une infinité de solutions de classe \(\mathcal{C}^1(\mathbb{R})\):
\( \begin{cases} y'(t)=2\sqrt{|y(t)|}, & t>0\\ y(0)=0. \end{cases}\)
- Parmi ces solutions, quelle solution approche-t-on si on utilise la mĂ©thode dâEuler explicite? et la mĂ©thode dâEuler implicite?
- Que se passe-t-il si la donnée initiale est \(y(0)=y_0>0\)?
Correction
Sur \(\mathbb{R}^+\) la fonction \(\varphi(t,y)=2\sqrt{y}\) nâest pas lipschitzienne par rapport Ă \(y\) au voisinage de \((t,0)\) (car \(\partial_y\varphi=1/\sqrt{y}\to\infty\) lorsque \(y\to0\)), donc le thĂ©orĂšme dâexistence et unicitĂ© locale nâest pas valable au voisinage de \((0,0)\). MĂȘme raisonnement sur \(\mathbb{R}^-\).
LâEDO est Ă variables sĂ©parables, on peut donc calculer explicitement toutes les solutions du problĂšme de Cauchy :
- elle admet une seule solution constante, la fonction \(y(t)=0\) pour tout \(t\in\mathbb{R}^+\),
- et des solutions de la forme \(y(t)=(t+c)^{2}\) pour tout \(t\ge c\).
En imposant la CI on trouve que, pour tout \(b\in\mathbb{R}^+\), les fonctions
\( y_b(t)= \begin{cases} 0 , &\text{si }0\le t\le b, \\ (t-b)^{2} , &\text{si }t\ge b, \end{cases} \)
sont de classe \(\mathcal{C}^1(\mathbb{R}^+)\) et sont solution du problÚme de Cauchy donné.
Code
# Remaruqe : si on demande à sympy de calculer les solutions, il donne une réponse enigmatique
# ===============================================================================================
t = sym.Symbol('t')
y = sym.Function('y')
display(Markdown("**ProblĂšme de Cauchy**"))
edo = sym.Eq( sym.diff(y(t),t) , 2*sym.sqrt(abs(y(t))) )
display(edo)
t0, y0 = 0, 0
display(sym.Eq(y(t0),y0))
# Méthode directe
display(Markdown("**Méthode directe**"))
sol = sym.dsolve(edo,y(t), ics={y(t0):y0})
display(sol)
# Méthode pas à pas
display(Markdown("**Méthode pas à pas**"))
solGEN = sym.dsolve(edo,y(t))
display(solGEN)
consts = sym.solve( [solGEN.rhs.subs(t,t0)-y0 ], dict=True)[0]
solPAR = solGEN.subs(consts).simplify()
display(solPAR)
ProblĂšme de Cauchy
\(\displaystyle \frac{d}{d t} y{\left(t \right)} = 2 \sqrt{\left|{y{\left(t \right)}}\right|}\)
\(\displaystyle y{\left(0 \right)} = 0\)
Méthode directe
\(\displaystyle \int\limits^{y{\left(t \right)}} \frac{1}{\sqrt{\left|{y}\right|}}\, dy = 2 t + \int\limits^{0} \frac{1}{\sqrt{\left|{y}\right|}}\, dy\)
Méthode pas à pas
\(\displaystyle \int\limits^{y{\left(t \right)}} \frac{1}{\sqrt{\left|{y}\right|}}\, dy = C_{1} + 2 t\)
\(\displaystyle 2 t = \int\limits^{y{\left(t \right)}} \frac{1}{\left|{\sqrt{y}}\right|}\, dy\)
Traçons quelques courbes :
Code
xx = np.linspace(0,2,101)
yyr = np.zeros_like(xx)
# f = lambda x,b : 0 if (x<=b) else (x-b)**2
# yy1 = [f(x,1) for x in xx]
# yy75= [f(x,0.75) for x in xx]
# yy0 = [f(x,0) for x in xx]
f = lambda x, b : np.where(x<=b, 0, (x-b)**2)
yy1 = f(xx,1)
yy75= f(xx,0.75)
yy0 = f(xx,0)
plt.figure(figsize=(8,5))
plt.plot(xx,yyr ,'r-', label=r'$y(t)=0$ $\forall$ $t$')
plt.plot(xx,yy1 ,'b:', label=r'$y_{b=1}(t)$')
plt.plot(xx,yy75 ,'g*', label=r'$y_{b=0.75}(t)$')
plt.plot(xx,yy0 ,'yd', label=r'$y_{b=0}(t)$')
plt.legend();
La mĂ©thode dâEuler explicite construit la suite
\(\begin{cases} u_0=y_0=0,\\ u_{n+1}=u_n+h \varphi(t_n,u_n)=u_n+hu_n^{1/2},& n=0,1,2,\dots N_h-1 \end{cases}\)
par consĂ©quent \(u_n=0\) pour tout \(n\): la mĂ©thode dâEuler explicite approche la solution constante \(y(t)=0\) pour tout \(t\in\mathbb{R}^+\).
La mĂ©thode dâEuler implicite construit la suite
\(\begin{cases} u_0=y_0=0,\\ u_{n+1}=u_n+h \varphi(t_{n+1},u_{n+1})=u_n+hu_{n+1}^{1/2},& n=0,1,2,\dots N_h-1. \end{cases}\)
par consĂ©quent \(u_0=0\) mais \(u_1\) dĂ©pend de la mĂ©thode de rĂ©solution de lâĂ©quation implicite \(x=0+h\sqrt{x}\). Bien-sĂ»r \(x=0\) est une solution mais \(x=h^{2}\) est aussi solution. Si le schĂ©ma choisit \(u_1=h^{2}\), alors \(u_n>0\) pour tout \(n\in\mathbb{N}^*\).
Notons que le problĂšme de Cauchy avec une CI \(y(0)=y_0>0\) admet une et une seule solution, la fonction \(y(t)=\frac{1}{4}(t+2\sqrt{y_0})^{2}\). Dans ce cas, les deux schĂ©mas approchent la mĂȘme unique solution.
1.2 ProblÚme numériquement bien posé : dépendance continue de la solution par rapport aux données.
Une fois calculĂ©e la solution numĂ©rique \(\{u_n\}_{n=0}^{N}\) dâun problĂšme de Cauchy mathĂ©matiquement bien posĂ©, il est lĂ©gitime de chercher Ă savoir dans quelle mesure lâerreur \(|y(t_n)-u_n|\) est petite. Cela dĂ©pend bien sur du schĂ©ma choisi, mais aussi du problĂšme en question. En effet, Ă©tant donnĂ© que les erreurs dâarrondi amĂšnent toujours Ă rĂ©soudre un problĂšme perturbĂ©, il est important de savoir si la solution dâun problĂšme perturbĂ© est proche de la solution du problĂšme non perturbĂ©.
Définition de problÚme numériquement bien posé
On dit quâun problĂšme de Cauchy est numĂ©riquement bien posĂ© si la solution dâun problĂšme faiblement perturbĂ© (second membre ou condition initiale) possĂšde une solution proche de celle du problĂšme original.
Si ce nâest pas le cas, on dit quâil est numĂ©riquement mal posĂ©.
Question pratique : GĂ©nĂ©ralement on utilise un schĂ©ma pour approcher la solution dâun problĂšme dont on ne connait pas la solution exacte. Comment peut-on conjecturer que le problĂšme est numĂ©riquement mal posĂ© ?
IdĂ©e : on teste un mĂȘme schĂ©ma avec diffĂ©rentes discrĂ©tisations (trĂšs diffĂ©rentes entre elles) ou on teste diffĂ©rents schĂ©mas. Si les solutions obtenues sont trĂšs diffĂ©rentes, le problĂšme est probablement numĂ©riquement mal posĂ©.
Exemple de problÚme BIEN posé numériquement
Soit \(y_0\) donnĂ© et considĂ©rons une petite perturbation \(\varepsilon\). Calculons \(\lim_{t\to+\infty} y_{\varepsilon}\) oĂč \(y_{\varepsilon}\) est la solution exacte du problĂšme de Cauchy
\(\begin{cases} y_{\varepsilon}'(t) = -y_{\varepsilon}(t), &\forall t>0,\\ y_{\varepsilon}(0) = y_0+\varepsilon. \end{cases}\)
La solution exacte est \(y(t)=y_0e^{-t}+\varepsilon e^{-t}\) : lâeffet de la perturbation \(\varepsilon\) sâattĂ©nue lorsque \(t\to+\infty\) puisque \(\varepsilon e^{-t}\xrightarrow[t\to+\infty]{}0\).
Cela suggĂšre que si une erreur est faite dans une Ă©tape dâune mĂ©thode dâitĂ©ration, lâeffet de cette erreur sâattĂ©nue au cours du temps: le problĂšme est numĂ©riquement bien posĂ©.
Code
y0 = 1
y = lambda t,eps : (y0+eps)*np.exp(-t)
tt = np.linspace(0,5,101)
yye = y(tt,0.1) # [y(t,0.1) for t in tt]
yy0 = y(tt,0) # [y(t,0) for t in tt]
plt.figure(figsize=(8,5))
plt.plot(tt,yye, label="$y(0)=1.1$")
plt.plot(tt,yy0, label="$y(0)=1$")
plt.legend(bbox_to_anchor=(1,1));
plt.axis([0,5,0,1.1]);
Exemple de problÚme BIEN posé numériquement
Considérons le problÚme de Cauchy \(\begin{cases} y'(t) = y(t)\sin(t), &\forall t>0,\\ y(0) = -1+\varepsilon. \end{cases}\)
La solution est \(y(t)=-e^{1-\cos(t)}+\varepsilon e^{1-\cos(t)}\) : lâeffet de la perturbation \(\varepsilon\) reste bornĂ© lorsque \(t\to+\infty\) puisque \(|\varepsilon e^{1-\cos(t)}|\le \varepsilon e^2\). Cela suggĂšre que si une erreur est faite dans une Ă©tape dâune mĂ©thode dâitĂ©ration, lâeffet de cette erreur reste bornĂ© au cours du temps: le problĂšme est numĂ©riquement bien posĂ©.
Code
Exemple de problÚme MAL posé numériquement
Considérons le problÚme de Cauchy
\(\begin{cases} y'(t) = y(t), &\forall t>0,\\ y(0) = y_0+\varepsilon. \end{cases}\)
La solution est \(y(t)=y_0e^{t}+\varepsilon e^{t}\) : lâeffet de la perturbation \(\varepsilon\) sâamplifie lorsque \(t\to+\infty\) puisque \(\varepsilon e^{t}\xrightarrow[t\to+\infty]{}+\infty\). Cela suggĂšre que si une erreur est faite dans une Ă©tape dâune mĂ©thode dâitĂ©ration, lâeffet de cette erreur sâamplifie au cours du temps: le problĂšme est numĂ©riquement mal posĂ©.
Code
y0 = 0
y = lambda t,eps : (y0+eps)*np.exp(t)
tt = np.linspace(0,5,101)
yye = y(tt,0.01) # [y(t,0.01) for t in tt]
yy0 = y(tt,0) # [y(t,0) for t in tt]
plt.figure(figsize=(8,5))
plt.plot(tt, yye, lw='2', label="$y(0)=0.01$")
plt.plot(tt, yy0, lw='5', label="$y(0)=0$")
plt.legend(bbox_to_anchor=(1,1))
plt.axis([0,5,0,1.1]);
Exemple de problÚme MAL posé numériquement
Soit \(\alpha\) un nombre quelconque. Ătudions la solution exacte \(y_{\alpha}\) du problĂšme de Cauchy
\( \begin{cases} y_{\alpha}'(t) = 3y_{\alpha}(t)-3t, &\forall t\in\mathbb{R},\\ y_{\alpha}(0) = \alpha. \end{cases} \)
Comparons ensuite les solutions \(y_{1/3}\) et \(y_{0.333333}\) en \(t=10\).
La solution, définie sur \(\mathbb{R}\), est donnée par
\( y_{\alpha}(t)=\left(\alpha-\frac{1}{3}\right)e^{3t}+t+\frac{1}{3}. \)
Ăvaluons \(y_{\alpha}\) en \(t=10\):
- si \(\alpha=\frac{1}{3}\) alors \(y_{\alpha}(10)=\frac{31}{3}\),
- si \(\alpha=0.333333\) alors \(y_{\alpha}(10)=(0.333333-1/3)e^{30}+10+1/3=-e^{30}/3000000+31/3\approx31/3+10^7/3\).
ConsĂ©quence : si nous faisons le calcul avec lâapproximation \(\alpha=0.333333\) au lieu de \(1/3\), nous avons \(y(10)=31/3-e^{30}/3000000\) ce qui reprĂ©sente une diffĂ©rence avec la prĂ©cĂ©dente valeur de \(e^{30}/3000000\approx10^7/3\).
Cet exemple nous apprend quâune petite erreur sur la condition initiale (erreur relative dâordre \(10^{-6}\)) peut provoquer une trĂšs grande erreur sur \(y(10)\) (erreur relative dâordre \(10^{6}\)). Ainsi, si le calculateur mis Ă notre disposition ne calcule quâavec \(6\) chiffres significatifs (en virgule flottante), alors \(\alpha=1/3\) devient \(\alpha=0.333333\) et il est inutile dâessayer dâinventer une mĂ©thode numĂ©rique pour calculer \(y(10)\). En effet, la seule erreur sur la condition initiale provoque dĂ©jĂ une erreur inadmissible sur la solution. Nous sommes en prĂ©sence ici dâun problĂšme numĂ©riquement mal posĂ©
Vérifions-le avec sympy :
Code
t = sym.Symbol('t')
y = sym.Function(r'y_{\alpha}')
edo = sym.Eq( sym.diff(y(t),t) , 3*y(t)-3*t )
#display(edo)
solgen = sym.dsolve(edo,y(t))
#display(solgen)
alpha = sym.Symbol('alpha')
t0, y0 = 0, alpha
consts = sym.solve( [solgen.rhs.subs(t,t0)-y0 ], dict=True)[0]
solpar = solgen.subs(consts).simplify()
display(solpar)
sol1 = solpar.subs(t,10).subs(alpha,sym.Rational(1,3))
sol2 = solpar.subs(t,10).subs(alpha,0.333333)
display(sol1)
display(sol2)
print('Difference:')
display((sol1.rhs-sol2.rhs).evalf())
\(\displaystyle y_{\alpha}{\left(t \right)} = t + \left(\alpha - \frac{1}{3}\right) e^{3 t} + \frac{1}{3}\)
\(\displaystyle y_{\alpha}{\left(10 \right)} = \frac{31}{3}\)
\(\displaystyle y_{\alpha}{\left(10 \right)} = \frac{31}{3} - 3.33333333324415 \cdot 10^{-7} e^{30}\)
Difference:
\(\displaystyle 3562158.19374618\)
Exercice : problÚme numériquement MAL posé à la précision machine
On considĂšre un problĂšme de Cauchy dĂ©pendant dâun paramĂštre \(\varepsilon\) et on note \(y_\varepsilon(t)\) sa solution. Estimer la diffĂ©rence en \(t=50\) entre les solutions \(y_{\varepsilon}\) avec \(\varepsilon=10^{-17}\) et \(\varepsilon=0\) :
\( \begin{cases} y_\varepsilon'(t)=5y_\varepsilon(t)-5, &t\in[0;50]\\ y_\varepsilon(0)=1+\varepsilon. \end{cases} \)
Notons que \(\varepsilon=10^{-17}\) est une valeur trĂšs proche de \(0\) et correspond Ă lâerreur dâarrondi dâun calculateur qui travaille avec \(17\) chiffres significatifs.
La solution exacte est donnée par \(y_\varepsilon(t)=\varepsilon e^{5t}+1\) comme on peut le vérifier avec sympy :
Code
import sympy as sym
import numpy as np
import matplotlib.pyplot as plt
# Définition des symboles
t = sym.Symbol('t')
epsilon = sym.Symbol(r'\varepsilon')
# Définition de la fonction y(t)
y = sym.Function(r'y_{\varepsilon}')(t)
# Ăquation diffĂ©rentielle
edo = sym.Eq(sym.diff(y, t), 5*y - 5)
display(edo)
# Condition initiale
display( sym.Eq(y.subs(t, 0), 1 + epsilon))
# Résolution
sol = sym.dsolve(edo, y, ics={y.subs(t, <span class="dv">0</span>): <span class="dv">1</span> <span class="op">+</span> epsilon})
display(sol)
# Calcul des solutions pour epsilon=10^(-17) et epsilon=0
sol1 = sol.subs({t: <span class="dv">50</span>, epsilon: sym.Rational(<span class="dv">1</span>, <span class="dv">10</span><span class="op">**</span><span class="dv">17</span>)})
sol0 = sol.subs({t: <span class="dv">50</span>, epsilon: <span class="dv">0</span>})
display(sol1)
display(sol0)
# Affichage de la différence entre les solutions
print('Difference:')
display((sol1.rhs - sol0.rhs).evalf())
\(\displaystyle \frac{d}{d t} y_{\varepsilon}{\left(t \right)} = 5 y_{\varepsilon}{\left(t \right)} - 5\)
\(\displaystyle y_{\varepsilon}{\left(0 \right)} = \varepsilon + 1\)
\(\displaystyle y_{\varepsilon}{\left(t \right)} = \varepsilon e^{5 t} + 1\)
\(\displaystyle y_{\varepsilon}{\left(50 \right)} = 1 + \frac{e^{250}}{100000000000000000}\)
\(\displaystyle y_{\varepsilon}{\left(50 \right)} = 1\)
Difference:
\(\displaystyle 3.74645461450267 \cdot 10^{91}\)
Une trĂšs petite erreur sur la condition initiale (de lâordre de la prĂ©cision machine) provoque une trĂšs grande erreur sur \(y(50)\). Ainsi, il est inutile dâessayer dâinventer une mĂ©thode numĂ©rique pour calculer \(y(50)\). En effet, la seule erreur sur la condition initiale provoque dĂ©jĂ une erreur inadmissible sur la solution. Nous sommes en prĂ©sence ici dâun problĂšme numĂ©riquement mal posĂ©
Exercice : problÚme numériquement MAL posé
Lâobjectif de cet exercice est de bien mettre en Ă©vidence lâinfluence dâune petite perturbation de la condition initiale sur la solution dâun problĂšme numĂ©riquement mal posĂ© et dâappliquer la mĂ©thode dâEuler explicite pour en approcher la solution exacte.
Considérons le problÚme de Cauchy
\(\begin{cases} y'(t)=3\dfrac{y(t)}{t}-\dfrac{5}{t^3},\\ y(1)=a \end{cases}\)
- Calculer lâunique solution exacte Ă ce problĂšme de Cauchy en fonction de \(a\) pour \(t>0\). Remarquer quâavec le changement de variable \(u(t)=\frac{y(t)}{t}\) on obtient une EDO linĂ©aire dâordre 1.
- Tracer la solution exacte sur lâintervalle \([1;5]\) pour \(a=1\), \(a=1\pm\frac{1}{1000}\) et \(a=1\pm\frac{1}{100}\).
- Pour \(a=1\), sur un autre graphique tracer la solution exacte et les solutions obtenues par la mĂ©thode dâEuler explicite avec \(N=20\), \(N=100\), \(N=300\), \(N=5000\). Comment expliquez-vous ce comportement du schĂ©ma?
Correction
Calculons les solutions de lâedo pour \(t>0\). On pose \(u(t)=\frac{y(t)}{t}\) ainsi \(y(t)=tu(t)\) et \(y'(t)=u(t)+tu'(t)\). On obtient lâedo linĂ©aire dâordre 1 suivante: \(
tu'(t)-2u(t)=-5t^{-3}.
\) On a \(a(t)=t\), \(b(t)=-2\) et \(g(t)=-5t^{-3}\) donc
+ \(A(t)=\int \frac{b(t)}{a(t)}\mathrm{d}t=\int -\frac{2}{t}\mathrm{d}t= -2\ln(t)=\ln(t^{-2})\), + \(B(t)=\int \frac{g(t)}{a(t)}e^{A(t)}\mathrm{d}t=\int -5t^{-4} e^{A(t)}\mathrm{d}t=\int -5t^{-6} \mathrm{d}t = t^{-5}\).
On conclut que \(u(t)=ce^{-A(t)}+B(t)e^{-A(t)}=ct^2+t^{-3}\) et \(\boxed{y(t)=tu(t)=ct^3+t^{-2}}\).
En imposant la condition \(a=y(1)\) on trouve lâunique solution du problĂšme de Cauchy donnĂ©: \( y(t)=(a-1)t^3+\dfrac{1}{t^2}. \)
Vérifions ce calcul avec sympy
:
Code
\(\displaystyle \frac{d}{d t} y{\left(t \right)} = \frac{3 y{\left(t \right)}}{t} - \frac{5}{t^{3}}\)
\(\displaystyle y{\left(t \right)} = \frac{C_{1} t^{5} + 1}{t^{2}}\)
\(\displaystyle y{\left(t \right)} = \frac{t^{5} \left(a - 1\right) + 1}{t^{2}}\)
Traçons les solutions exactes pour \(a=1\), \(a=1\pm\frac{1}{1000}\) et \(a=1\pm\frac{1}{100}\) sur lâintervalle \([1;5]\) :
Code
sol_exacte = lambda t,y0 : (y0-1)*t**3+1/t**2
# INITIALISATION
t0 = 1
tfinal = 5
c = 1
tt = np.linspace(t0,tfinal,101)
Y0 = [c+1.e-2,c+1.e-3,c,c-1.e-3,c-1.e-2]
plt.figure(figsize=(10,7))
for y0 in Y0:
yy = sol_exacte(tt,y0) # [sol_exacte(t,y0) for t in tt]
plt.plot(tt, yy, label=f'$y_0={</span>y0<span class="sc">}$')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.grid()
plt.title('Solutions exactes pour differents valeurs de $y_0$')
plt.axis([t0,tfinal,-c,c]);
On constate quâune petite perturbation de la condition initiale entraĂźne une grosse perturbation de la solution, en effet \(
\lim_{t\to+\infty}y(t)=
\begin{cases}
+\infty &\text{si } a>1,\\
0^+ &\text{si } a=1,\\
-\infty &\text{si } a<1.
\end{cases}
\)
Si \(a=1\), la solution exacte est \(y(t)=t^{-2}\) mais le problĂšme est numĂ©riquement mal posĂ© car toute (petite) erreur de calcul a le mĂȘme effet quâune perturbation de la condition initiale: on ârĂ©veilleâ le terme dormant \(t^{3}\).
Lorsque lâon essaye dâapprocher la solution avec les mĂ©thodes classiques Ă un pas, bien sĂ»r lorsque \(N\to+\infty\) on converge vers la solution exacte, cependant en pratique \(N\) est fini et on voit quâinĂ©vitablement nous allons approcher une autre solution que celle correspondant Ă \(a=1\).
Code
phi = lambda t,y : 3*y/t-5/t**3
t0 = 1
tfinal = 5
y0 = 1
def EE(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros(len(tt))
uu[0] = y0
for i in range(len(tt)-1):
uu[i+1] = uu[i]+h*phi(tt[i],uu[i])
return uu
def EI(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros(len(tt))
uu[0] = y0
for i in range(len(tt)-1):
uu[i+1] = fsolve(lambda x : -x +uu[i]+h*phi(tt[i+1],x),uu[i])[0]
return uu
def EM(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros(len(tt))
uu[0] = y0
for i in range(len(tt)-1):
utilde = uu[i]+h/2*phi(tt[i],uu[i])
uu[i+1] = uu[i]+h*phi(tt[i]+h/2,utilde)
return uu
def CN(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros(len(tt))
uu[0] = y0
for i in range(len(tt)-1):
uu[i+1] = fsolve(lambda x : -x +uu[i]+h/2*(phi(tt[i],uu[i])+phi(tt[i+1],x)),uu[i])[0]
return uu
def HE(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros(len(tt))
uu[0] = y0
for i in range(len(tt)-1):
utilde = uu[i]+h*phi(tt[i],uu[i])
uu[i+1] = uu[i] + h/2 * (phi(tt[i],uu[i])+phi(tt[i+1],utilde))
return uu
NN = [20,100,300,5000]
plt.figure(figsize=(15, 10))
plt.subplot(2,3,1)
for N in NN:
tt = np.linspace(t0,tfinal,N)
uu = EE(phi,tt,y0)
plt.plot(tt,uu,'.-')
plt.plot(tt, sol_exacte(tt,y0),'c-',lw=2)
plt.legend(['N=20','N=100','N=300','N=5000','Exacte'])
plt.title('$y_0=1$ - Exacte vs EE')
plt.axis([t0,tfinal,-c,c]);
plt.subplot(2,3,3)
for N in NN:
tt = np.linspace(t0,tfinal,N)
uu = EI(phi,tt,y0)
plt.plot(tt,uu,'.-')
plt.plot(tt,[sol_exacte(t,y0) for t in tt],'c-',lw=2)
plt.legend(['N=20','N=100','N=300','N=5000','Exacte'])
plt.title('$y_0=1$ - Exacte vs EI')
plt.axis([t0,tfinal,-c,c]);
plt.subplot(2,3,4)
for N in NN:
tt = np.linspace(t0,tfinal,N)
uu = EM(phi,tt,y0)
plt.plot(tt,uu,'.-')
plt.plot(tt,[sol_exacte(t,y0) for t in tt],'c-',lw=2)
plt.legend(['N=20','N=100','N=300','N=5000','Exacte'])
plt.title('$y_0=1$ - Exacte vs EM')
plt.axis([t0,tfinal,-c,c]);
plt.subplot(2,3,5)
for N in NN:
tt = np.linspace(t0,tfinal,N)
uu = HE(phi,tt,y0)
plt.plot(tt,uu,'.-')
plt.plot(tt,[sol_exacte(t,y0) for t in tt],'c-',lw=2)
plt.legend(['N=20','N=100','N=300','N=5000','Exacte'])
plt.title('$y_0=1$ - Exacte vs HE')
plt.axis([t0,tfinal,-c,c]);
plt.subplot(2,3,6)
for N in NN:
tt = np.linspace(t0,tfinal,N)
uu = CN(phi,tt,y0)
plt.plot(tt,uu,'.-')
plt.plot(tt,[sol_exacte(t,y0) for t in tt],'c-',lw=2)
plt.legend(['N=20','N=100','N=300','N=5000','Exacte'])
plt.title('$y_0=1$ - Exacte vs CN')
plt.axis([t0,tfinal,-c,c]);
1.3 ProblĂšme bien conditionnĂ© (= non raide) : solution approchĂ©e en un nombre raisonnable dâitĂ©rations.
Définition de problÚme bien conditionné
On dit quâun problĂšme de Cauchy est bien conditionnĂ© si les mĂ©thodes numĂ©riques usuelles peuvent donner sa solution en un nombre raisonnable dâopĂ©rations.
Dans le cas contraire on parle de problĂšme raide.
Exemple de problÚme MAL conditionné (= raide = stiff)
Considérons le problÚme de Cauchy avec \(\beta>0\) :
\( \begin{cases} y'(t) = -\beta y(t), &\forall t\in[0;1],\\ y(0) = 1. \end{cases} \)
Ce problĂšme est
- mathématiquement bien posé pour tout \(\beta\in\mathbb{R}\) : il existe une et une seule solution, elle définie sur \(\mathbb{R}\) et est donnée par \(y(t)=e^{-\beta t}\);
- numĂ©riquement bien posĂ© pour tout \(\beta>0\) : lâerreur sur la solution sera au pire de lâordre de lâerreur sur la condition initialeâŻ;
- mal conditionnĂ© ou stiff si \(\beta \gg 1\) : plus \(\beta\) est grand, plus le pas \(h\) devient petit car la solution devient de plus en plus raide (stiff) et seul un pas trĂšs petit permet dâapprocher la solution exacte indĂ©pendamment de la mĂ©thode numĂ©rique utilisĂ©e.
Nous allons tracer la solution exacte pour \(\beta=1\), \(\beta=10\), \(\beta=50\) et \(\beta=100\) sur lâintervalle \([0;1]\) pour illustrer ce phĂ©nomĂšne.
Nous allons aussi Ă©tudier analytiquement le comportement du schĂ©ma dâEuler explicite pour ce problĂšme.
Voici ci-dessous le tracé de la solution exacte pour \(\beta\) allant de \(1\) à \(100\) :
Code
exacte = lambda t,b : np.exp(-b*t)
t0 = 0
tfinal = 1
tt = np.linspace(t0,tfinal,501)
plt.figure(1, figsize=(18, 4))
for i,b in enumerate([1,10,50,100]):
plt.subplot(1,4,i+1)
yy = exacte(tt,b) #[exacte(t,b) for t in tt]
plt.plot(tt, yy)
plt.title(f'$b={</span>b<span class="sc">}$')
plt.axis([0,1,0,1])
plt.grid();
Intuitivement : la solution exacte \(y(t)=e^{-\beta t}\) dĂ©croit trĂšs rapidement lorsque \(\beta\) est grand ; pour que la solution numĂ©rique puisse suivre cette dĂ©croissance rapide, il faut quâil y ait des points dans cette zone de dĂ©croissance rapide, câest-Ă -dire que le pas \(h\) soit petit.
On verra plus tard que, si on nâest pas intĂ©ressĂ© par cette zone de dĂ©croit rapide, mais plutĂŽt par le comportement asymptotique de la solution, on peut utiliser des mĂ©thodes numĂ©riques spĂ©cifiques qui permettent de prendre des pas plus grands.
La mĂ©thode dâEuler explicite pour cette EDO sâĂ©crit
\( u_{n+1}=(1-\beta h)u_n=\dots=(1-\beta h)^{n+1}u_0. \)
La suite obtenue est une suite gĂ©omĂ©trique de raison \(q=1-\beta h\). On sait quâune telle suite
- diverge si \(|q|>1\) ou \(q=-1\),
- est stationnaire si \(q=1\),
- converge vers \(0\) si \(|q|<1\) (de façon monotone vers \(0\) si \(0<q<1\)).
ainsi la solution numĂ©rique converge vers \(0\) ssi \(0<\beta h<2\). On voit donc que plus \(\beta\) est grand, plus le pas \(h\) doit ĂȘtre petit pour que la solution numĂ©rique puisse approcher la solution exacte. Cela signifie que le problĂšme devient de plus en plus raide (stiff).
Exercie : resolution numĂ©rique dâun problĂšme raide
Soient \(b,g>0\) et considérons le problÚme de Cauchy
\(\begin{cases} y'(t)=-by(t)+g,& t\in[0;1]\\ y(0)=y_0. \end{cases}\)
Solution exacte
- Donner lâunique solution exacte Ă ce problĂšme de Cauchy et tracer le graphe \(t\mapsto y(t)\) pour \(t\ge0\) en fonction de \(y_0\).
- Soient \(b=g=10\). Tracer avec python les solutions exactes sur lâintervalle \([0;1]\) pour \(y_0=\frac{g}{b}\) et \(y(0)=\frac{g}{b}+10^{-8}\) pour \(b=g=10\).
- Sur un graphe Ă cotĂ© tracer les mĂȘmes courbes avec \(b=g=40\). Que peut-on dire lorsque \(b\) devient de plus en plus grand?
- Donner lâunique solution exacte Ă ce problĂšme de Cauchy et tracer le graphe \(t\mapsto y(t)\) pour \(t\ge0\) en fonction de \(y_0\).
MĂ©thode dâEuler explicite
- Vérifier que la méthode génÚre une suite arithmético-géométrique et calculer analytiquement pour quelles valeurs de \(h\) la suite ainsi construite converge et pour quelles valeurs la convergence est monotone.
- Soient \(b=g=40\) et \(y_0=\frac{g}{b}\). Tracer les solutions approchées obtenues avec \(N=19\), \(N=23\), \(N=45\), \(N=100\).
- Répéter pour \(y_0=\frac{g}{b}+10^{-8}\) et expliquer chaque résultat.
MĂ©thode dâEuler implicite
- RĂ©pĂ©ter le mĂȘme exercice pour la mĂ©thode dâEuler implicite. Noter que, Ă©tant \(\varphi\) linĂ©aire, la mĂ©thode peut ĂȘtre rendu explicite par un calcul Ă©lĂ©mentaire.
ConsidĂ©rons lâĂ©quation diffĂ©rentielle ordinaire \(y'(t) = ay(t) + b\), oĂč \(a \neq 0\) et \(b\) sont des constantes rĂ©elles et considĂ©rons une donnĂ©e initiale \(y(0) = y_0\neq0\).
On cherche Ă réécrire cette Ă©quation sous la forme dâune Ă©quation \(v'(t) = qv(t)\), oĂč \(v\) est une nouvelle fonction Ă dĂ©terminer.
Posons \(v(t) = y(t) + \frac{b}{a}\). Alors \(v(0) = y_0 + \frac{b}{a}\) et
\(\begin{aligned} v'(t) &= y'(t)\\ &= ay(t) + b\\ &=a\left(v(t)-\frac{b}{a}\right)+b\\ &=av(t). \end{aligned}\)
La solution de cette équation est \(v(t) = v(0) e^{at}\).
On conclut alors que \(y(t) = v(t) + \frac{b}{a} = v(0) e^{at} + \frac{b}{a} = \left( y_0 + \frac{b}{a} \right) e^{at} - \frac{b}{a}\), autrement dit
\( \left( y(t)+\frac{b}{a} \right) = \left( y_0+\frac{b}{a} \right) e^{at}. \)
Une suite \((u_n)\) est dite arithmético-géométrique si elle satisfait une relation de la forme \(u_{n+1}=au_n+b\) avec \(a\neq1\) et \(b\) des réels constants.
On cherche Ă réécrire cette suite sous la forme dâune suite gĂ©omĂ©trique \((v_n)\) telle que \(v_{n+1}=qv_n\) avec \(q\) une constante rĂ©elle.
On pose \(v_n=u_n-\frac{b}{1-a}\). Alors
\(\begin{aligned} v_{n+1} &= u_{n+1}-\frac{b}{1-a}\\ &=au_n+b-\frac{b}{1-a}\\ &=a\left(v_n+\frac{b}{1-a}\right)+b-\frac{b}{1-a}\\ &=av_n+\frac{ab}{1-a}+b-\frac{b}{1-a}\\ &=av_n+\frac{ab+b(1-a)-b}{1-a}\\ &=av_n. \end{aligned}\)
La suite \((v_n)\) est bien géométrique de raison \(q=a\) donc \(v_n = a^n v_0\).
On conclut alors que \(u_n = a^n v_0 + \frac{b}{1-a}= a^n \left(u_0-\frac{b}{1-a}\right) + \frac{b}{1-a}\), autrement dit
\( \left( u_n-\frac{b}{1-a} \right) = \left( u_0-\frac{b}{1-a} \right) a^n . \)
Correction : solution exacte
Il sâagit de lâedo linĂ©aire dâordre 1 \(y'(t)=-by(t)+g\), dont la solution est
\( y(t)-\frac{g}{b}=\left( y_0-\frac{g}{b} \right)e^{-bt} \)
et
\( \lim_{t\to+\infty}y(t)=\frac{g}{b} \text{ pour tout } y_0\in\mathbb{R} \)
le problĂšme est numĂ©riquement bien posĂ©, câest-Ă -dire que lâerreur sur la solution sera au pire de lâordre de lâerreur sur la condition initiale.
Cependant, lorsque \(b\) devient de plus en plus grand, la solution devient de plus en plus raide:
Code
exacte = lambda t, b, g, y0 : (y0-g/b)*np.exp(-b*t)+g/b
t0 = 0.
tfinal = 1.0
tt = np.linspace(t0,tfinal,10001)
plt.figure(1, figsize=(15, 5))
plt.subplot(1,2,1)
g = 10
b = 10
Y0 = [g/b, g/b+1.e-8]
for y0 in Y0:
yy = exacte(tt,b,g,y0) # [exacte(t,b,g,y0) for t in tt]
plt.plot(tt,yy,label=('$y_0=$'+str(y0)));
plt.title("$g=b=$"+str(g))
plt.axis([0,1,g/b-1.e-8,g/b+1.e-8])
plt.legend()
plt.grid()
plt.subplot(1,2,2)
g = 40
b = 40
Y0 = [g/b, g/b+1.e-8]
for y0 in Y0:
yy = exacte(tt,b,g,y0) # [exacte(t,b,g,y0) for t in tt]
plt.plot(tt,yy,label=(r'$y_0=$'+str(y0)));
plt.title("$g=b=$"+str(g))
plt.axis([0,1,g/b-1.e-8,g/b+1.e-8])
plt.legend()
plt.grid();
Correction : MĂ©thode dâEuler explicite
La mĂ©thode dâEuler explicite donne la suite dĂ©finie par rĂ©currence \(u_{n+1}=Au_n+B\) avec \(A=1-bh\) et \(B=gh\), soit encore
\( \left( u_n-\frac{B}{1-A} \right) = \left( u_0-\frac{B}{1-A} \right) A^n \quad\leadsto\quad u_n-\frac{g}{b}=(1-hb)^n\left( y_0 -\frac{g}{b}\right). \)
Comparons la solution exacte et la solution approchée :
\(\begin{aligned} y_n&=\frac{g}{b}+\left( y_0 -\frac{g}{b}\right)e^{-bt_n}\\ u_n&=\frac{g}{b}+\left( y_0 -\frac{g}{b}\right)(1-hb)^n \end{aligned}\)
Pour que \(u_n\simeq y_n\) il faut que \((1-hb)^n\simeq e^{-bt_n} \in]0,1]\), donc il faut que \(0\le(1-hb)<1\), soit encore \(h<\frac{1}{b}\). Comme \(h=\frac{T-t_0}{N}=\frac{1}{N}\), cela implique \(N\ge b\). Dans cet exemple, pour obtenir une bonne convergence il est nĂ©cessaire de prendre un pas \(h\) de pus en plus petit que \(b\) est grand, câest-Ă -dire un coĂ»t en calcul plus Ă©levĂ©. On parle de problĂšme raide ou mal conditionnĂ©.
Code
phi = lambda t, y, b, g : -b*y+g
def EE(phi,tt,y0,b,g):
h = tt[1]-tt[0]
uu = np.zeros_like(tt)
uu[0] = y0
for i in range(len(tt)-1):
uu[i+1] = uu[i]+h*phi(tt[i],uu[i],b,g)
return uu
t0 = 0.
tfinal = 1.0
g = 40
b = 40
Y0 = [g/b, g/b+1.e-8]
NN = [19, 23, 45, 100]
plt.figure(figsize=(18, 7))
plt.subplot(1,2,1)
y0 = Y0[0]
for N in NN:
tt = np.linspace(t0,tfinal,N+1)
yy = EE(phi,tt,y0,b,g)
plt.plot(tt,yy,label=('$N=$'+str(N)+' noeuds'));
plt.title("Euler explicite, $g=b=$"+str(g)+ ", $y_0$="+str(y0))
plt.axis([0,1,g/b-1.e-8,g/b+1.e-8])
plt.legend()
plt.grid()
plt.subplot(1,2,2)
y0 = Y0[1]
for N in NN:
tt = np.linspace(t0,tfinal,N+1)
yy = EE(phi,tt,y0,b,g)
plt.plot(tt,yy,label=('$N=$'+str(N)+' noeuds'));
plt.title("Euler explicite, $g=b=$"+str(g)+ ", $y_0$="+str(y0))
plt.axis([0,1,g/b-1.e-8,g/b+1.e-8])
plt.legend()
plt.grid()
Correction : MĂ©thode dâEuler implicite
La mĂ©thode dâEuler implicite donne la suite dĂ©finie par rĂ©currence \(u_{n+1}=Au_n+B\) avec \(A=\frac{1}{1+bh}\) et \(B=\frac{gh}{1+bh}\), soit encore
\( \left( u_n-\frac{B}{1-A} \right) = \left( u_0-\frac{B}{1-A} \right) A^n \quad\leadsto\quad u_n-\frac{g}{b}=\frac{1}{(1+hb)^n}\left( y_0 -\frac{g}{b}\right). \)
Comparons la solution exacte et la solution approchée :
\(\begin{aligned} y_n&=\frac{g}{b}+\left( y_0 -\frac{g}{b}\right)e^{-bt_n}\\ u_n&=\frac{g}{b}+\left( y_0 -\frac{g}{b}\right)\left(\frac{1}{1+hb}\right)^n \end{aligned}\)
Pour que \(u_n\simeq y_n\) il faut que \(\frac{1}{(1+hb)^n}\simeq e^{-bt_n} \in]0,1]\), donc il faut que \(0\le\frac{1}{1+hb}<1\) câest-Ă -dire pour nâimporte quelle valeur de \(h\). Dans cet exemple, pour obtenir la convergence il nâest pas nĂ©cessaire de limiter le pas \(h\). Cependant, pour une edo quelconque, Ă chaque pas de temps on doit rĂ©soudre une Ă©quation non-linĂ©aire.
Code
phi = lambda t,y,b,g : -b*y+g
def EI(phi,tt,y0,b,g):
h = tt[1]-tt[0]
uu = np.zeros_like(tt)
uu[0] = y0
for i in range(len(tt)-1):
uu[i+1] = g/b + (y0-g/b)/(1+h*b)**i
uu[i+1] = fsolve(lambda x: x-uu[i]-h*phi(tt[i+1],x,b,g), uu[i])[0]
return uu
t0 = 0.
tfinal = 1
g = 40
b = 40
Y0 = [g/b,g/b+1.e-8]
NN = [19, 23, 45, 100]
plt.figure(figsize=(18,7))
plt.subplot(1,2,1)
y0 = Y0[0]
for N in NN:
tt = np.linspace(t0,tfinal,N+1)
yy = EI(phi,tt,y0,b,g)
plt.plot(tt,yy,label=('$N=$'+str(N)+' noeuds'));
plt.title("Euler implicite, $g=b=$"+str(g)+ ", $y_0$="+str(y0))
plt.axis([0,1,g/b-1.e-8,g/b+1.e-8])
plt.legend()
plt.grid()
plt.subplot(1,2,2)
y0 = Y0[1]
for N in NN:
tt = np.linspace(t0,tfinal,N+1)
yy = EI(phi,tt,y0,b,g)
plt.plot(tt,yy,'-*',label=('$N=$'+str(N)+' noeuds'));
plt.title("Euler implicite, $g=b=$"+str(g)+ ", $y_0$="+str(y0))
plt.axis([0,1,g/b-1.e-8,g/b+1.e-8])
plt.legend()
plt.grid()
Exercice : problÚme MAL conditionné
\( \begin{cases} y'(t)=-150y(t)+30\\ y(0)=\frac{1}{5}. \end{cases} \)
VĂ©rifier quâil est bien posĂ© mathĂ©matiquement et numĂ©riquement.
Que se passe-t-il si on utilise la mĂ©thode dâEuler explicite ?
Le problÚme de Cauchy donné admet une et une seule solution, la fonction constante \(y(t)=\frac{1}{5}\), il est donc bien posé mathématiquement.
Considérons le problÚme de Cauchy perturbé
\( \begin{cases} y_\varepsilon'(t)=-150y_\varepsilon(t)+30\\ y_\varepsilon(0)=\frac{1}{5}+\varepsilon. \end{cases} \)
La solution exacte \(y_\varepsilon\) est
\( \left( y_\varepsilon(t)+\frac{30}{-150} \right) = \left( y_\varepsilon(0)+\frac{30}{-150} \right) e^{-150t} \quad\leadsto\quad \left( y_\varepsilon(t)-\frac{1}{5} \right) = \left( y_\varepsilon(0)-\frac{1}{5} \right) e^{-150t} = \varepsilon e^{-150t}. \)
Si \(\varepsilon\to0\), alors \(y_{\varepsilon}(t)\to \frac{1}{5}\) : le problĂšme est numĂ©riquement bien posĂ©, car lâerreur sur la solution sera infĂ©rieure Ă lâerreur sur la condition initiale.
Code
# Calcul de la solution exacte
# ============================
t = sym.Symbol('t')
y = sym.Function('y')
edo = sym.Eq( sym.diff(y(t),t) , -150*y(t)+30 )
display(edo)
eps = sym.Symbol(r'\varepsilon')
t0, y0 = 0, sym.Rational(1,5)+eps
display(sym.Eq(y(t0),y0))
sol = sym.dsolve(edo,y(t), ics={y(t0):y0})
display(sol)
func = sym.lambdify((t,eps),sol.rhs,'numpy')
tt = np.linspace(0,1,101)
yy_eps = func(tt,0.01)
yy_0 = func(tt,0)
plt.figure(figsize=(8,5))
plt.plot(tt,yy_eps,label=r'$\varepsilon=0.01$')
plt.plot(tt,yy_0,label=r'$\varepsilon=0$')
plt.legend()
plt.grid()
\(\displaystyle \frac{d}{d t} y{\left(t \right)} = 30 - 150 y{\left(t \right)}\)
\(\displaystyle y{\left(0 \right)} = \varepsilon + \frac{1}{5}\)
\(\displaystyle y{\left(t \right)} = \varepsilon e^{- 150 t} + \frac{1}{5}\)
La mĂ©thode dâEuler implicite donne la suite dĂ©finie par rĂ©currence \(u_{n+1} = u_n+h(-150u_{n}+30) = au_n+b\) avec \(a=1-150h\) et \(b=30h\), soit encore
\(\begin{aligned} \left( u_n-\frac{b}{1-a} \right) = \left( u_0-\frac{b}{1-a} \right) a^n &\quad\leadsto\quad \left( u_n-\frac{30h}{150h} \right) = \left( u_0-\frac{30h}{150h} \right) (1-150h)^n \\ &\quad\leadsto\quad \left( u_n-\frac{1}{5} \right) = \left( u_0-\frac{1}{5} \right) (1-150h)^n. \end{aligned}\)
Comparons la solution exacte et la solution approchée :
\(\begin{aligned} y_n-\frac{1}{5} &= \varepsilon e^{-150t}\\ u_n-\frac{1}{5} &= \varepsilon (1-150h)^n \end{aligned}\)
Pour que \(u_n\simeq y_n\) il faut que \((1-150h)^n\simeq e^{-150(nh)} \in]0,1]\), donc il faut que \(|1-150h|<1\), câest-Ă -dire \(h<\frac{1}{75}\).
Exercice : problĂšme raide
Il existe des problĂšmes qui rĂ©sistent Ă toutes les mĂ©thodes usuelles. On trouve par exemple ces phĂ©nomĂšnes en chimie oĂč deux rĂ©actions ont des Ă©chelles de temps trĂšs diffĂ©rentes. ConsidĂ©rons par exemple \( \begin{cases} y'(t)=-1000\big(y(t)-e^{-t}\big)-e^{-t}, & t\in[0;1]\\ y(0)=0. \end{cases} \)
VĂ©rifier, en calculant la solution exacte, que le problĂšme est bien posĂ© mathĂ©matiquement et numĂ©riquement et quâil est raide.
Code
# Calcul de la solution exacte
# ============================
t = sym.Symbol('t')
y = sym.Function('y')
edo = sym.Eq( sym.diff(y(t),t) , -1000*(y(t)-sym.exp(-t))-sym.exp(-t) )
display(edo)
eps = sym.Symbol(r'\varepsilon')
t0, y0 = 0, 0+eps
display(sym.Eq(y(t0),y0))
sol = sym.dsolve(edo,y(t), ics={y(t0):y0})
display(sol.expand())
func = sym.lambdify((t,eps),sol.rhs,'numpy')
tt = np.linspace(0,1,501)
yy_1 = func(tt,1)
yy_eps = func(tt,0.01)
yy_0 = func(tt,0)
plt.figure(figsize=(8,5))
plt.plot(tt,yy_1,label=r'$\varepsilon=1$')
plt.plot(tt,yy_eps,'.',label=r'$\varepsilon=0.01$')
plt.plot(tt,yy_0,':',label=r'$\varepsilon=0$')
plt.legend()
plt.grid()
\(\displaystyle \frac{d}{d t} y{\left(t \right)} = - 1000 y{\left(t \right)} + 999 e^{- t}\)
\(\displaystyle y{\left(0 \right)} = \varepsilon\)
\(\displaystyle y{\left(t \right)} = \varepsilon e^{- 1000 t} + e^{- t} - e^{- 1000 t}\)
Le problĂšme est
- bien posé mathématiquement : il admet une et une seule solution, la fonction \(y(t)=e^{-t}\), définie sur \(\mathbb{R}\),
- bien posĂ© numĂ©riquement : lâerreur \(\varepsilon\) sur la donnĂ©e initiale est attĂ©nuĂ©e au cours du temps,
- raide : la solution exacte \(y(t)=e^{-t}-e^{-1000t}\) croit trÚs rapidement (\(-e^{-1000t}\)) sur un trÚs petit intervalle, puis elle décroit comme \(e^{-t}\). Notons que, si \(\varepsilon=1\), la solution est \(y(t)=e^{-t}\).
- Un problĂšme de Cauchy est mathĂ©matiquement bien posĂ© sâil existe une et une seule solution. Si ce nâest pas le cas, inutile de chercher Ă approcher la solution numĂ©riquement.
- Un problĂšme de Cauchy est numĂ©riquement bien posĂ© si la solution dâun problĂšme faiblement perturbĂ© (second membre ou condition initiale) possĂšde une solution proche de celle du problĂšme original. Si ce nâest pas le cas, on peut chercher Ă approcher la solution numĂ©riquement, mais câest dĂ©licat, car une petite erreur peut provoquer une trĂšs grande erreur sur la solution. Il faudra alors utiliser des mĂ©thodes numĂ©riques spĂ©cifiques (dâordre Ă©levĂ©).
- Un problĂšme de Cauchy est bien conditionnĂ© si les mĂ©thodes numĂ©riques usuelles peuvent donner sa solution en un nombre raisonnable dâopĂ©rations. Dans le cas contraire on parle de problĂšme raide (stiff). Si un problĂšme est raide, il faudra utiliser des mĂ©thodes numĂ©riques spĂ©cifiques (gĂ©nĂ©ralement des mĂ©thodes A-stable car on verra que câest grosso modo le mĂȘme problĂšme que pour les problĂšmes numĂ©riquement mal posĂ©s).
2 PARTIE 2ïžâŁ - propriĂ©tĂ©s dâun schĂ©ma dâapproximation : convergence, consistance, stabilitĂ©(s)
Rappelons ci-dessous la dĂ©finition de schĂ©ma convergent et de schĂ©ma consistant, avant dâintroduire la (les) notion(s) de stabilitĂ© dâun schĂ©ma.
2.1 Convergence et ordre de convergence
Définition: schéma convergent et ordre de convergence
Une méthode numérique est convergente si
\( |y_n-u_n|\le C(h)\xrightarrow[h\to0]{}0 \qquad\forall n=0,\dots,N \)
Si \(C(h) = \mathcal{O}(h^p)\) pour \(p > 0\), on dit que la convergence de la mĂ©thode est dâordre \(p\).
Pour Ă©tudier la convergence dâune mĂ©thode numĂ©rique, on exprime lâerreur \(e_{n+1}\) au pas \(t_{n+1}\) sous la forme :
\(\begin{aligned} e_{n+1} &\equiv y_{n+1} - u_{n+1} \\ &= (y_{n+1} - u_{n+1}^*) + (u_{n+1}^* - u_{n+1}), \\ &=h\tau_{n+1}(h) + (u_{n+1}^* - u_{n+1}), \qquad \tau_{n+1}(h) \equiv \frac{y_{n+1} - u_{n+1}^*}{h} \end{aligned}\)
\(u_{n+1}^*\) désignant la valeur obtenue en appliquant le schéma numérique à la solution exacte au temps \(t_{n+1}\).
Le terme \(h\tau_{n+1}(h) = y_{n+1} - u_{n+1}^*\) reprĂ©sente lâerreur engendrĂ©e par une seule itĂ©ration du schĂ©ma (erreur de consistance).
Le terme \(u_{n+1}^* - u_{n+1}\) reprĂ©sente la propagation de \(t_{n}\) Ă \(t_{n+1}\) de lâerreur accumulĂ©e au temps prĂ©cĂ©dent \(t_{n}\).
Si les deux termes \((y_{n+1} - u_{n+1}^*)\) et \((u_{n+1}^* - u_{n+1})\) tendent vers zéro lorsque \(h \to 0\), alors la méthode est convergente.
Exemple : convergence de la mĂ©thode dâEuler explicite
ConsidĂ©rons le problĂšme de Cauchy \(y'(t)=\varphi(t,y(y))\) pour \(t\in[t_0;T]\) et \(y(t_0)=y_0\). Supposons que la fonction \(\varphi\) soit lipschitzienne de constante \(L\) par rapport Ă sa deuxiĂšme variable. Nous allons montrer que la mĂ©thode dâEuler explicite
\( \begin{cases} u_0=y_0,\\ u_{n+1}=u_n+h\varphi(t_n,u_n),&n=0,\dots,N-1 \end{cases} \)
est convergente dâordre 1.
Pour cela, on Ă©tudie sĂ©parĂ©ment lâerreur de consistance et lâaccumulation de ces erreurs. On en dĂ©duit ensuite la convergence.
Terme \(h\tau_{n+1}(h)=y_{n+1} - u_{n+1}^*\) (erreur de consistance).
Il reprĂ©sente lâerreur engendrĂ©e par une seule itĂ©ration de la mĂ©thode dâEuler explicite :
\(\begin{aligned} y_{n+1}-u_{n+1}^* &=y_{n+1}-\Big(y_{n} + h\varphi(t_{n}, y_{n})\Big) \\ &=y(t_{n+1})-y(t_{n}) - h y'(t_n). \end{aligned}\)
En supposant que la dĂ©rivĂ©e seconde de \(y\) existe et est continue, on sait quâil existe un point \(\eta_n\) de lâintervalle \(]t_n;t_{n+1}[\) tel que
\( y(t_{n+1})=y(t_n)+hy'(t_n)+\frac{h^2}{2}y''(\eta_n) \)
(développement de Taylor de \(y\) au voisinage de \(t_n\) évalué en \(t_{n+1}\) avec reste de Lagrange). On a alors
\( y_{n+1}-u_{n+1}^* =y(t_{n+1})-y(t_{n}) - h y'(t_n)=\frac{h^2}{2}y''(\eta_n) \le \frac{M}{2}h^2 \xrightarrow[h\to0]{}0 \)
oĂč \(M\equiv\max_{t\in [t_0,T]}|y''(t)|\).
Terme \(u_{n+1}^* - u_{n+1}\) (accumulation des erreurs).
Il reprĂ©sente la propagation de \(t_{n}\) Ă \(t_{n+1}\) de lâerreur accumulĂ©e au temps prĂ©cĂ©dent \(t_{n}\). On a
\(\begin{aligned} u_{n+1}^* - u_{n+1} &= \Big(y_n + h \varphi(t_n, y_n)\Big)-\Big(u_n + h \varphi(t_n, u_n)\Big) \\ &=e_n+h\Big( \varphi(t_n,y_n)-\varphi(t_n,u_n) \Big). \end{aligned}\)
Comme \(\varphi\) est lipschitzienne par rapport Ă sa deuxiĂšme variable, on a
\(|\varphi(t_n,y_n)-\varphi(t_n,u_n)|\le L|y_n-u_n|=L|e_n|.\)
En factorisant on trouve alors
\( |u_{n+1}^{*} - u_{n+1}|\le (1 + hL)|e_{n}|. \)
Convergence.
Comme \(e_0 = 0\), les relations précédentes donnent
\(\begin{aligned} |e_n| & \le |y_n - u_n^*| + |u_n^* - u_n| \\ &\le h|\tau_n(h)| + (1+hL)|e_{n-1}| \\ &\le h|\tau_n(h)| + (1+hL)\left( h|\tau_{n-1}(h)| + (1+hL)|e_{n-2}| \right)| \\ &\le \left( 1+(1+hL)+\dots+(1+hL)^{n-1} \right)h\tau(h) \\ &= \left(\sum_{i=0}^{n-1}(1+hL)^i\right)h\tau(h) \\ &= \frac{(1+hL)^n-1}{hL}h\tau(h) \\ &\le \frac{(e^{hL})^n-1}{hL}h\tau(h) \qquad\text{car }(1+x)\le e^x \\ &= \frac{(e^{hL})^{(t_n-t_0)/h}-1}{L}\tau(h)\qquad\text{car } t_n-t_0=nh \\ &= \frac{e^{L(t_n-t_0)}-1}{L}\tau(h) \\ &= \frac{e^{L(t_n-t_0)}-1}{L}\frac{M}{2}h=\mathcal{O}(h) \end{aligned}\)
On peut conclure que la mĂ©thode dâEuler explicite est convergente dâordre 1.
Remarque : lâestimation de convergence est obtenue en supposant seulement \(\varphi\) lipschitzienne. On peut Ă©tablir une meilleure estimation si \(\partial_y\varphi\) existe et est non nĂ©gative pour tout \(t \in [t_0;T]\) et tout \(y\in\mathbb{R}\). En effet dans ce cas \(\begin{align*} u_n^* - u_n &= \left(y_{n-1} + h\varphi(t_{n-1}, y_{n-1})\right) - \left( u_{n-1} + h\varphi(t_{n-1},u_{n-1})\right) \\ &= e_{n-1}+h\left( \varphi(t_{n-1},y_{n-1})-\varphi(t_{n-1},u_{n-1}) \right) \\ &= e_{n-1}+h\left( e_{n-1}\partial_y\varphi(t_{n-1},\eta_n) \right) \\ &= \left( 1+h\partial_y\varphi(t_{n-1},\eta_n) \right)e_{n-1} \end{align*}\) oĂč \(\eta_n\) appartient Ă lâintervalle dont les extrĂ©mitĂ©s sont \(y_{n-1}\) et \(u_{n-1}\). Ainsi, si \( 0<h<\frac{2}{\max\limits_{t\in[t_0,T]}\partial_y\varphi(t,y(t))} \) alors \( |u_n^* - u_n |\le |e_{n-1}|. \) On en dĂ©duit \(|e_n| \le |y_n - u_n^*| + |e_{n-1}| \le nh\tau(h) + |e_0|\) et donc \( |e_n|\le M \frac{h}{2}(t_n-t_0). \) La restriction sur le pas de discrĂ©tisation \(h\) est une condition de stabilitĂ©, comme on le verra dans la suite.
ThĂ©orĂšme dâĂ©quivalence de Lax-Ritchmyer : consistance + zĂ©ro-stabilitĂ© = convergence
Un schéma consistant est convergent ssi il est zéro-stable.
2.2 Consistance et ordre de consistance
Définition : erreurs de troncature
Lâerreur de troncature locale est donnĂ©e par :
\( \tau_{n+1}(h) \equiv \frac{y_{n+1} - u_{n+1}^*}{h}. \)
Elle reprĂ©sente (Ă un facteur \(1/h\) prĂšs) lâerreur introduite en insĂ©rant la solution exacte dans le schĂ©ma numĂ©rique.
Lâerreur de troncature globale (ou simplement erreur de troncature) est dĂ©finie comme :
\( \tau(h) = \max_{n=0,\dots,N} |\tau_n(h)|. \)
Elle correspond Ă la borne supĂ©rieure de lâerreur de troncature locale sur lâensemble des pas de temps.
Définition : Consistance et ordre de consistance
- Une méthode numérique est dite consistante si \(\lim_{h\to0} \tau(h) = 0\).
- Elle est consistante dâordre \(p\) si lâerreur de troncature vĂ©rifie \(\tau(h) = \mathcal{O}(h^p)\), pour un certain \(p \geq 1\).
Remarque : La propriĂ©tĂ© de consistance est une condition nĂ©cessaire pour la convergence. En effet, sans consistance, la mĂ©thode introduirait Ă chaque itĂ©ration une erreur qui ne tendrait pas vers zĂ©ro lorsque \(h\) diminue. Lâaccumulation de ces erreurs empĂȘcherait alors lâerreur globale de sâannuler lorsque \(h \to 0\).
Remarque : lâordre de convergence coĂŻncide en gĂ©nĂ©ral avec lâordre de son erreur de troncature.
2.3 Deux notions de stabilité : zéro-stabilité et A-stabilité
De maniĂšre gĂ©nĂ©rale, un schĂ©ma numĂ©rique est considĂ©rĂ© comme stable sâil permet de maĂźtriser la solution lorsquâon perturbe les donnĂ©es. Il existe plusieurs notions de stabilitĂ©, nous allons en dĂ©tailler deux : la zĂ©ro-stabilitĂ© et lâA-stabilitĂ©.
Prenons le problÚme de Cauchy, supposé mathématiquement et numériquement bien posé :
\( \begin{cases} y'(t) = \varphi(t,y(t)), &\forall t \in I=]t_0,T[,\\ y(t_0) = y_0. \end{cases} \)
Deux questions naturelles se posent alors :
- Que se passe-t-il lorsque lâon fixe le temps final \(T\) et que lâon fait tendre le pas \(h\) vers \(0\) ?
- Que se passe-t-il lorsque lâon fixe le pas \(h>0\) et que lâon fait tendre \(T\) vers lâinfini ?
Dans ces deux cas, le nombre de nĆuds tend vers lâinfini, mais les enjeux diffĂšrent : dans le premier cas, on sâintĂ©resse Ă lâerreur en chaque point, tandis que dans le second, il sâagit du comportement asymptotique de la solution approchĂ©e.
Ces deux problématiques font intervenir deux notions de stabilité :
Zéro-stabilité
Elle concerne la rĂ©solution du problĂšme de Cauchy sur des intervalles bornĂ©s (le nombre \(N\) de sous-intervalles ne tend vers lâinfini que lorsque \(h\) tend vers zĂ©ro).
Elle garantit que la mĂ©thode numĂ©rique est peu sensible aux petites perturbations des donnĂ©es. Si la mĂ©thode numĂ©rique nâest pas zĂ©ro-stable, les erreurs dâarrondi sur \(y_0\) et le calcul de \(\varphi(t_n,y_n)\) rendent la solution calculĂ©e inutilisable.A-stabilitĂ©
Dans certaines situations, le problĂšme de Cauchy doit ĂȘtre rĂ©solu sur des intervalles de temps trĂšs longs, voire infinis. Ici, mĂȘme pour un \(h\) fixĂ©, le nombre \(N\) de sous-intervalles tend vers lâinfini. On recherche alors des mĂ©thodes capables dâapprocher la solution sur des intervalles de temps arbitrairement grands.
IdĂ©alement, on souhaiterait utiliser des pas de temps \(h\) suffisamment grands (une mĂ©thode est dite inconditionnellement A-stable si lâon peut choisir \(h>0\) sans restriction ; sinon, une condition de stabilitĂ© sur \(h\) dĂ©terminera le temps de calcul).
2.3.1 Ătude de la zĂ©ro-stabilitĂ© (dans \(\mathbb{R}\)) pour les schĂ©mas Ă un pas
La zéro-stabilité garantit que, sur un intervalle borné, de petites perturbations des données entraßnent des perturbations contrÎlées de la solution numérique lorsque \(h\to0\).
Plus précisément, une méthode numérique visant à approcher le problÚme de Cauchy sur un intervalle fini \(I=[t_0,T]\) est dite zéro-stable si les conditions suivantes sont satisfaites :
\( \exists h_0>0,\ \exists C>0,\ \exists \varepsilon_0>0\ \text{tels que}\ \forall h\in]0,h_0],\ \forall \varepsilon\in]0,\varepsilon_0],\ \text{si } |\varrho_n| \le \varepsilon,\ 0 \le n \le N, \)
alors
\( |z_n - u_n| \le C\varepsilon,\ 0 \le n \le N \)
oĂč : - \(C\) est une constante indĂ©pendante de \(h\), - \(u_n\) est la solution obtenue par le schĂ©ma numĂ©rique sans perturbation, - \(z_n\) est la solution obtenue par le mĂȘme schĂ©ma appliquĂ© au problĂšme perturbĂ©, - \(\varrho_n\) reprĂ©sente la perturbation au \(n\)-iĂšme pas, - \(\varepsilon_0\) est la perturbation maximale admissible.
Il est important de noter que \(\varepsilon_0\) doit ĂȘtre suffisamment petit pour que le problĂšme perturbĂ© conserve une solution unique sur lâintervalle dâintĂ©gration considĂ©rĂ©.
Dans le cas dâune mĂ©thode consistante Ă un pas, on peut dĂ©montrer que la zĂ©ro-stabilitĂ© dĂ©coule du fait que \(\varphi\) est lipschitzienne par rapport Ă sa seconde variable. Dans ce contexte, la constante \(C\) dĂ©pend de \(\exp((T-t_0)L)\), oĂč \(L\) est la constante de Lipschitz. Toutefois, cette propriĂ©tĂ© nâest pas nĂ©cessairement vĂ©rifiĂ©e pour dâautres familles de mĂ©thodes numĂ©riques.
Exemple : zĂ©ro-stabilitĂ© de la mĂ©thode dâEuler explicite
ConsidĂ©rons \(u_n\) comme lâapproximation obtenue avec la mĂ©thode dâEuler explicite pour le problĂšme initial :
\( \begin{cases} u_0 = y_0, \\ u_{n+1} = u_n + h\varphi(t_n, u_n), & n = 0, \dots, N - 1 \end{cases} \)
et \(z_n\) comme lâapproximation obtenue avec la mĂ©thode dâEuler explicite pour le problĂšme perturbĂ© :
\( \begin{cases} z_0 = y_0 + \varrho_0, \\ z_{n+1} = z_n + h\left(\varphi(t_n, z_n) + \varrho_n\right), & n = 0, \dots, N - 1 \end{cases} \)
Nous avons alors :
\(\begin{align} |u_n - z_n| &\le |u_{n-1} - z_{n-1}| + h|\varphi(t_{n-1}, u_{n-1}) - \varphi(t_{n-1}, z_{n-1})| + h|\varrho_n| \\ &\le (1 + hL)|u_{n-1} - z_{n-1}| + h\varepsilon \\ &\le (1 + hL)^2|u_{n-2} - z_{n-2}| + (1 + (1 + hL))h\varepsilon \\ &\vdots \\ &\le (1 + hL)^n|\varrho_0| + \left(1 + (1 + hL) + \dots + (1 + hL)^{n-1}\right)h\varepsilon \\ &= (1 + hL)^n|\varrho_0| + \left(\sum_{i=0}^{n-1}(1 + hL)^i\right)h\varepsilon \\ &= (1 + hL)^n|\varrho_0| + \frac{(1 + hL)^n - 1}{L}\varepsilon \\ &\le (e^{hL})^n|\varrho_0| + \frac{(e^{hL})^n - 1}{hL}h\varepsilon \qquad\text{car } (1 + x) \le e^x \\ &= e^{nhL}|\varrho_0| + \frac{e^{nhL} - 1}{L}\varepsilon \\ &\le \left(e^{nhL} + \frac{e^{nhL} - 1}{L}\right)\varepsilon \\ &= \frac{(1 + L)e^{L(T - t_0)} - 1}{L}\varepsilon \qquad\text{car } t_n - t_0 = nh \end{align}\)
Ainsi, nous avons montrĂ© que la mĂ©thode dâEuler explicite est zĂ©ro-stable.
2.3.2 Ătude de la A-stabilitĂ© (dans \(\mathbb{R}\)) pour les schĂ©mas Ă un pas
Dans la section prĂ©cĂ©dente, nous avons Ă©tudiĂ© la rĂ©solution du problĂšme de Cauchy sur des intervalles bornĂ©s. Dans ce contexte, le nombre \(N\) de sous-intervalles ne tend vers lâinfini que lorsque \(h\) tend vers zĂ©ro.
Cependant, il existe de nombreuses situations oĂč le problĂšme de Cauchy doit ĂȘtre rĂ©solu sur des intervalles de temps trĂšs longs, voire infinis. Dans ces cas-lĂ , mĂȘme pour un \(h\) fixĂ©, \(N\) tend vers lâinfini, rendant la notion de zĂ©ro-stabilitĂ© inapplicable puisque \(T - t_0 \to +\infty\).
On cherche donc des mĂ©thodes capables dâapprocher la solution sur des intervalles de temps arbitrairement grands, y compris avec des pas de temps \(h\) relativement grands.
Définition : A-stabilité dans \(\mathbb{R}\)
Soit \(\beta > 0\) un réel positif et considérons le problÚme de Cauchy (modÚle simplifié = toy-model) :
\(\begin{cases} y'(t) = -\beta y(t), &\text{pour } t > 0, \\ y(0) = y_0 \end{cases}\)
oĂč \(y_0 \neq 0\) est une valeur initiale donnĂ©e. La solution exacte est \(y(t) = y_0 e^{-\beta t}\), dâoĂč :
\(\lim_{t \to +\infty} y(t) = 0.\)
Considérons un pas de temps fixé \(h > 0\) et définissons \(t_n = nh\) pour \(n \in \mathbb{N}\). Notons \(u_n \approx y(t_n)\) une approximation de la solution \(y\) au temps \(t_n\).
Si, sous dâĂ©ventuelles conditions sur \(h\), on a
\( \lim_{n \to +\infty} u_n = 0, \)
alors on dit que le schéma est A-stable.
Remarques :
- Des conclusions similaires restent valables lorsque \(\beta\) est un nombre complexe ou une fonction positive de \(t\) (ce cas sera traité dans la section suivante).
- Ă premiĂšre vue, lâexigence dâune stabilitĂ© absolue pour une mĂ©thode numĂ©rique appliquĂ©e Ă un autre problĂšme que le toy-model peut sembler superflue. Cependant, il est possible de dĂ©montrer que si une mĂ©thode est absolument stable pour le toy-model, alors, lorsquâelle est appliquĂ©e Ă un problĂšme plus gĂ©nĂ©ral, lâerreur de perturbation (câest-Ă -dire la diffĂ©rence absolue entre la solution perturbĂ©e et la solution non perturbĂ©e) reste uniformĂ©ment bornĂ©e par rapport Ă \(h\).
En dâautres termes, une mĂ©thode absolument stable selon la dĂ©finition appliquĂ©e au toy-model garantit un contrĂŽle des perturbations mĂȘme dans des contextes plus gĂ©nĂ©raux.
2.3.2.1 A-stabilitĂ© dâun systĂšme et problĂšmes raides
Cette dĂ©finition peut ĂȘtre gĂ©nĂ©ralisĂ©e Ă un systĂšme de \(n\) EDO de la forme
\( \mathbf{y}'(t) = -\mathbb{A}\mathbf{y}(t) \)
oĂč \(\mathbb{A}\) est une matrice constante ayant \(n\) valeurs propres positives \(\lambda_i\), \(i = 1, 2, \dots, n\).
La solution sâĂ©crit
\( \mathbf{y}(t) = \sum_i c_i \mathbf{v}_i e^{-\lambda_i t} \)
oĂč \(\mathbf{v}_i\) est le \(i\)-Ăšme vecteur propre associĂ© Ă la valeur propre \(\lambda_i\). On a donc :
\( \lim_{t \to +\infty} y_i(t) = 0 \quad \forall i = 1, 2, \dots, n. \)
SystĂšmes raides (stiff systems) : un systĂšme dâĂ©quations diffĂ©rentielles est dit raide lorsque les valeurs propres \(\lambda_i\) de la matrice \(\mathbb{A}\) prĂ©sentent des magnitudes trĂšs diffĂ©rentes. En dâautres termes, si certaines valeurs propres sont beaucoup plus grandes que dâautres, alors le systĂšme Ă©volue selon des Ă©chelles de temps trĂšs variĂ©es. Cette diffĂ©rence de magnitudes crĂ©e un dĂ©fi pour les mĂ©thodes numĂ©riques : pour garantir la A-stabilitĂ©, il est parfois nĂ©cessaire de choisir un pas de temps \(h\) suffisamment petit, proportionnel au plus grand \(\lambda_i\). Cela peut rendre les calculs trĂšs coĂ»teux lorsque les valeurs propres sont trĂšs disparates. En revanche, les mĂ©thodes inconditionnellement A-stables sont prĂ©fĂ©rĂ©es pour les systĂšmes raides, car elles permettent dâutiliser des pas de temps plus grands tout en maintenant la A-stabilitĂ©, indĂ©pendamment du plus grand \(\lambda_i\).
2.3.2.2 Exemples et exercices sur la A-stabilité
Exemple : Ă©tude de lâA-stabilitĂ© du schĂ©ma dâEuler explicite
Le schĂ©ma dâEuler progressif appliquĂ© au toy-model (\(\varphi(t,y)=-\beta y\)) sâĂ©crit
\( u_{n+1}=(1-\beta h)u_n, \qquad n=0,1,2,\dots \)
et par suite
\( u_{n}=(1-\beta h)^nu_0, \qquad n=0,1,2,\dots \)
Par conséquente, \(\lim\limits_{n\to+\infty}u_n=0\) si et seulement si
\( \left|1-\beta h\right|<1, \)
ce qui a pour effet de limiter \(h\) Ă
\( \boxed{h<\frac{2}{\beta}.} \)
Cette condition de A-stabilitĂ© limite le pas \(h\) dâavance en \(t\) lorsquâon utilise le schĂ©ma dâEuler progressif.
Remarques :
- Cette convergence est monotone ssi \(1-\beta h>0\), i.e. ssi \(h<\frac{1}{\beta}\) (bien plus restrictif que la condition de A-stabilité).
- Notons que si \(1-\beta h>1\) alors \(u_n\) tend vers \(+\infty\) lorsque \(t\) tend vers lâinfini et si \(1-\beta h<-1\) alors \(u_n\) tend vers lâinfini en alternant de signe lorsque \(t\) tend vers lâinfini. Nous dirons dans ces cas que le schĂ©ma dâEuler progressif est instable.
- Dans le cas du systĂšme, le schĂ©ma dâEuler progressif est A-stable ssi \(h<\frac{2}{\lambda_\text{max}}\).
Exercice : Ă©tudier lâA-stabilitĂ© du schĂ©ma dâEuler implicite
\( \begin{cases} u_0 = y_0,\\ u_{n+1} = u_{n}+h \varphi_{n+1}, & n=0,1,\dots,N-1. \end{cases} \)
Le schĂ©ma dâEuler rĂ©trograde devient dans le cadre de notre exemple \( (1+\beta h)u_{n+1}=u_n, \qquad n=0,1,2,\dots \) et par suite \( u_{n}=\frac{1}{(1+\beta h)^{n}}u_0, \qquad n=0,1,2,\dots \) Dans ce cas nous voyons que pour tout \(h>0\) nous avons \(\lim_{n\to\infty}u_n=0\), le schĂ©ma dâEuler rĂ©trograde est donc toujours stable, sans limitations sur \(h\).
Exercice : Ă©tudier lâA-stabilitĂ© du schĂ©ma dâEuler modifiĂ©
\( \begin{cases} u_0 = y_0,\\ u_{n+1} = u_{n}+h \varphi\left(t_n+\frac{h}{2},u_n+\frac{h}{2}\varphi_n\right), & n=0,1,\dots,N-1. \end{cases} \)
Le schĂ©ma dâEuler modifiĂ© pour notre exemple devient \( u_{n+1}=u_n+h\left( -\beta\left( u_n+\frac{h}{2}(-\beta u_n) \right) \right) =\left(1-\beta h +\frac{(\beta h )^2}{2} \right) u_{n} \) Par induction on obtient \( u_{n}=\left(1-\beta h +\frac{(\beta h )^2}{2} \right)^nu_0. \) Par consĂ©quent, \(\lim\limits_{n\to+\infty}u_n=0\) si et seulement si \( \left| 1 - \beta h +\frac{1}{2}(\beta h)^2 \right|<1. \) Notons \(x\) le produit \(\beta h\) et \(q\) le polynĂŽme \(q(x)=\frac{1}{2}x^2-x+1\) dont le graphe est reprĂ©sentĂ© en figure:
Code
Nous avons \(|q(x)|<1\) si et seulement si \(0<x<2\). La relation \(\lim\limits_{n\to+\infty}u_n=0\) est donc satisfaite si et seulement si \( \boxed{ h <\frac{2}{\beta}. } \) Cette condition de stabilitĂ© limite le pas \(h\) dâavance en \(t\) lorsquâon utilise le schĂ©ma dâEuler modifiĂ©.
Notons quâon a la mĂȘme condition de A-stabilitĂ© que le schĂ©ma dâEuler explicite. Cependant, \(q(x)>0\) pour tout \(x\), donc cette convergence est monotone (tandis quâavec le schĂ©ma dâEuler explicite la convergence nâest monotone que si \(h<\frac{1}{\beta}\)).
Exercice : Ă©tudier lâA-stabilitĂ© du schĂ©ma de Cranck-Nicolson
\( \begin{cases} u_0 = y_0,\\ u_{n+1} = u_{n}+\frac{h}{2}\left(\varphi_n+\varphi_{n+1}\right), & n=0,1,\dots,N-1. \end{cases} \)
Le schĂ©ma de Crank-Nicolson appliquĂ© Ă notre exemple sâĂ©crit \(
\left(1+\frac{\beta h}{2}\right)u_{n+1} = \left(1-\frac{\beta h}{2}\right) u_{n}
\) et par suite \(
u_{n}=\left( \frac{2-\beta h}{2+\beta h} \right)^{n}u_0, \qquad n=0,1,2,\dots
\) Par conséquent, \(\lim\limits_{n\to+\infty}u_n=0\) si et seulement si \(
\left|\frac{2-\beta h}{2+\beta h}\right|<1.
\) Notons \(x\) le produit \(\beta h>0\) et \(q\) la fonction \(q(x)=\frac{2-x}{2+x}=1-2\frac{x}{2+x}\). Nous avons \(0<\frac{x}{2+x}<1\) pour tout \(x\in\mathbb{R}_+^*\), donc \(|q(x)|<1\) pour tout \(x\in\mathbb{R}_+^*\). La relation \(\lim\limits_{n\to+\infty}u_n=0\) est donc satisfaite pour tout \(h>0\): le schéma de Crank-Nicolson est donc toujours stable, sans limitations sur \(h\).
Cependant, si on cherche \(0<q<1\) on a (pour \(x>0\)) \(
1-2\frac{x}{2+x}>0
\iff
x<2.
\)
Code
Exercice : Ă©tudier lâA-stabilitĂ© du schĂ©ma de Heun
Le schéma de Heun pour notre exemple devient \(
u_{n+1} =u_n+\frac{h}{2}\left( -\beta u_n-\beta\left( u_n+h(-\beta u_n) \right) \right) =\left(1-\beta h +\frac{(\beta h )^2}{2} \right) u_{n}
\) ce qui coĂŻncide avec la mĂ©thode dâEuler modifiĂ©e. Par consĂ©quent, \(\lim\limits_{n\to+\infty}u_n=0\) si et seulement si \(
\boxed{ h <\frac{2}{\beta} }
\) et cette convergence est monotone.
Cette condition de stabilitĂ© limite le pas \(h\) dâavance en \(t\) lorsquâon utilise le schĂ©ma de Heun.
Exercice : Ă©tudier lâA-stabilitĂ© du schĂ©ma de Simpson implicite
Le schĂ©ma de Simpson implicite appliquĂ© Ă notre exemple sâĂ©crit \( \left(1+\beta\frac{h}{6}\right)u_{n+1} = \left(1-\frac{5}{6}\beta h+\frac{1}{3}(\beta h)^2\right) u_{n} \) et par suite \( u_{n}=\left( \frac{ 1-\frac{5}{6}\beta h+\frac{1}{3}(\beta h)^2 }{ 1+\beta\frac{h}{6} } \right)^{n}u_0, \qquad n=0,1,2,\dots \) Par consĂ©quent, \(\lim\limits_{n\to+\infty}u_n=0\) si et seulement si \( \left|\frac{ 6-5\beta h+2(\beta h)^2 }{ 6+\beta h }\right|<1. \) Notons \(x\) le produit \(\beta h>0\) et \(q\) la fonction \(q(x)=\frac{6-5x+2x^2}{6+x}\) dont le graphe est reprĂ©sentĂ© en figure.
Code
Nous avons \(q(x)>0\) pour tout \(x\in\mathbb{R}_+^*\) et \(q(x)<1\) si et seulement si \(x<3\), donc \(|q(x)|<1\) pour tout \(x\in]0;3[\). Par consĂ©quent, \(\lim\limits_{n\to+\infty}u_n=0\) si et seulement si \( h <\frac{3}{\beta}. \) Cette condition de stabilitĂ© limite le pas \(h\) dâavance en \(t\).
Exercice : Ă©tudier lâA-stabilitĂ© du schĂ©ma de Simpson explicite
Le schéma de Simpson explicite pour notre exemple devient \( u_{n+1} = u_n+\frac{h}{6}\left( -\beta u_n -4 \beta\left( u_n+\frac{h}{2}(-\beta u_n) \right) -\beta\left( u_n+h(-\beta u_n) \right) \right) =\left(1-\beta h +\frac{3}{2}(\beta h )^2 \right) u_{n} \) Par induction on obtient \( u_{n}=\left(1-\beta h +\frac{3}{2}(\beta h )^2 \right)^nu_0. \) Par conséquent, \(\lim\limits_{n\to+\infty}u_n=0\) si et seulement si \( \left|1-\beta h +\frac{3}{2}(\beta h )^2\right|<1. \) Notons \(x\) le produit \(\beta h\) et \(q\) le polynÎme \(q(x)=\frac{3}{2}x^2-x+1\) dont le graphe est représenté en figure.
Code
Nous avons \(|q(x)|<1\) si et seulement si \(0<x<\frac{2}{3}\). La relation \(\lim\limits_{n\to+\infty}u_n=0\) est donc satisfaite si et seulement si \( h <\frac{2}{3\beta}. \) Cette condition de stabilitĂ© limite le pas \(h\) dâavance en \(t\).
2.4 Tableau récapitulatif, implémentation des schémas et tests
\( \begin{array}{|c|c|c|c|c|c|} \hline \text{Acronyme} & \text{Schéma} & \text{Type} & \text{Ordre} & \text{A-stabilité} & \text{Positivité} \\ \hline \text{EE} & u_{n+1} = u_n + h\varphi_n & \text{Explicite} & 1 & 0 < h < \frac{2}{\beta} & 0 < h < \frac{1}{\beta} \\ \text{EI} & u_{n+1} = u_n + h\varphi_{n+1} & \text{Implicite} & 1 & \forall h > 0 & \forall h > 0 \\ \text{EM} & u_{n+1} = u_n + h\varphi\left(t_n + \frac{h}{2}, u_n + \frac{h}{2}\varphi_n\right) & \text{Explicite} & 2 & 0 < h < \frac{2}{\beta} & 0 < h < \frac{2}{\beta} \\ \text{CN} & u_{n+1} = u_n + \frac{h}{2}\left(\varphi_n + \varphi_{n+1}\right) & \text{Implicite} & 2 & \forall h > 0 & 0 < h < \frac{2}{\beta} \\ \text{H} & u_{n+1} = u_n + \frac{h}{2}\left(\varphi_n + \varphi(t_{n+1}, u_n + h\varphi_n)\right) & \text{Explicite} & 2 & 0 < h < \frac{2}{\beta} & 0 < h < \frac{2}{\beta} \\ \hline \end{array} \)
Exercice : tester numĂ©riquement lâA-stabilitĂ© des schĂ©mas classiques Ă un pas
On considĂšre le toy-model avec \(\beta=1\) et on teste numĂ©riquement lâA-stabilitĂ© des schĂ©mas dâEuler explicite, dâEuler implicite, dâEuler modifiĂ©, de Crank-Nicolson et de Heun.
\( \begin{cases} y'(t)=-y(t), & t\in[0;12]\\ y(0)=1. \end{cases}\)
Calculer la solution exacte. Calculer ensuite la solution approchée par les schémas pour différentes valeurs de \(h\). Vérifier que les conditions de stabilité sont respectées.
Solution exacte
Lâunique solution du problĂšme de Cauchy est la fonction \(y(t)=e^{-t}\) dĂ©finie pour tout \(t\) \(\in\) \(\mathbb{R}\).
Code
phi = lambda t,y : -y
sol_exacte = lambda t : np.exp(-t)
# INITIALISATION
t0, y0, tfinal = 0 , 1 , 12
# PREPARATIONS DES CAS TEST pour différentes valeurs de h
H = [ 2**(k-2) for k in range(5) ]
T = [ np.arange(t0,tfinal,h) for h in H] # liste des grilles
yy = sol_exacte(T[0]) # on affichera la sol exacte sur la grille la plus fine
Solution approchĂ©e par la mĂ©thode dâEuler explicite
La mĂ©thode dâEuler explicite pour cette EDO sâĂ©crit
\( u_{n+1}=(1-h)u_n. \)
En procédant par récurrence sur \(n\), on obtient
\( u_{n+1}=(1-h)^{n+1}. \)
De la formule \(u_{n+1}=(1-h)^{n+1}\) on déduit que
- si \(0<h<1\) alors la solution numérique est stable et convergente,
- si \(h=1\) alors la solution numérique est stationnaire \(u_n=0\) pour tout \(n\in\mathbb{N}^*\),
- si \(1<h<2\) alors la solution numérique oscille mais est encore convergente,
- si \(h=2\) alors la solution numérique oscille, plus précisément on a \(u_{2n}=1\) et \(u_{2n+1}=-1\) pour tout \(n\in\mathbb{N}^*\),
- si \(h>2\) alors la solution numérique oscille et diverge.
En effet, la méthode est A-stable si et seulement si \(|1 - h| < 1\).
Remarque : la suite obtenue est une suite gĂ©omĂ©trique de raison \(q=1-h\). On sait quâune telle suite
- diverge si \(|q|>1\) ou \(q=-1\),
- est stationnaire si \(q=1\),
- converge vers \(0\) si \(|q|<1\).
- converge de façon monotone vers \(0\) si \(0<q<1\).
Voyons graphiquement ce que cela donne avec différentes valeurs de \(h>0\) :
- si \(h=4\) alors \(t_n=4n\) et \(u_{n}=\left(-4\right)^{n}\) tandis que \(y(t_{n})=e^{-4n}\),
- si \(h=2\) alors \(t_n=2n\) et \(u_{n}=\left(-1\right)^{n}\) tandis que \(y(t_{n})=e^{-2n}\),
- si \(h=1\) alors \(t_n=n\) et \(u_{n}=0\) tandis que \(y(t_{n})=e^{-n}\),
- si \(h=\frac{1}{2}\) alors \(t_n=\frac{n}{2}\) et \(u_{n}=\left(\dfrac{1}{2}\right)^{n}\) tandis que \(y(t_{n})=e^{-n/2}\),
- si \(h=\frac{1}{4}\) alors \(t_n=\frac{n}{4}\) et \(u_{n}=\left(\dfrac{3}{4}\right)^{n}\) tandis que \(y(t_{n})=e^{-n/4}\).
Ci-dessous sont tracĂ©es sur lâintervalle \([0;10]\), les courbes reprĂ©sentatives de la solution exacte et de la solution calculĂ©e par la mĂ©thode dâEuler explicite. En faisant varier le pas \(h\) nous pouvons constater que si \(h>1\) lâerreur commise entre la solution exacte et la solution calculĂ©e est amplifiĂ©e dâun pas Ă lâautre.
Remarque : la premiĂšre itĂ©rĂ©e a la mĂȘme pente quel que soit le pas \(h\) (se rappeler la construction gĂ©omĂ©trique de la mĂ©thode dâEuler).
Code
# SCHEMA
def EE(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros_like(tt)
uu[0] = y0
for i in range(len(tt)-1):
uu[i+1] = uu[i]+h*phi(tt[i],uu[i])
return uu
# CALCUL DE LA SOLUTION SUR CHAQUE GRILLE
U = [ EE(phi,tt,y0) for tt in T ]
# AFFICHAGE
plt.figure(1, figsize=(15, 10))
plt.axis([t0, tfinal, -1, 1])
plt.plot(T[0],yy,'-',label='$y(t)=e^{-t}$')
for k in range(5):
plt.plot(T[k],U[k],'-o',label=f'h = {</span>H[k]<span class="sc">}')
plt.legend()
plt.grid();
Solution approchĂ©e par la mĂ©thode dâEuler implicite
La mĂ©thode dâEuler implicite pour cette EDO sâĂ©crit
\( u_{n+1}=\frac{1}{1+h}u_n. \)
En procédant par récurrence sur \(n\), on obtient
\( u_{n+1}=\frac{1}{(1+h)^{n+1}}. \)
De la formule \(u_{n+1}=(1+h)^{-(n+1)}\) on déduit que la solution numérique est stable et convergente pour tout \(h\). En effet, la méthode est inconditionnellement A-stable.
Remarque : la suite obtenue est une suite géométrique de raison \(q=\frac{1}{1+h}\in]0;1[\).
Code
# SCHEMA
def EI(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros_like(tt)
uu[0] = y0
for i in range(len(tt)-1):
uu[i+1] = fsolve(lambda x:-x+uu[i]+h*phi(tt[i+1],x),uu[i])[0]
return uu
# CALCUL DE LA SOLUTION SUR CHAQUE GRILLE
U = [ EI(phi,tt,y0) for tt in T ]
# AFFICHAGE
plt.figure(1, figsize=(15, 10))
plt.axis([t0, tfinal, -1, 1])
plt.plot(T[0],yy,'-',label='$y(t)=e^{-t}$')
for k in range(5):
plt.plot(T[k],U[k],'-o',label=f'h = {</span>H[k]<span class="sc">}')
plt.legend()
plt.grid();
Solution approchĂ©e par la mĂ©thode dâEuler modifiĂ©
La mĂ©thode dâEuler modifiĂ© pour cette EDO sâĂ©crit
\( u_{n+1}=(1-h+\frac{1}{2}h^2)u_n. \)
En procédant par récurrence sur \(n\), on obtient
\( u_{n+1}=(1-h+\frac{1}{2}h^2)^{n+1}. \)
La suite obtenue est une suite géométrique de raison \(q=1-h+\frac{1}{2}h^2\):
- si \(0<h<2\) alors la solution numérique est stable et convergente,
- si \(h=2\) alors la solution numérique est stationnaire \(u_n=u_0\) pour tout \(n\in\mathbb{N}^*\),
- si \(h>2\) alors la solution numérique diverge vers \(+\infty\).
En effet, la méthode est A-stable si et seulement si \(|1-h+\frac{1}{2}h^2| < 1\). De plus, comme \(1-h+\frac{1}{2}h^2>0\) pour tout \(h>0\), la suite est positive.
Code
# SCHEMA
def EM(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros_like(tt)
uu[0] = y0
for i in range(len(tt)-1):
utilde = uu[i]+h/2*phi(tt[i],uu[i])
uu[i+1] = uu[i]+h*phi(tt[i]+h/2,utilde)
return uu
# CALCUL DE LA SOLUTION SUR CHAQUE GRILLE
U = [ EM(phi,tt,y0) for tt in T ]
# AFFICHAGE
plt.figure(1, figsize=(15, 10))
plt.axis([t0, tfinal, -1, 2])
plt.plot(T[0],yy,'-',label='$y(t)=e^{-t}$')
for k in range(5):
plt.plot(T[k],U[k],'-o',label=f'h = {</span>H[k]<span class="sc">}')
plt.legend()
plt.grid();
Solution approchée par la méthode de Crank-Nicolson
La mĂ©thode de Crank-Nicolson pour cette EDO sâĂ©crit
\( u_{n+1}=\frac{2-h}{2+h}u_n. \)
En procédant par récurrence sur \(n\), on obtient
\( u_{n+1}=\left(\frac{2-h}{2+h}\right)^{n+1}. \)
La suite obtenue est une suite géométrique de raison \(q=\frac{2-h}{2+h}\in]-1;1[\). On déduit que la solution numérique est stable et convergente pour tout \(h\). En effet, la méthode est inconditionnellement A-stable.
De plus, la suite est positive ssi \(0<q<1\) donc ssi \(h<2\).
Code
# SCHEMA
def CN(phi,tt,y0):
h = tt[1]-tt[0]
uu = np.zeros_like(tt)
uu[0] = y0
for i in range(len(tt)-1):
uu[i+1] = fsolve(lambda x:-x+uu[i]+h/2*phi(tt[i],uu[i])+h/2*phi(tt[i+1],x),uu[i])[0]
return uu
# CALCUL DE LA SOLUTION SUR CHAQUE GRILLE
U = [ CN(phi,tt,y0) for tt in T ]
# AFFICHAGE
plt.figure(1, figsize=(15, 10))
plt.axis([t0, tfinal, -1, 1])
plt.plot(T[0],yy,'-',label='$y(t)=e^{-t}$')
for k in range(5):
plt.plot(T[k],U[k],'-o',label=f'h = {</span>H[k]<span class="sc">}')
plt.legend()
plt.grid();
Solution approchée par la méthode de Heun
La mĂ©thode de Heun pour cette EDO sâĂ©crit
\( u_{n+1}=(1-h+\frac{1}{2}h^2)u_n. \)
On retrouve le schĂ©ma dâEuler modifiĂ©.