Numerical Differentiation in R - r

I'm currently trying to calculate finite differences in R using the fderiv method from the pracma library. I've developed the method to identify the Lorenz derivatives below:
library(deSolve)
parameters <- c(s = 10, r = 28, b = 8/3) # Lorenz Parameters: sigma, rho, beta
state <- c(X = -8, Y = 7, Z = 27) # Initial State
# Lorenz Function used to generate Lorenz Derivatives
lorenz <- function(t, state, parameters) {
with(as.list(c(state, parameters)), {
dX <- s * (Y - X)
dY <- X * (r - Z) - Y
dZ <- X * Y - b * Z
list(c(dX, dY, dZ))
})
}
times <- seq(0.01, 100, by = 0.01)
# ODE45 used to determine Lorenz Matrix
out <- ode(y = state, times = times, func = lorenz, parms = parameters)
However, I'm struggling to develop the first or second order differences from this function. When I use fderiv(Vectorize(lorenz), state = state, parameters = parameters, x = times, n = 1, "forward") I get the error Error in eval(substitute(expr), data, enclos = parent.frame()) : object 'Y' not found. I was hoping for insight on how I can develop these finite differences with fderiv.
Thanks in advance.

Related

Estimate the basic reproductive number(R0) of Covid-19 using the next-generation matrix(NGM)

I want to estimate the basic reproductive number(R0) of Covid-19 using the next-generation matrix method. I have a complemental model as follows:
rm(list = ls())
library(deSolve)
library(rootSolve)
pars<- c( R0=8,inter.eff=0.75,
inter.start=1,e.dur=3,i.dur=10,cfr=0.0003)
tout <- seq(1, 2, by = 1)
derivs <- function(t, state, pars){
with(as.list(c(state, pars)),{
num <- S + E + I + R# Population size
# Effective contact rate and FOI from a rearrangement of Beta * c * D
ce <- R0 / i.dur
lambda <- ce * I/num
if (!is.null(inter.eff) && t >= inter.start) {
lambda <- lambda * (1 - inter.eff)
}
dS <- -lambda*S
dE <- lambda*S - (1/e.dur)*E
dI <- (1/e.dur)*E - (1 - cfr)*(1/i.dur)*I - cfr*(1/i.dur)*I
dR <- (1 - cfr)*(1/i.dur)*I
# Compartments and flows are part of the derivative vector
# Other calculations to be output are outside the vector, but within the containing list
list(c(dS, dE, dI, dR))
})
}
And consequently, an ordinary differential system as follows:
v<-as.data.frame( ode(y = c(S=64000000,
E=1000, I=5, R=3),
times = tout, func = derivs,
parms = pars,method = "euler"))
In the next step, I want to estimate the Jacobin matrix for each row of the v.The last code I wrote for this purpose was as follows, but unfortunately, I did not get the result. So that a matrix is estimated as a whole and not for each row of the v.Please help me if possible.
v<- v[,-c(1)]#Delete time column
for (i in 1:nrow(v) ){
r<-jacobian.full(y= c(S=v[i,1], E=v[i,2], I=v[i,3],
R=v[i,4]),
func=derivs,
parms =pars,
pert = 1e-8)
}
The solution is:
`product = function(x, output){
S=x[1]
E=x[2]
I= x[3]
R=x[4]
w<-jacobian.full(y= c(S, E, I,
R),
func=derivs,
parms =pars,
pert = 1e-8)
# return product
return(as.data.frame( w))
}
single <- apply(v,1,product )`

deSolve ODE Integration Error, am I using the wrong function?

