Constant increase of Infected compartment: \[\frac{\mathrm dI(t)}{\mathrm dt} = a,\quad I(0)=I_0,\] which is solved by moving \(\mathrm{d}t\) to the right hand side and re-writing the equation in the form: \[\mathrm dI = a\mathrm dt \quad \Rightarrow \quad \int \mathrm dI = \int a\>\mathrm dt.\] This gives: \(I(t) = a\,t+C\), where \(C\) is a constant of integration. It is defined by using initial condition: \(I(0)=I_0\), so that: \(I_0=a\times0+C\) and \(C=I_0\).
Finally we write: \[I(t) = I_0+a\,t.\]
library(dplyr)
library(magrittr)
library(ggplot2)
# Initial number of susceptibles: 100 people
I0 = 5
# Constant rate
a = 3
# We set a time to a sequence of 100 timepoint
# between 0 and 5 weeks
df = data.frame(t = seq(0,5,length.out=100)) %>%
# then we impute the solution we obtained before
mutate(I = I0 + a*t)
ggplot(data=df,aes(x=t)) +
geom_path(aes(y=I,color="Infected"),size=1.5) +
coord_cartesian(ylim=c(0,27)) +
theme_bw(base_size=14,base_family='Times') +
labs(x="Time (weeks)",y="Number of infected people") +
guides(color=guide_legend(title=NULL)) +
theme(legend.background = element_blank())
A small modification of the previous example: \[\frac{\mathrm dI(t)}{\mathrm dt} = a\cdot t,\quad I(0)=I_0,\] that is solved in analogous way by moving \(\mathrm dt\) to the right hand side: \[\int \mathrm dI(t) = \int a\cdot t{\mathrm dt}\quad \Rightarrow \quad I(t) = \frac{at^2}2+C\]. The constant of integration is defined by the initial condition: \(I(0)=I_0=\frac{a\times0^2}2+C\), so that: \(C=I_0\) and: \[I(t)=I_0+\frac{at^2}2\].
# Here we modify the dataframe from a previous example just a bit
# Note that the power of two is written as "**" in R
df %>%
mutate(I = I0 + a*t**2/2) %>%
ggplot(aes(x=t)) +
geom_path(aes(y=I,color="Infected"),size=1.5) +
coord_cartesian(ylim=c(0,52)) +
theme_bw(base_size=14,base_family='Times') +
labs(x="Time (weeks)",y="Number of infected people") +
guides(color=guide_legend(title=NULL)) +
theme(legend.background = element_blank())
Dynamics: \[\frac{\mathrm dS(t)}{\mathrm dt} = -\lambda S(t),\quad \frac{\mathrm dI(t)}{\mathrm dt} = \lambda S(t),\] with initial conditions: \(S(0)=S_0\) and \(I(0)=0\).
First, we solve the equation for \(S(t)\): \[ \frac{\mathrm dS}S = -\lambda\mathrm dt\quad\Rightarrow\quad \mathrm d\ln S = -\lambda\mathrm dt\,. \] Because: \(\mathrm d\ln S=\frac{\mathrm dS}S\)
Integrating both sides gives: \[ \int\mathrm d\ln S = -\lambda\int\mathrm dt\quad\Rightarrow\quad \ln S = -\lambda t+C_1\,, \] where \(C_1\) is the constant of integration.
Now we take the exponent of both sides: \[ \exp(\ln S) = \exp(-\lambda t+C_1)=\exp(-\lambda t)\cdot\exp(C_1)\,, \] or \[ S(t) = e^{C_1}\cdot e^{-\lambda t}\,. \] Here we do not know the constant \(C_1\), so we define it using initial condition. Precisely, we substitute \(t=0\) in the previous equation to obtain: \[ S(t=0)=S_0=e^{C_1}\cdot e^{-\lambda\cdot 0}=e^{C_1}\, \] The zero power of any number equals to one (\(e^0=1\)) so that our final formula: \[ S(t) = S_0e^{-\lambda t}\,. \]
To find how \(I(t)\) changes in time, we may use two ways. The first one, the simplest, is to notice that \(S(t)+I(t)\) is constant in time.Indeed, by using the dynamic equations, we get: \[ \frac{\mathrm d(S+I)}{\mathrm dt}=\frac{\mathrm dS}{\mathrm dt}+\frac{\mathrm dI}{\mathrm dt}=-\lambda S+\lambda S=0\,. \] It also means that \(S(t)+I(t)=S_0\). Then we obtain: \[ I(t)=S_0-S(t)=S_0-S_0e^{-\lambda t}=S_0(1-e^{-\lambda t})\,. \]
Another way is simply to substitute \(S(t)=S_0e^{-\lambda t}\) into the second dynamical equation for \(I(t)\). We get in this case: \[ \frac{\mathrm dI}{\mathrm dt} = \lambda S_0e^{-\lambda t}\quad\Rightarrow\quad \mathrm dI = \lambda S_0e^{-\lambda t}\mathrm dt=-S_0\mathrm de^{-\lambda t}\,. \] We check: \(\mathrm de^{-\lambda t}=\frac{\mathrm d}{\mathrm dt}(e^{-\lambda t})\mathrm dt=-\lambda e^{-\lambda t}\mathrm dt\). Integrating both sides: \[ \int\limits_0^t\mathrm dI =-S_0\int\limits_0^t\mathrm de^{-\lambda t}\quad\rightarrow I(t)-I(0) = -S_0(e^{-\lambda t}-e^{-\lambda\cdot 0})\,. \] Since \(I(0)=0\), we finally obtain: \[ I(t)=S_0(1-e^{-\lambda t}) \]
Let us plot the results in R
library(dplyr)
library(magrittr)
# Initial number of susceptibles: 100 people
S0 = 100
# Suppose that a person becomes sick after 2 weeks on average
lambda = 1/2
# We set a time to a sequence of one hundred points between 0 and 7 weeks
# This means that we observe a population for one week 100 times.
# This will be our variable "t" in the data frame "df"
df = data.frame(t = seq(0,7,length.out=100))
# Then we add what we observe the following dynamics
df %<>% mutate(
S = S0*exp(-lambda*t),
I = S0*(1-exp(-lambda*t)))
We get the following data frame1 we show only eight first rows of the data frame:
# Library to show the tables nicely
library(knitr)
df %>%
# Show first eight elements
head(8) %>%
# Show it nicely as a table
kable(row.names=NA,digits=2,
col.names=c("time, weeks","susceptibles",
"infected"))
| time, weeks | susceptibles | infected |
|---|---|---|
| 0.00 | 100.00 | 0.00 |
| 0.07 | 96.53 | 3.47 |
| 0.14 | 93.17 | 6.83 |
| 0.21 | 89.94 | 10.06 |
| 0.28 | 86.81 | 13.19 |
| 0.35 | 83.80 | 16.20 |
| 0.42 | 80.89 | 19.11 |
| 0.49 | 78.08 | 21.92 |
library(ggplot2)
df %>% ggplot(aes(x=t)) +
geom_path(aes(y=I,color="Infected"),size=1.5) +
geom_path(aes(y=S,color="Susceptibles"),size=1.5) +
coord_cartesian(ylim=c(0,100)) +
theme_bw(base_size=14,base_family='Times') +
labs(x="Time (weeks)",y="Number of people") +
guides(color=guide_legend(title=NULL)) +
theme(legend.position = c(1,.5),
legend.justification = c(1, .5),
legend.background = element_blank())
Now we add the mortality term into the \(I\)-compartment. We write: \[\frac{\mathrm dS(t)}{\mathrm dt} = -\lambda S(t),\quad \frac{\mathrm dI(t)}{\mathrm dt} = \lambda S(t)-\mu I(t),\] with the same initial conditions: \(S(0)=S_0\) and \(I(0)=0\).
After solving the first equation: \(S(t)=S_0e^{-\lambda t}\), we get the second equation in the form: \[ \frac{\mathrm dI}{\mathrm dt} = -\mu I+\lambda S_0e^{-\lambda t}\,. \]
Step 1. First we deal with the uniform solution. We solve: \[ \frac{\mathrm dI}{\mathrm dt} = -\mu I\quad\Rightarrow\quad \frac{\mathrm dI}I = -\mu\mathrm dt\quad\Rightarrow \mathrm d\ln I=-\mu\cdot\mathrm dt\,. \] If we integrate both parts of the equation, we get the solution dependent on the constant of integration \(C\): \[ I_{\text{uniform}}(t) = Ce^{-\mu t}\,. \]
Step 2. Here we want to obtain any particular solution of the original equation. To do so, we assume that the constant \(C\) varies in time: \(C=C(t)\), and we substitute this into the initial equation for \(I\): \[ \begin{split} \frac{\mathrm dI}{\mathrm dt} = \frac{d(C(t)e^{-\mu t})}{\mathrm dt} = \frac{\mathrm dC}{\mathrm dt}e^{-\mu t}+C\frac{\mathrm de^{-\mu t}}{\mathrm dt} = {} \qquad \\ \qquad \frac{\mathrm dC}{\mathrm dt}e^{-\mu t}-\mu Ce^{-\mu t}={-}\mu Ce^{-\mu t}+\lambda S_0e^{-\lambda t} \end{split} \] as we see the term \({-}\mu Ce^{-\mu t}\) is the same in both sides and it disappears. Then, we get: \[ \begin{split} \frac{\mathrm dC}{\mathrm dt}e^{-\mu t}=\lambda S_0e^{-\lambda t}\quad\Rightarrow\quad \frac{\mathrm dC}{\mathrm dt}=\lambda S_0e^{(\mu-\lambda)t} \qquad \\ \Rightarrow\quad \mathrm dC = \lambda S_0e^{(\mu-\lambda)t}\mathrm dt=\frac{\lambda S_0}{\mu-\lambda}\cdot\mathrm de^{(\mu-\lambda)t} \end{split} \] Again we check: \[ \frac{\mathrm de^{(\mu-\lambda)t}}{\mu-\lambda}=e^{(\mu-\lambda)t}\mathrm dt \]
By integrating both sides, we obtain: \[ C = \frac{\lambda S_0}{\mu-\lambda}e^{(\mu-\lambda)t} \] since we are interested in any particular solution, we can admit the constant of integration to any value2 Here we took: \(C(0)=1\). Thus, we write a particular solution in the form: \[ I_{\text{particular}}(t) = Ce^{-\mu t} = \frac{\lambda S_0}{\mu-\lambda}e^{(\mu-\lambda)t}\cdot e^{-\mu t}=\frac{\lambda S_0}{\mu-\lambda}e^{-\lambda t}\,. \]
Step 3.
Here we combine the uniform and particular into the final result: \[ I(t) = I_{\text{uniform}}(t)+I_{\text{particular}} = Ce^{-\mu t}+\frac{\lambda S_0}{\mu-\lambda}e^{-\lambda t}\,. \]
We remember that the initial condition \(I(0)=0\) should still work. So we use it to identify the constant \(C\): \[ I(t=0)=0=Ce^{-\mu\cdot0}+\frac{\lambda S_0}{\mu-\lambda}e^{-\lambda\cdot0}=C+\frac{\lambda S_0}{\mu-\lambda}\,, \] which means that: \[ C = -\frac{\lambda S_0}{\mu-\lambda}\,. \]
The final solution writes as follows: \[ I(t) = -\frac{\lambda S_0}{\mu-\lambda}e^{-\mu t}+\frac{\lambda S_0}{\mu-\lambda}e^{-\lambda t}\,. \] We can also re-write it in a bit nicer form: \[ I(t) = \frac{\lambda S_0}{\mu-\lambda}\left(e^{-\lambda t}-e^{-\mu t}\right). \] We may check that our solution gives the previous one if we take \(\mu=0\). Indeed: \[ I(t)\Big|_{\mu=0}=\frac{\lambda S_0}{0-\lambda}(e^{-\lambda t}-e^{-0\cdot t})=S_0(1-e^{-\lambda t}) \]
Notice that the number of died (or recovered) people \(R(t)\) will be simply expressed as follows: \[ R(t) = S(0)-(S(t)+I(t)) \]
# We add the mortality (or recovery) factor:
# each person recovers after 4 weeks on average
mu = 1/4
# We change our data frame a bit
df %<>% mutate(
I = lambda*S0/(mu-lambda)*(exp(-lambda*t)-exp(-mu*t)))
# We also track the number of died (or recovered) persons
df %<>% mutate(
R = S0-I-S
)
We get the following data frame:
df %>%
head(8) %>%
# Show it nicely as a table
kable(row.names=NA,digits=2,
col.names=c("time, weeks","susceptibles",
"infected","recovered"))
| time, weeks | susceptibles | infected | recovered |
|---|---|---|---|
| 0.00 | 100.00 | 0.00 | 0.00 |
| 0.07 | 96.53 | 3.44 | 0.03 |
| 0.14 | 93.17 | 6.71 | 0.12 |
| 0.21 | 89.94 | 9.80 | 0.27 |
| 0.28 | 86.81 | 12.72 | 0.47 |
| 0.35 | 83.80 | 15.49 | 0.72 |
| 0.42 | 80.89 | 18.10 | 1.01 |
| 0.49 | 78.08 | 20.57 | 1.35 |
df %>% ggplot(aes(x=t)) +
geom_path(aes(y=R,color="Recovered"),size=1.5) +
geom_path(aes(y=I,color="Infected"),size=1.5) +
geom_path(aes(y=S,color="Susceptibles"),size=1.5) +
coord_cartesian(ylim=c(0,100)) +
theme_bw(base_size=14,base_family='Times') +
labs(x="Time (weeks)",y="Number of people") +
guides(color=guide_legend(title=NULL)) +
theme(legend.position = c(.5,1),
legend.justification = c(.5, 1),
legend.background = element_blank())
We can also get the number of people on day 7:
df %>%
# Get the last row of the data frame
tail(1) %>%
# Show it nicely as a table
kable(row.names=NA,digits=0,
col.names=c("time, weeks","susceptibles",
"infected","recovered"))
| time, weeks | susceptibles | infected | recovered | |
|---|---|---|---|---|
| 100 | 7 | 3 | 29 | 68 |
We check that 3+29+68=100 people.