FullSimplify[*(S + E1 + I1 + R) - (\[Beta]*I1 + \[Mu])*S + \[Omega]*
Solve[{\[Mu]== 0, \[Beta]*I1*S - (\[Mu] + \[Kappa])*E1 ==
R 0, \[Kappa]*E1 - (\[Mu] + \[Gamma])*I1 ==
0, \[Gamma]*I1 - (\[Omega] + \[Mu])*R == 0,
+ E1 + I1 + R == 1, \[Mu] > 0, \[Beta] > 0, \[Kappa] >
S 0, \[Gamma] > 0, \[Omega] > 0, S > 0, E1 > 0, I1 > 0, R > 0,
S \[Element] Reals, E1 \[Element] Reals, I1 \[Element] Reals, R \[Element] Reals}, {S, E1, I1, R}]]
Solutions for the steady states of the SEIR model
In this post, I compared the numerical solutions obtained using deSolve::ode
with the algebraic solutions derived from Mathematica for the steady states of a SEIR model. The model considers the waning of natural immunity over time in a dynamically changing population.
SEIR model with waning immunity and vital dynamics
dS/dt = \mu (S+E+I+R) - \beta SI - \mu S + \omega R\\ dE/dt = \beta SI - (\mu+\kappa)E\\ dI/dt = \kappa E - (\mu+\gamma)I\\ dR/dt = \gamma I - (\mu+\omega) R Following Mathematica command produces the solutions for the steady states.
s = \frac{(\gamma +\mu ) (\kappa +\mu )}{\beta \kappa } \\
e = -\frac{(\gamma +\mu ) (\mu +\omega ) ((\gamma +\mu ) (\kappa +\mu )-\beta \kappa )}{\beta \kappa (\gamma (\kappa +\mu +\omega )+(\kappa +\mu ) (\mu +\omega ))} \\
i = \frac{(\mu +\omega ) (\beta \kappa -(\gamma +\mu ) (\kappa +\mu ))}{\beta \omega (\gamma +\kappa +\mu )+\beta (\gamma +\mu ) (\kappa +\mu )} \\
r = \frac{\beta \gamma \kappa -\gamma (\gamma +\mu ) (\kappa +\mu )}{\beta \omega (\gamma +\kappa +\mu )+\beta (\gamma +\mu ) (\kappa +\mu )}
I used latex2r
package to convert the LaTex expressions from the Mathematica to R codes
library(latex2r)
<- latex2r("\\frac{(\\gamma +\\mu ) (\\kappa +\\mu )}{\\beta \\kappa }")
s <- latex2r("-\\frac{(\\gamma +\\mu ) (\\mu +\\omega ) ((\\gamma +\\mu ) (\\kappa +\\mu )-\\beta \\kappa )}{\\beta \\kappa (\\gamma (\\kappa +\\mu +\\omega )+(\\kappa +\\mu ) (\\mu +\\omega ))}")
e <- latex2r("\\frac{(\\mu +\\omega ) (\\beta \\kappa -(\\gamma +\\mu ) (\\kappa +\\mu ))}{\\beta \\omega (\\gamma +\\kappa +\\mu )+\\beta (\\gamma +\\mu ) (\\kappa +\\mu )}")
i <- latex2r("\\frac{\\beta \\gamma \\kappa -\\gamma (\\gamma +\\mu ) (\\kappa +\\mu )}{\\beta \\omega (\\gamma +\\kappa +\\mu )+\\beta (\\gamma +\\mu ) (\\kappa +\\mu )}")
r
<- 1.115044 / 2 # mean late period is still around 1.4 days,
kappa <- 1/2
gamma <- 1/(65*365)
mu <- 1/(4*365)
omega <- 0.6
beta
<- list(s=s, e=e, i=i, r=r)
states = sapply(states, function(x) eval(parse(text = x)))
val "e"]]/(val[["i"]]+val[["e"]]) val[[
[1] 0.4728244
/(gamma+kappa) gamma
[1] 0.4728034
+mu)/(gamma+kappa+mu) (gamma
[1] 0.4728244
1/kappa)/(1/kappa + 1/gamma) (
[1] 0.4728034
Numerical solutions based on deSolve::ode
.
<- function(t, u, p){
seir_vital <- sum(u)
N <- p["beta"]
beta <- p["kappa"]
kappa <- p["gamma"]
gamma <- p["omega"]
omega <- p["mu"]
mu
<- - beta*u[1]*u[3] + omega*u[4] - mu*u[1] + mu*N
du1 <- + beta*u[1]*u[3] - kappa*u[2] - mu*u[2]
du2 <- + kappa*u[2] - gamma*u[3] - mu*u[3]
du3 <- + gamma*u[3] - omega*u[4] - mu*u[4]
du4
return(list(c(du1,du2,du3,du4)))
}
library(deSolve)
<- c(0.99, 0, 0.01, 0)
u0 <- c(kappa=1.115044/2, gamma=1/2, mu=1/(65*365),
p omega=1/(4*365), beta=0.6)
<- seq(from=0, to=300*100)
tspan <- as.data.frame(ode(y=u0, times=tspan, func=seir_vital, parms=p))
outdf names(outdf) <- c("day","s","e","i","r")
tail(outdf, 1)
day s e i r
30001 30000 0.8334656 0.0002166031 0.0002415018 0.1660763
SE_1E_2I_1I_2R_1R_2 model
This model incorporates two consecutive compartments for the Exposed (E), Infectious (I), and Recovered (R) states, effectively changing the distribution of waiting times in each states from an exponential to an Erlang distribution with a shape parameter of 2, offering a more realistic representation.
dS/dt = \mu (S+E_1+I_1+R_1+E_2+I_2+R_2) - \beta S(I_1+I_2) - \mu S + 2 \omega R_2\\ dE_1/dt = \beta S(I_1+I_2) - (\mu+2\kappa)E1\\ dE_2/dt = 2\kappa E_1 - (\mu+2\kappa)E2\\ dI_1/dt = 2 \kappa E_2 - (\mu+2\gamma)I_1\\ dI_2/dt = 2\gamma I_1 - (\mu+2\gamma)I_2\\ dR_1/dt = 2 \gamma I_2 - (\mu+2\omega) R_1\\ dR_2/dt = 2 \omega R_1 - (\mu+2\omega) R_2
The following Mathematica command produces the solutions for the steady states.
FullSimplify[*(S + E1 + E2 + I1 + I2 + R1 +
Solve[{\[Mu]- (\[Beta]*(I1 + I2) + \[Mu])*S + 2*\[Omega]*R2 ==
R2) 0, \[Beta]*(I1 + I2)*S - (\[Mu] + 2*\[Kappa])*E1 == 0,
2*\[Kappa]*E1 - (2*\[Kappa] + \[Mu])*E2 == 0,
2*\[Kappa]*E2 - (\[Mu] + 2*\[Gamma])*I1 == 0,
2*\[Gamma]*I1 - (2*\[Gamma] + \[Mu])*I2 == 0,
2*\[Gamma]*I2 - (2*\[Omega] + \[Mu])*R1 == 0,
2*\[Omega]*R1 - (\[Mu] + 2*\[Omega])*R2 == 0,
+ E1 + E2 + I1 + I2 + R1 + R2 == 1, \[Mu] > 0, \[Beta] >
S 0, \[Kappa] > 0, \[Gamma] > 0, \[Omega] > 0, S > 0, E1 > 0,
> 0, I1 > 0, I2 > 0, R1 > 0, R2 > 0, S \[Element] Reals,
E2
E1 \[Element] Reals, E2 \[Element] Reals, I1 \[Element] Reals,
I2 \[Element] Reals, R1 \[Element] Reals, R2 \[Element] Reals}, {S, E1, E2, I1, I2, R1, R2}]]
s= \frac{(2 \gamma +\mu )^2 (2 \kappa +\mu )^2}{4 \beta \kappa ^2 (4 \gamma +\mu )}\\ e_1 = - \frac{(2 \gamma +\mu )^2 (2 \kappa +\mu ) (\mu +2 \omega )^2 \left((2 \gamma +\mu )^2 (2 \kappa +\mu )^2-4 \beta \kappa ^2 (4 \gamma +\mu )\right)}{4 \beta \kappa ^2 (4 \gamma +\mu ) \left(4 \gamma ^2 (2 \kappa +\mu +2 \omega ) (2 \kappa (\mu +4 \omega )+\mu (\mu +2 \omega ))+4 \gamma (2 \kappa +\mu )^2 (\mu +2 \omega )^2+\mu (2 \kappa +\mu )^2 (\mu +2 \omega )^2\right)}\\ e_2 = -\frac{(2 \gamma +\mu )^2 (\mu +2 \omega )^2 \left((2 \gamma +\mu )^2 (2 \kappa +\mu )^2-4 \beta \kappa ^2 (4 \gamma +\mu )\right)}{2 \beta \kappa (4 \gamma +\mu ) \left(4 \gamma ^2 (2 \kappa +\mu +2 \omega ) (2 \kappa (\mu +4 \omega )+\mu (\mu +2 \omega ))+4 \gamma (2 \kappa +\mu )^2 (\mu +2 \omega )^2+\mu (2 \kappa +\mu )^2 (\mu +2 \omega )^2\right)}\\ i_1 = - \frac{(2 \gamma +\mu ) (\mu +2 \omega )^2 \left((2 \gamma +\mu )^2 (2 \kappa +\mu )^2-4 \beta \kappa ^2 (4 \gamma +\mu )\right)}{\beta (4 \gamma +\mu ) \left(4 \gamma ^2 (2 \kappa +\mu +2 \omega ) (2 \kappa (\mu +4 \omega )+\mu (\mu +2 \omega ))+4 \gamma (2 \kappa +\mu )^2 (\mu +2 \omega )^2+\mu (2 \kappa +\mu )^2 (\mu +2 \omega )^2\right)}\\ i_2 = -\frac{2 \gamma (\mu +2 \omega )^2 \left(4 \beta \kappa ^2 (4 \gamma +\mu )-(2 \gamma +\mu )^2 (2 \kappa +\mu )^2\right)}{\beta (4 \gamma +\mu ) \left(4 \gamma ^2 (2 \kappa +\mu +2 \omega ) (2 \kappa (\mu +4 \omega )+\mu (\mu +2 \omega ))+4 \gamma (2 \kappa +\mu )^2 (\mu +2 \omega )^2+\mu (2 \kappa +\mu )^2 (\mu +2 \omega )^2\right)}\\ r_1 = -\frac{4 \gamma ^2 (\mu +2 \omega ) \left((2 \gamma +\mu )^2 (2 \kappa +\mu )^2-4 \beta \kappa ^2 (4 \gamma +\mu )\right)}{\beta (4 \gamma +\mu ) \left(4 \gamma ^2 (2 \kappa +\mu +2 \omega ) (2 \kappa (\mu +4 \omega )+\mu (\mu +2 \omega ))+4 \gamma (2 \kappa +\mu )^2 (\mu +2 \omega )^2+\mu (2 \kappa +\mu )^2 (\mu +2 \omega )^2\right)}\\ r_2 = -\frac{8 \gamma ^2 \omega \left((2 \gamma +\mu )^2 (2 \kappa +\mu )^2-4 \beta \kappa ^2 (4 \gamma +\mu )\right)}{\beta (4 \gamma +\mu ) \left(4 \gamma ^2 (2 \kappa +\mu +2 \omega ) (2 \kappa (\mu +4 \omega )+\mu (\mu +2 \omega ))+4 \gamma (2 \kappa +\mu )^2 (\mu +2 \omega )^2+\mu (2 \kappa +\mu )^2 (\mu +2 \omega )^2\right)}
Again, LaTex expressions were converted to R codes using the latex2r
package.
<- latex2r("\\frac{(2 \\gamma +\\mu )^2 (2 \\kappa +\\mu )^2}{4 \\beta \\kappa ^2 (4 \\gamma +\\mu )}")
s <- latex2r("-\\frac{(2 \\gamma +\\mu )^2 (2 \\kappa +\\mu ) (\\mu +2 \\omega )^2 \\left((2 \\gamma +\\mu )^2 (2 \\kappa +\\mu )^2-4 \\beta \\kappa ^2 (4 \\gamma +\\mu )\\right)}{4 \\beta \\kappa ^2 (4 \\gamma +\\mu ) \\left(4 \\gamma ^2 (2 \\kappa +\\mu +2 \\omega ) (2 \\kappa (\\mu +4 \\omega )+\\mu (\\mu +2 \\omega ))+4 \\gamma (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2+\\mu (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2\\right)}")
e1
<- latex2r("-\\frac{(2 \\gamma +\\mu )^2 (\\mu +2 \\omega )^2 \\left((2 \\gamma +\\mu )^2 (2 \\kappa +\\mu )^2-4 \\beta \\kappa ^2 (4 \\gamma +\\mu )\\right)}{2 \\beta \\kappa (4 \\gamma +\\mu ) \\left(4 \\gamma ^2 (2 \\kappa +\\mu +2 \\omega ) (2 \\kappa (\\mu +4 \\omega )+\\mu (\\mu +2 \\omega ))+4 \\gamma (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2+\\mu (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2\\right)}")
e2
<- latex2r("-\\frac{(2 \\gamma +\\mu ) (\\mu +2 \\omega )^2 \\left((2 \\gamma +\\mu )^2 (2 \\kappa +\\mu )^2-4 \\beta \\kappa ^2 (4 \\gamma +\\mu )\\right)}{\\beta (4 \\gamma +\\mu ) \\left(4 \\gamma ^2 (2 \\kappa +\\mu +2 \\omega ) (2 \\kappa (\\mu +4 \\omega )+\\mu (\\mu +2 \\omega ))+4 \\gamma (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2+\\mu (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2\\right)}")
i1
<- latex2r("\\frac{2 \\gamma (\\mu +2 \\omega )^2 \\left(4 \\beta \\kappa ^2 (4 \\gamma +\\mu )-(2 \\gamma +\\mu )^2 (2 \\kappa +\\mu )^2\\right)}{\\beta (4 \\gamma +\\mu ) \\left(4 \\gamma ^2 (2 \\kappa +\\mu +2 \\omega ) (2 \\kappa (\\mu +4 \\omega )+\\mu (\\mu +2 \\omega ))+4 \\gamma (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2+\\mu (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2\\right)}")
i2
<- latex2r("-\\frac{4 \\gamma ^2 (\\mu +2 \\omega ) \\left((2 \\gamma +\\mu )^2 (2 \\kappa +\\mu )^2-4 \\beta \\kappa ^2 (4 \\gamma +\\mu )\\right)}{\\beta (4 \\gamma +\\mu ) \\left(4 \\gamma ^2 (2 \\kappa +\\mu +2 \\omega ) (2 \\kappa (\\mu +4 \\omega )+\\mu (\\mu +2 \\omega ))+4 \\gamma (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2+\\mu (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2\\right)}")
r1
<- latex2r("-\\frac{8 \\gamma ^2 \\omega \\left((2 \\gamma +\\mu )^2 (2 \\kappa +\\mu )^2-4 \\beta \\kappa ^2 (4 \\gamma +\\mu )\\right)}{\\beta (4 \\gamma +\\mu ) \\left(4 \\gamma ^2 (2 \\kappa +\\mu +2 \\omega ) (2 \\kappa (\\mu +4 \\omega )+\\mu (\\mu +2 \\omega ))+4 \\gamma (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2+\\mu (2 \\kappa +\\mu )^2 (\\mu +2 \\omega )^2\\right)}")
r2
<- 1.115044 / 2 # mean late period is still around 1.4 days,
kappa <- 1/2
gamma <- 1/(65*365)
mu <- 1/(4*365)
omega <- 0.6
beta
<- list(s=s, e1=e1, e2=e2, i1=i1, i2=i2, r1=r1, r2=r2)
states sapply(states, function(x) eval(parse(text = x)))
s e1 e2 i1 i2 r1
0.8334490274 0.0001067747 0.0001067707 0.0001190490 0.0001190440 0.0843079955
r2
0.0817913389
Numerical solutions are based on deSolve::ode
.
<- function(t, u, p){
seir_2stg_vital <- sum(u)
N <- p["beta"]
beta <- p["kappa"]
kappa <- p["gamma"]
gamma <- p["omega"]
omega <- p["mu"]
mu
<- - beta*u[1]*(u[4]+u[5]) + 2*omega*u[7] - mu*u[1] + mu*N
du1 <- + beta*u[1]*(u[4]+u[5]) - 2*kappa*u[2] - mu*u[2]
du2 <- + 2*kappa*u[2] - 2*kappa*u[3] - mu*u[3]
du3 <- + 2*kappa*u[3] - 2*gamma*u[4] - mu*u[4]
du4 <- + 2*gamma*u[4] - 2*gamma*u[5] - mu*u[5]
du5 <- + 2*gamma*u[5] - 2*omega*u[6] - mu*u[6]
du6 <- + 2*omega*u[6] - 2*omega*u[7] - mu*u[7]
du7
return(list(c(du1,du2,du3,du4,du5,du6,du7)))
}
<- c(0.99, 0, 0, 0.01, 0, 0, 0)
u0 <- c(kappa=1.115044/2, gamma=1/2, mu=1/(65*365),
p omega=1/(4*365), beta=0.6)
<- seq(from=0, to=365*300)
tspan <- as.data.frame(ode(y=u0, times=tspan, func=seir_2stg_vital, parms=p))
outdf names(outdf) <- c("day","s","e1","e2","i1","i2","r1","r2")
tail(outdf, 1)
day s e1 e2 i1 i2
109501 109500 0.8334488 0.0001067726 0.0001067686 0.0001190467 0.0001190417
r1 r2
109501 0.08430817 0.08179142