Grind uses the R-package deSolve
for numerical
integration (Soetaert, 2010) and that package requires a function
returning the derivatives of a model as a list. The form of that
function is \(f(t,s,p)\), where \(t\) is time, \(s\) is the state, and \(p\) are the parameters. For the
Lotka-Volterra model, \(R'=rR(1-R/K)-aRN\), and \(N'=caRN-dN\), the state, \(s\), is a vector of two variables, \(R\) and \(N\), and the parameters, \(p\), form a vector of 5 values. In Grind
both are defined as named vectors s <- c(R=1,N=0.01)
and
p <- c(r=1,K=1,a=1,c=1,d=0.5)
, respectively.
deSolve()
formatmodel <- function(t, state, parms) {
with(as.list(c(state,parms)), {
dR <- r*R*(1 - R/K) - a*R*N
dN <- c*a*R*N - d*N
return(list(c(dR, dN)))
})
}
s <- c(R=1,N=0.01)
p <- c(r=1,K=1,a=1,c=1,d=0.5)
model(0,s,p)
## [[1]]
## [1] -0.010 0.005
Thanks to the with(as.list(c(state,parms)), )
one can
write the ODEs just using the names of the variables and parameters.
model <- function(t, s, p) {
R <- s["R"]
N <- s["N"]
dR <- p["r"]*R*(1 - R/p["K"]) - p["a"]*R*N
dN <- p["c"]*p["a"]*R*N - p["d"]*N
return(list(c(dR, dN)))
}
model(0,s,p)
## [[1]]
## r c
## -0.010 0.005
which returns the same derivatives, but the notation of the model is much more cumbersome.
The R-function with()
is used to evaluate expressions
within some environment like a list
(or a
data.frame
). For instance
with(as.list(p),r+K)
## [1] 2
prints the sum of \(r\) and \(K\) from the vector p
. And
with(as.list(c(s,p)),r*R)
## [1] 1
prints the value of \(rR\).
Soetaert, K., Petzoldt, T., and Setzer, R. W., 2010. Solving differential equations in R: Package deSolve. Journal of Statistical Software 33:1-25.