I'm attempting to solve a set of equations related to biological processes. One equation (of about 5) is for a pharmacokinetic (PK) curve of the form C = Co(exp(k1*t)-exp(k2*t). The need is to simultaneously solve the derivative of this equation along with some enzyme binding equations and initial results where not as expected. After troubleshooting, realized that the PK derivative doesn't numerically integrate by itself, if k is negative using the desolve ode function. I've attempted every method (lsode, lsoda, etc) in the ode function, with no success. I've tried adjusting rtol, it doesn't resolve.
Is there an alternative to the deSolve ode function I should investigate? Or another way to get at this problem?
Below is the code with a simplified equation to demonstrate the problem.
When k is negative, the integrated solution does not match the analytical result.
When k is positive, results are as expected.
First Image, result with k=0.2: Analytical and Integrated results match when k is positive
Second Image, result with k=-0.2: Integrated result does not match analytical when k is negative
library(deSolve)
abi <- function(t, state, parameters) {
with(as.list(c(state, parameters)), {
dI <- k*exp(k*t)
list(c(dI))
})
}
k <- c(-0.2)
times <- seq(0, 24, by = 1)
I_analytical <- exp(k*times)
parameters <- c(k)
state <- c(I = 0)
out <- ode(y = state, times = times, func = abi, parms = parameters)
plot(out)
points(I_analytical ~ times)
It was pointed out that the initial condition easily resolves the above example, which is very helpful. Here is the equation I can't accurately integrate, I've tried a few different initial conditions without real success.
library(deSolve)
## Chaos in the atmosphere
CYP <- function(t, state, parameters) {
with(as.list(c(state, parameters)), {
#dE <- ksyn - (kdeg * E) + (k2 * EI) - (k1 * E * I)
#dEI <- (k1 * E * I) - (k2 * EI) + (k4 * EIstar) - (k3 * EI)
#dEIstar <- (k3 * EI) - (k4 * EIstar)
#dOcc <- dEI + dEIstar
dI <- a*tau1*exp(tau1*t) + b*tau2*exp(tau2*t) + c*tau3*exp(tau3*t)
#list(c(dE, dEI, dEIstar, dOcc, dI))
list(c(dI))
})
}
ifit <- c(-0.956144311,0.82619445,0.024520276,-0.913499862,-0.407478829,-0.037174745)
a = ifit[1]
b = ifit[2]
c = ifit[3]
tau1 = ifit[4]
tau2 = ifit[5]
tau3 = ifit[6]
parameters <- c(ksyn = 0.82, kdeg = 0.02, k1 = 2808, k2 = 370.66, k3 = 2.12, k4 = 0.017, a, b, c, tau1, tau2, tau3)
#state <- c(E = 41, EI = 0, EIstar = 0, Occupancy = 0, I = 0.0)
state <- c(I=-0.01)
times <- seq(0, 24, by = .1)
out <- ode(y = state, times = times, func = CYP, parms = parameters)
I_analytical <- a*exp(tau1*times) + b*exp(tau2*times) + c*exp(tau3*times)
plot(out)
points(I_analytical ~ times)
Target curve and the ode solution line.
The initial value should be
state <- c(I= a + b + c)
#state <- c(I = 1)
The first script contains several issues. The most important two are that (1) the model function (abi) must contain the derivative, not an integrated function, while (2) the analytically integrated model missed I_0 that results from the integration constant.
Let's assume a first order decay model
dI/dt = k I
then analytical integration yields
I_t = I_0 exp(kt)
The code is then:
library(deSolve)
abi <- function(t, state, parameters) {
with(as.list(c(state, parameters)), {
# dI <- k*exp(k*t) # original
dI <- k * I # corrected, should be the dervivative
list(c(dI))
})
}
k <- -0.2 # simplified, c() was not necessary
times <- seq(0, 24, by = 1)
# correction: set I0 to a value > zero
I0 <- 10
# I_analytical <- exp(k*times) # original
I_analytical <- I0 * exp(k*times) # corrected, multiplied with I0
#state <- c(I = 0) # original
state <- c(I = I0) # corrected
parameters <- c(k = k)
out <- ode(y = state, times = times, func = abi, parms = parameters)
plot(out)
points(I_analytical ~ times)
This code can be further simplified if you want.

R deSolve: how are arguments en thus parameters interpreted?

