2021 CC v1 : le sujet comporte deux exercices indépendents.
1 2021 CC v1 : le sujet comporte deux exercices indépendents.
1.1 Exercice 1 : implémentation d’un schéma pour un système
Le modèle S.I.R. a été présenté pour la première fois par KERMACK & McKENDRICK à Londres et Cambridge en 1927 pour expliquer a posteriori l’évolution de l’épidémie de peste à Bombay en 1905-1906.
A chaque instant on décide de diviser la population en trois catégories (qu’on appelle « compartiments » dans le langage de l’épidémiologie): - les individus « Susceptibles » ou « Sains » (S) : ceux qui n’ont jamais eu la maladie et peuvent la contracter ; - les individus « Infectés » (I) : les malades, ce sont aussi les contagieux (c’est une hypothèse de ce modèle) ; - les individus « Rétablis » (R, comme « Recovered » en anglais) : ceux qui ont déjà eu la maladie et sont désormais immunisés contre cette maladie. Dans ce modèle on inclut dans ce groupe les personnes décédées (puisqu’elles ne peuvent plus contracter la maladie).
On travaillera avec des variables normalisées: leur valeur est comprise entre 0 et 1 et représente une fraction de la population totale (P).
Le modèle s’écrit {S′(t)=−βS(t)I(t)I′(t)=βS(t)I(t)−νI(t)R′(t)=νI(t)
Dans la suite, considérons les données initiales: - S(0)=0.99 - I(0)=0.01 - R(0)=0
Pour la rugéole on prendra - β=0.8 = taux de transmission (plus il est grand, plus la maladie est infectieuse) - ν=0.05 = taux de rémission ou de décès du virus ( = 1 / (duréé moyenne de l’infection); plus ν est petit, plus le temps durant lequel le malade est contagieux est grand )
On simulera pour t∈[0;90] jours
Q1
Soit P(t)=S(t)+I(t)+R(t). Montrer que P est un invariant.
P′(t)=S′(t)+I′(t)+R′(t)=−βS(t)I(t)+βS(t)I(t)−νI(t)+νI(t)=0.
Q2
Calculer la solution approchée obtenue par la méthode d’Euler Progressif avec 91 points.
Afficher ensuite sur le même repère t↦S(t), t↦I(t), t↦R(t) et t↦P(t).
On notera Sn≈S(tn), In≈I(tn) et Rn≈R(tn).
Euler explicite {Sn+1=Sn+hφ0(Sn,In,Rn,tn),In+1=In+hφ1(Sn,In,Rn,tn),Rn+1=Rn+hφ2(Sn,In,Rn,tn).
Code
# S0, I0, R0, h variables globales
def euler_progressif(phi0,phi1,phi2,tt):
SS = [S0]
II = [I0]
RR = [R0]
for i in range(len(tt)-1):
SS.append(SS[i]+h*phi0(SS[i],II[i],RR[i],tt[i]))
II.append(II[i]+h*phi1(SS[i],II[i],RR[i],tt[i]))
RR.append(RR[i]+h*phi2(SS[i],II[i],RR[i],tt[i]))
return [SS,II,RR]
[SS_ep, II_ep, RR_ep] = euler_progressif(phi0,phi1,phi2,tt)
figure(figsize=(10,5))
PP_ep=[SS_ep[i]+II_ep[i]+RR_ep[i] for i in range(len(tt))]
plot(tt,SS_ep,'--',tt,II_ep,'.-',tt,RR_ep,':',tt,PP_ep)
xlabel('t')
legend(['S(t)','I(t)','R(t)','P(t)'])
title('Euler progressif')
grid()
axis([tt[0],tt[-1],0,1.1]);
Q3
Calculer la solution approchée obtenue par la méthode d’Euler Régressif avec 91 points.
Afficher ensuite sur le même repère t↦S(t), t↦I(t), t↦R(t) et t↦P(t).
On notera Sn≈S(tn), In≈I(tn) et Rn≈R(tn).
Euler implicite {Sn+1=Sn+hφ0(Sn+1,In+1,Rn+1,tn+1),In+1=In+hφ1(Sn+1,In+1,Rn+1,tn+1),Rn+1=Rn+hφ2(Sn+1,In+1,Rn+1,tn+1).
Code
from scipy.optimize import fsolve
# S0, I0, R0, h variables globales
def euler_regressif(phi0,phi1,phi2,tt):
SS = [S0]
II = [I0]
RR = [R0]
for i in range(len(tt)-1):
sys = lambda z : [ -z[0]+SS[i]+h*phi0(z[0],z[1],z[2],tt[i+1]) , -z[1]+II[i]+h*phi1(z[0],z[1],z[2],tt[i+1]) , -z[2]+RR[i]+h*phi2(z[0],z[1],z[2],tt[i+1]) ]
Stemp,Itemp, Rtemp = fsolve( sys , (SS[i],II[i],RR[i]) )
SS.append(Stemp)
II.append(Itemp)
RR.append(Rtemp)
return [SS,II,RR]
[SS_er, II_er, RR_er] = euler_regressif(phi0,phi1,phi2,tt)
figure(figsize=(10,5))
PP_er=[SS_er[i]+II_er[i]+RR_er[i] for i in range(len(tt))]
plot(tt,SS_er,'--',tt,II_er,'.-',tt,RR_er,':',tt,PP_er)
xlabel('t')
legend(['S(t)','I(t)','R(t)','P(t)'])
title('Euler regressif')
grid()
axis([tt[0],tt[-1],0,1.1]);
Q4
Calculer la solution approchée obtenue par la fonctionodeint
du module scipy.
Afficher ensuite sur le même repère t↦S(t), t↦I(t), t↦R(t) et t↦P(t).
Code
from scipy.integrate import odeint
pphi = lambda yy,t : [ phi0(yy[0],yy[1],yy[2],t), phi1(yy[0],yy[1],yy[2],t), phi2(yy[0],yy[1],yy[2],t) ]
CI = [S0,I0,R0]
sol = odeint(pphi,CI,tt)
SS,II,RR = sol[:,0],sol[:,1],sol[:,2]
figure(figsize=(10,5))
PP = [SS[i]+II[i]+RR[i] for i in range(len(tt))]
plot(tt,SS,'--',tt,II,'.-',tt,RR,':',tt,PP)
xlabel('t')
legend(['S(t)','I(t)','R(t)','P(t)'])
title('Odeint')
grid()
axis([tt[0],tt[-1],0,1.1]);
1.2 Exercice 2 : étude d’un schéma multipas
On notera φkdéf=φ(tk,uk). Soit la méthode multipas un+1=2γun+(1−2γ)un−1+h(γφn+1+(2−3γ)φn).
Q5
Pour quelles valeurs de $$ est-elle consistante?
p=1: c’est une méthode à q=p+1=2 : - $a_0=2$ et $a_1=1-2$ - $b_0=2-3$ et b1=0 - $b_{-1}=$
La méthode est implicite si γ≠0.
- La méthode est consistante pour tout γ car {p∑j=0aj=a0+a1=2γ+(1−2γ)=1,−p∑j=0jaj+p∑j=−1bj=−(0a0+1a1)+(b−1+b0+b1)=−(1−2γ)+(γ+2−3γ)=1 Vérifions ces calculs ci-dessous:
Code
1
1
[]
Q6
Pour quelles valeurs de γ est-elle convergente?
- Le premier polynôme caractéristique est ϱ(r)=rp+1−∑pj=0ajrp−j=r2−a0r−a1=r2−2γr+(2γ−1) dont les racines sont r0=1,r1=2γ−1.
(r−1)(−2γ+r+1)
[1, 2γ−1]
- La méthode est zéro-stable ssi {|rj|≤1pour tout j=0,…,pϱ′(rj)≠0 si |rj|=1, donc ssi 0≤γ<1.
Code
La première condition impose
0≤γ∧γ≤1
- La méthode est convergente ssi elle est consistante et zéro-stable donc ssi 0≤γ<1.
Q7
Quel ordre de convergente a-t-elle?
- La méthode est d’ordre au moins 2 car ∑pj=0(−j)2aj+2∑pj=−1(−j)1bj=(02a0+12a1)+2(−(−1)b−1+0b0+1b1)=(1−2γ)+2(γ)=1
Code
1
[]
- La méthode est d’ordre 3 ssi γ=25 car ∑pj=0(−j)3aj+3∑pj=−1(−j)2bj=−a1+3(b−1+b1)=−(1−2γ)+3(γ)=5γ−1=1⟺γ=25
Code
5γ−1
[25]
On conclut que - le schéma est convergent au moins d’ordre 2 pour tout γ∈[0,1[ - le schéma est convergent à l’ordre 3 pour γ=25 (et on peut montrer qu’il n’est pas d’ordre 4)
Q8
Pour deux valeurs différentes de γ pour lesquelles le schéma est convergent (dont une qui donne l’ordre de convergence maximale), vérifier empiriquement l’ordre de convergence sur le problème de Cauchy {y′(t)=y(t)(1−y(t)),∀t∈I=[0,1],y(0)=2, après avoir calculé la solution exacte.
- On définit la solution exacte (calculée en utilisant le module
sympy
) pour estimer les erreurs:
Code
import sympy as sym
sym.init_printing()
t = sym.Symbol('t')
y = sym.Function('y')
edo= sym.Eq( sym.diff(y(t),t) , phi(t,y(t)) )
display(edo)
solgen = sym.dsolve(edo)
display(solgen)
consts = sym.solve( sym.Eq( y0, solgen.rhs.subs(t,t0)) , dict=True)[0]
display(consts)
solpar=solgen.subs(consts).simplify()
display(solpar)
sol_exacte = sym.lambdify(t,solpar.rhs,'numpy')
ddty(t)=(1−y(t))y(t)
y(t)=1C1e−t+1
{C1:−12}
y(t)=2et2et−1
On calcule la solution approchée pour différentes valeurs de N:
Code
from scipy.optimize import fsolve
def multipas(phi, tt, gamma):
h = tt[1] - tt[0]
uu = [y0]
uu.append(sol_exacte(tt[1]))
for i in range(1,len(tt) - 1):
temp = fsolve( lambda x : -x+2*gamma*uu[i]+(1-2*gamma)*uu[i-1]+h*(gamma*phi(tt[i+1],x)+(2-3*gamma)*phi(tt[i],uu[i])) ,uu[i])
uu.append( temp )
return uu
H = []
err_mp_2 = []
err_mp_3 = []
N = 10
for k in range(7):
N+=20
tt = linspace(t0, tfinal, N + 1)
h = tt[1] - tt[0]
yy = [sol_exacte(t) for t in tt]
uu_mp_2 = multipas(phi, tt, 1/5)
uu_mp_3 = multipas(phi, tt, 2/5)
H.append(h)
err_mp_2.append(max([abs(uu_mp_2[i] - yy[i]) for i in range(len(yy))]))
err_mp_3.append(max([abs(uu_mp_3[i] - yy[i]) for i in range(len(yy))]))
print ('Multipas gamma=1/5 ordre=%1.2f' %(polyfit(log(H),log(err_mp_2), 1)[0]))
print ('Multipas gamma=2/5 ordre=%1.2f' %(polyfit(log(H),log(err_mp_3), 1)[0]))
figure(figsize=(8,5))
plot(log(H), log(err_mp_2), 'r-o', label=r'Multipas $\gamma=\frac{1}{5}$')
plot(log(H), log(err_mp_3), 'b-o', label=r'Multipas $\gamma=\frac{2}{5}$')
xlabel('$\ln(h)$')
ylabel('$\ln(e)$')
legend(bbox_to_anchor=(1.04, 1), loc='upper left')
grid(True)
show()
Multipas gamma=1/5 ordre=1.97
Multipas gamma=2/5 ordre=2.94