sir.aoi | R Documentation |
Numerically integrates the SIR equations with rates of transmission and recovery structured by age of infection.
sir.aoi(from = 0, to = from + 1, by = 1,
R0, ell = 1, eps = 0, n = max(length(R0), length(ell)),
init = c(1 - init.infected, init.infected),
init.infected = .Machine[["double.neg.eps"]],
weights = rep(c(1, 0), c(1L, n - 1L)),
F = function (x) 1, Fargs = list(),
H = identity, Hargs = list(),
method = c("lsoda", "lsode", "vode", "daspk", "radau"),
root = NULL, aggregate = FALSE, ...)
## S3 method for class 'sir.aoi'
summary(object, name = "Y", tol = 1e-6, ...)
from , to , by |
passed to |
R0 |
a numeric vector of length |
ell |
a numeric vector of length |
eps |
a non-negative number giving the the ratio of the mean time spent
infectious and the mean life expectancy; |
n |
a positive integer giving the number of infected compartments.
Setting |
init |
a numeric vector of length 2 giving initial susceptible and infected proportions. |
init.infected |
a number in |
weights |
a numeric vector of length |
F , H |
functions returning a numeric vector of length 1 or of length equal
that of the first formal argument. The body must be symbolically
differentiable with respect to the first formal argument; see
|
Fargs , Hargs |
lists of arguments passed to |
method |
a character string indicating a numerical integration method as the
name of a solver in package deSolve. Otherwise, an object of
class |
root |
a function returning a numeric vector of length 1, with formal
arguments |
aggregate |
a logical indicating if infected compartments should be aggregated. |
... |
optional arguments passed to the solver indicated by |
object |
an R object inheriting from class |
name |
a character string in |
tol |
a positive number giving an upper bound on the relative change (from
one time point to the next) in the slope of |
The SIR equations with rates of transmission and recovery structured by age of infection are
\begin{alignedat}{4}
\text{d} & S &{} / \text{d} t
&{} = \mu (1 - S) - (\textstyle\sum_{j} \beta_{j} I_{j}) F H(S) \\
\text{d} & I_{ 1} &{} / \text{d} t
&{} = (\textstyle\sum_{j} \beta_{j} I_{j}) F H(S) - (\gamma_{1} + \mu) I_{1} \\
\text{d} & I_{j + 1} &{} / \text{d} t
&{} = \gamma_{j} I_{j} - (\gamma_{j + 1} + \mu) I_{j + 1} \\
\text{d} & R &{} / \text{d} t
&{} = \gamma_{n} I_{n} - \mu R
\end{alignedat}
where
S, I_{j}, R \ge 0
,
S + \sum_{j} I_{j} + R = 1
,
F
is a forcing function, and
H
is a susceptible heterogeneity function.
In general, F
and H
are nonlinear. In the standard
SIR equations, F
is 1 and H
is the identity function.
Nondimensionalization using parameters
\mathcal{R}_{0,j} = \beta_{j}/(\gamma_{j} + \mu)
,
\ell_{j} = (1/(\gamma_{j} + \mu))/t_{+}
, and
\varepsilon = t_{+}/(1/\mu)
and independent variable
\tau = t/t_{+}
,
where
t_{+} = \sum_{j:\mathcal{R}_{0,j} > 0} 1/(\gamma_{j} + \mu)
designates as a natural time unit the mean time spent infectious, gives
\begin{alignedat}{4}
\text{d} & S &{} / \text{d} \tau
&{} = \varepsilon (1 - S) - (\textstyle\sum_{j} (\mathcal{R}_{0,j}/\ell_{j}) I_{j}) F H(S) \\
\text{d} & I_{ 1} &{} / \text{d} \tau
&{} = (\textstyle\sum_{j} (\mathcal{R}_{0,j}/\ell_{j}) I_{j}) F H(S) - (1/\ell_{1} + \varepsilon) I_{1} \\
\text{d} & I_{j + 1} &{} / \text{d} \tau
&{} = (1/\ell_{j}) I_{j} - (1/\ell_{j+1} + \varepsilon) I_{j + 1} \\
\text{d} & R &{} / \text{d} \tau
&{} = (1/\ell_{n}) I_{n} - \varepsilon R
\end{alignedat}
sir.aoi
works with the nondimensional equations, dropping the
last equation (which is redundant given
R = 1 - S - \sum_{j} I_{j}
) and augments the
resulting system of 1 + n
equations with a new equation
\text{d}Y/\text{d}\tau = (\textstyle\sum_{j} (\mathcal{R}_{0,j}/\ell_{j}) I_{j}) (H(S) - 1/(\textstyle\sum_{j} \mathcal{R}_{0, j}))
due to the usefulness of the solution Y
in applications.
root = NULL |
a “multiple time series” object, inheriting from class
|
root = function (tau , S , I , Y , dS , dI , dY , R0 , ell) |
a numeric vector of length |
If aggregate = TRUE
, then infected compartments are aggregated so
that the number of columns (elements, if root
is a function)
named I
is 1 rather than n
. This column (element) stores
prevalence, the proportion of the population that is infected.
For convenience, there are 4 additional columns (elements) named
I.E
, I.I
, foi
, and inc
. These store the
non-infectious and infectious components of prevalence (so that
I.E + I.I = I
), the force of infection, and incidence.
The method for summary
returns a numeric vector of length
2 containing the left and right “tail exponents” of the variable
V
indicated by name
, defined as the asymptotic values of
the slope of \log(V)
. NaN
elements indicate that
a tail exponent cannot be approximated because the time window
represented by object
does not cover enough of the tail, where
the meaning of “enough” is set by tol
.
sir.aoi
is not a special case of sir
nor a
generalization. The two functions were developed independently and for
different purposes: sir.aoi
to validate analytical results
concerning the SIR equations as formulated here, sir
to simulate
incidence time series suitable for testing fastbeta
.
if (requireNamespace("deSolve")) withAutoprint({
to <- 100; by <- 0.01; R0 <- c(0, 16); ell <- c(0.5, 1)
peak <- sir.aoi(to = to, by = by, R0 = R0, ell = ell,
root = function (S, R0) sum(R0) * S - 1,
aggregate = TRUE)
peak
to <- 4 * peak[["tau"]] # a more principled endpoint
soln <- sir.aoi(to = to, by = by, R0 = R0, ell = ell,
aggregate = TRUE, atol = 0, rtol = 1e-12)
## ^^^^ ^^^^
## 'atol', 'rtol', ... are passed to deSolve::ode
head(soln)
tail(soln)
plot(soln) # dispatching stats:::plot.ts
plot(soln, log = "y")
(lamb <- summary(soln)) # left and right tail exponents
xoff <- function (x, k) x - x[k]
k <- c(16L, nrow(soln)) # c(1L, nrow(soln)) worse due to transient
plot(soln[, "Y"], log = "y", ylab = "Y")
abline(v = peak[["tau"]], h = peak[["Y"]],
lty = 2, lwd = 2, col = "red")
for (i in 1:2)
lines(soln[k[i], "Y"] * exp(lamb[i] * xoff(time(soln), k[i])),
lty = 2, lwd = 2, col = "red")
wrap <-
function (root)
sir.aoi(to = to, by = by, R0 = R0, ell = ell,
root = root, aggregate = TRUE)
Ymax <- peak[["Y"]]
## NB: want *simple* roots, not *multiple* roots
L <- list(function (Y) (Y - Ymax * 0.5) ,
function (Y) (Y - Ymax * 0.5)^2,
function (Y) (Y - Ymax ) ,
function (Y) (Y - Ymax )^2)
lapply(L, wrap)
## NB: critical values can be attained twice
L <- list(function (Y, dY) if (dY > 0) Y - Ymax * 0.5 else 1,
function (Y, dY) if (dY < 0) Y - Ymax * 0.5 else 1)
lapply(L, wrap)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.