I'm building predator-prey models based on Lotka-Volterra derivatives in R using package deSolve. I define parameters, initial state and timesteps and the model function. Then I solve everyting using ode() or dede() when using a time lag.
I noticed there's a big difference in output depending on how you define the parameters WITHIN the model function and I really don't understand why. You can extract the parameters either by calling them via the argument: parms['r'], or via the previously defined object I passed to the argument: parameters['r']. Same result in both cases.
This is different voor the initial state though: calling the argument: y[1] or y['N'], gives a totally different result than calling it via the object passed to the argument: init[1] or init['N'].
Also in the DDE: there's a difference in time - tau vs times - tau and ylag <- y vs ylag <- init.
Why is there a different result for argument vs object for the initial state and time and not for the parameters? I need to comprehend this well in order to use the FME package in a later stage, so I hope someone can explain this behaviour.
My code:
library(deSolve)
## Parameters
parameters <- c(r = 0.25, K = 200, a = 0.01, c = 0.01, m = 1, tau = 7)
init <- c(N = 20, P = 2)
time <- seq(0, 100, by = 0.01)
## Ordinary DE
PreyPred <- function(times, y, parms){ #chose same argument names as ode()
N <- y['N'] #y[1] works as well
P <- y['P']
#N <- init['N'] #(or init[1]) gives a totally different result!
#P <- init['P']
r <- parms['r'] #growth rate prey parameters['r'] gives same result
K <- parms['K'] #carrying capacity prey
a <- parms['a'] #attack rate predator
c <- parms['c'] #assimilation rate (?) predator
m <- parms['m'] #mortality predator
dN <- r * N * (1-N/K) - a * N * P
dP <- c * N * P - m * P
return(list(c(dN, dP)))
}
oderesult <- ode(func = PreyPred, parms = parameters, y = init, times = time)
plot(oderesult, lwd = 2, mfrow = c(1,2))
## Delayed DE
PreyPredLag <- function(times, y, parms){
N <- y['N']
P <- y['P']
#N <- init['N']
#P <- init['P']
r <- parms['r'] #growth rate prey
K <- parms['K'] #carrying capacity prey
a <- parms['a'] #attack rate predator
c <- parms['c'] #assimilation rate (?) predator
m <- parms['m'] #mortality predator
tau <- parms['tau'] #time lag
tlag <- times - tau
#tlag <- time - tau #different result
if (tlag < 0)
ylag <- y
#ylag <- init
else
ylag <- lagvalue(tlag)
# dede
dN <- r * N * (1-N/K) - a * N * P
dP <- c * ylag[1] * ylag[2] - m * P
return(list(c(dN, dP), lag = ylag))
}
dederesult <- dede(func = PreyPredLag, parms = parameters, y = init, times = time)
plot(dederesult, lwd = 2, mfrow = c(2,2))
The observed behavior is correct. A short explanation:
'parms' is the local variable in the model function, while 'parameters' the global variable in the workspace. This is nothing special for deSolve, it is the general way how R works. The in most cases preferred way is to use the local variable.
For the states, this is indeed different. here the outer value 'init' is the initial value at the beginning, while the local 'y' is the current value for the time step.
The dede parameters are analogous. init is the start, y the instantaneous value, times is the global vector of all time steps and time the actual time step.

How to program a differential equation of form dy/dt = f(t,y) (i.e. time is in differential equation) in R?

I am trying to simulate a model with this differential equation for concentration A:
dA/dt = (a-b)*exp^(d*(s-t))
(The equations has parameters: a, b, d, and s.) I can not figure out how to use R to solve differential equations that have a t (time step) variable? I tried it with the function radau of the package deSolve (See beneath). I did not get the code to work. I also do not understand how to define the index variable? Or if this is solvable with this function at all? (All my other simpler differential equations I have ran in the past with the ode function of deSolve, worked fine).
I hope you can help me!
My try:
#Defining parameters
parameter <- c(a=0.03, b=0.02, d=0.01, s=179)
#Defining Function
Function1 <- function(t, y, parameter) { with (as.list(Y),
list(c(dA = (a-b)*exp^(d*(s-t)))))}
#Initial conditions
yini <- c(A=1)
#Mass matrix
M <- diag(nrow=1)
M[5,5] <- 0
M
#index/times/output
index <- c(1)
times <- seq(from = 0, to = 10, by = 0.01)
out <- radau(y = yini, func = Function1, parms = parameters, times = times, mass = M, nind = index)
plot(out, type = "l", lwd = 2)
I'm not sure what's up with M or index as they don't appear in your model, but here's code that runs and produces results based on your code.
#Defining parameters
parameter <- c(a=0.03, b=0.02, d=0.01, s=179)
#Defining Function
model <- function(t, y, parameter) {
with(as.list(parameter),{
dA <- (a - b) * exp(d * (s - t))
list(dA)
})
}
#Initial conditions
yini <- 1
# Output times
times <- seq(from = 0, to = 10, by = 0.01)
# Solve model
out <- ode(y = yini, func = model, parms = parameter, times = times)
# Plot results
plot(out, type = "l", lwd = 2)

changing a variable depending on time in R ODE solver

I have a model that has a differential equation in it, that I'm solving using odesolver in R. One of the parameters that you give to the ode function is times. Is there a way that you can change another variable depending on what time it is in the solver (e.g. for seasonal changes). What I'd like to do is something like the below, where ODETIME is the variable for times in ODE.
function1 <- function(r, y, x) {
z <- x[which(x$time = ODETIME),2]
list(- r * y * z)
}
N <- 10
r <- runif(N, 15, 20)
yini <- runif(N, 1, 40)
vals <- rep(1:5, 22)
times <- 0:10
x <- data.frame(time = rep(times, 10), vals)
out <- ode(y = yini, parms = NULL, times = times, func = function1)

Resources