Aimee Kopolow
2014-Apr-02 03:51 UTC
[R] Difficulty coding time-forced functions in deSolve
Hi all,
I'm trying to use deSolve to solve a series of differential equations
with rk4 mimicking a SEIR model, while including an event/function
that is not solely time-dependent.
Explicitly:
I want to introduce vaccination 7 days after the proportion of I2/N2
reaches 0.01.
Here is the code I am using:
require(deSolve)
require(sfsmisc)
SEIR <- function(t, x, p) {
with(as.list(c(x,p)),{
dS<-b*N-d*S-beta*S*I/N-V(I, N, t)*S
dE<- -d*E+beta*S*I/N -epsilon*E-V(I, N, t)*E
dI<- -d*I+epsilon*E-gamma*I-mu*I-V(I, N, t)*I
dR<--d*R+gamma*I+V(I, N, t)*S+V(I, N, t)*E+V(I, N, t)*I
dN<-dS+dE+dI+dR
list(c(dS, dE, dI, dR, dN))
})
}
V <-function(I, N, t) {ifelse(t >=8 & I[t-7]/N[t-7]>0.01, 0.25, 0)}
num_years <- 10.0
time_limit <-num_years*365.00
Ni <-1.0E3
b <-1/(10.0*365)
d <-b
beta <-0.48
epsilon <-1/4
gamma <-1/4
mu <--log(1-0.25)*gamma
parms <-c(Ni=Ni, b=b, d=d, beta=beta, epsilon=epsilon, gamma=gamma, mu=mu)
xstart <-c(S=999, E=0, I=1, R=0, N=1000)
times <- seq(0.0, time_limit, 1.0)
tol <- 1e-16
my.atol <- rep(tol,5)
my.rtol <- 1e-12
out_rk4 <- as.data.frame(rk4(xstart, times, SEIR, parms))
outfilename <- paste("Basic SEIR.csv")
write.csv(out_rk4,file=outfilename,row.names=FALSE, col.names=FALSE)
If I remove function V and the associated parts within the
differential equations, the model runs just fine. If I define V as
V<-function(I, N) {ifelse(I/N >0.01, 0.25, 0)
the model functions just fine.
Any pointers as to how I can code a function that relies on solutions
from previous time steps?
thank you in advance,
Aimee.
Thomas Petzoldt
2014-Apr-02 06:47 UTC
[R] Difficulty coding time-forced functions in deSolve
On 4/2/2014 5:51 AM, Aimee Kopolow wrote:> Any pointers as to how I can code a function that relies on solutions > from previous time steps?Such a system would be called a delay differential equation (DDE). It can be solved with the dede function, see ?dede for details. However if you want to model something like this: > Explicitly: > I want to introduce vaccination 7 days after the proportion of I2/N2 > reaches 0.01. Than this is called "root finding", that can be combined with events, see example "EVENTS triggered by a root function" in ?events. More can be found in the papers listed at: http://desolve.r-forge.r-project.org ... or you may consider to ask the R-sig-dynamic models mailing list: https://stat.ethz.ch/mailman/listinfo/r-sig-dynamic-models Hope it helps Thomas Petzoldt Dr. Thomas Petzoldt Technische Universitaet Dresden Faculty of Environmental Sciences Institute of Hydrobiology 01062 Dresden, Germany http://tu-dresden.de/Members/thomas.petzoldt
All, I'm getting this:> sprintf("%.17f", 0.8)[1] "0.80000000000000004" Where does the `4` at the end come from? Shouldn't it be zero at the end? Maybe I'm missing something.> sessionInfo()R version 3.0.2 (2013-09-25) Platform: x86_64-redhat-linux-gnu (64-bit) locale: [1] LC_CTYPE=en_US.utf8 LC_NUMERIC=C LC_TIME=en_US.utf8 [4] LC_COLLATE=en_US.utf8 LC_MONETARY=en_US.utf8 LC_MESSAGES=en_US.utf8 [7] LC_PAPER=en_US.utf8 LC_NAME=C LC_ADDRESS=C [10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.utf8 LC_IDENTIFICATION=C attached base packages: [1] stats graphics grDevices utils datasets methods base Thanks, M
Thomas Petzoldt
2014-Apr-05 19:52 UTC
[R] Difficulty coding time-forced functions in deSolve
Hi,
does the following help you?
Thomas
require(deSolve)
SEIR <- function(t, x, p) {
if (t < 7)
xlag <- x
else
xlag <- lagvalue(t - 7)
V <- ifelse(xlag[3]/sum(xlag) > 0.01, 0.25, 0)
## uncomment the following for printing some internal information
#cat("t=", t, " -- ")
#cat(xlag, " -- ", V, "\n")
N <- sum(x)
with(as.list(c(x,p)),{
dS<- b*N - d*S - beta*S*I/N - V*S
dE<- -d*E+beta*S*I/N - epsilon*E - V*E
dI<- -d*I + epsilon*E - gamma*I - mu*I - V*I
dR<- -d*R + gamma*I + V*S + V*E + V*I
list(c(dS, dE, dI, dR), N = unname(N), V = unname(V))
})
}
num_years <- 1
time_limit <- num_years*365.00
b <- 1/(10.0*365)
d <- b
beta <- 0.48
epsilon <- 1/4
gamma <- 1/4
mu <- -log(1-0.25)*gamma
parms <- c(b=b, d=d, beta=beta, epsilon=epsilon, gamma=gamma, mu=mu)
xstart <-c(S=999, E=0, I=1, R=0)
times <- seq(0.0, time_limit, 1.0)
out <- dede(xstart, times, SEIR, parms, rtol=1e-8, atol=1e-8)
plot(out)