Le modèle que nous considérons maintenant est typiquement appelé modèle SIR de Kermack-McKendrick (KMK)
3 compartiments, mais quand on inspecte en détail, on remarque que les retirés n'ont pas d'influence directe sur la dynamique de
De plus, la population totale (incluant les morts qui sont aussi classés dans
Par conséquent,
Donc on considère à présent
Considérons les équilibres de
Le second cas est un problème: la linéarisation usuelle ne fonctionne pas lorsque l'on a un continuum d'équilibres, puisque les équilibres ne sont pas isolés!
Quelle est la dynamique de
pourvu que
Attention! Il convient de se souvenir que
On intègre
avec
CI
(puisque
Trajectoires du système
Étudions
On a
Donc dans les courbes précédentes, le max de
rhs_SIR_KMK <- function(t, x, p) {
with(as.list(c(x, p)), {
dS = - beta * S * I
dI = beta * S * I - gamma * I
dR = gamma * I
return(list(c(dS, dI, dR)))
})
}
# Condition initiale pour S (pour calculer R_0)
S0 = 1000
gamma = 1/14
# On règle beta pour que R_0 = 1.5
beta = 1.5 * gamma / S0
params = list(gamma = gamma, beta = beta)
IC = c(S = S0, I = 1, R = 0)
times = seq(0, 365, 1)
sol <- ode(IC, times, rhs_SIR_KMK, params)
plot(sol[, "time"], sol[, "I"], type = "l",
main = TeX("SIR de Kermack et McKendrick, $R_0=1.5$"),
xlab = "Temps (jours)", ylab = "Prévalence")
Pour la fonction à valeurs positives et intégrable
On note aussi
calculons la somme de
Intégrons de 0 à
Le terme de gauche donne
car
Le terme de droite prend la forme
On a donc
Divisons les deux cotés par
Intégrons de 0 a
Exprimons
On a donc
que l'on écrit
On cherche par conséquent les zéros de la fonction
On cherche
Notons pour commencer que lorsque
Différentiant
Lorsque
Donc si
On a vu que
Par ailleurs,
Du reste,
On a vu que
Pour
Comme précédemment,
On va résoudre numériquement. Il faut une fonction
final_size_eq = function(S_inf, S0 = 999, I0 = 1, R_0 = 2.5) {
OUT = S0*(log(S0)-log(S_inf)) - (S0+I0-S_inf)*R_0
return(OUT)
}
et on résoud facilement en utilisant uniroot
, ici avec les valeurs par défaut qu'on a mis dans la fonction:
uniroot(f = final_size_eq, interval = c(0.05, 999))
$root
[1] 106.8819
$f.root
[1] -2.649285e-07
$iter
[1] 10
$init.it
[1] NA
$estim.prec
[1] 6.103516e-05
Pour passer des valeurs différentes, on peut par exemple faire
N0 = 1000
I0 = 1
S0 = N0-I0
R_0 = 2.4
uniroot(
f = function(x)
final_size_eq(S_inf = x,
S0 = S0, I0 = I0,
R_0 = R_0),
interval = c(0.05, S0))
S = seq(0.1, S0, by = 0.1)
fs = final_size(S, S0 = S0, I0 = I0, R_0 = R_0)
S_inf = uniroot(f = function(x) final_size_eq(S_inf = x,
S0 = S0, I0 = I0,
R_0 = R_0),
interval = c(0.05, S0))
plot(S, fs, type = "l", ylab = "Valeur de l'équation (8)")
abline(h = 0)
points(x = S_inf$root, y = 0, pch = 19)
text(x = S_inf$root, y = 0, labels = "S_inf", adj = c(-0.25,-1))
valeurs = expand.grid(
R_0 = seq(0.01, 3, by = 0.01),
I0 = 1:100
)
valeurs$S0 = N0-valeurs$I0
L = split(valeurs, 1:nrow(valeurs))
valeurs$S_inf = sapply(X = L, FUN = final_size)
valeurs$taille_finale = valeurs$S0-valeurs$S_inf+valeurs$I0
valeurs$taux_attaque = (valeurs$taille_finale / N0)*100
levelplot(taux_attaque ~ R_0*I0, data = valeurs,
xlab="R_0", ylab = "I0",
col.regions = viridis(100))
(requiert les librairies lattice
et viridis
)