Solving differential equation in R - deSolve - r

I have an equation as below;
dN/dt = N(t)G(t)
G(t) is given by the equation: dG/dt = a * G
How do I solve this in R, using ode function from deSolve package?

As dario already mentioned, the question lacks some details. Nevertheless, let's try an answer. If we assume that a < 0, the model looks like the ode formulation of Gompertz growth:
dN/dt = N * G
dG/dt = a * G
This can then be solved as:
library(deSolve)
model <- function(t, y, p) {
with(as.list(c(y, p)), {
dN <- N * G
dG <- a * G
list(c(dN, dG))
})
}
y <- c(N = 1, G = 1)
parms <- c(a = -0.1)
times <- seq(0, 100)
out <- ode(y, times, model, parms)
plot(out)

Related

How to customise a kernel function in R density package?

I want to use a new kernel function, called Epanech, in order to use for use in:
fit1 <- density(x=Data, bw = "nrd0", kernel = "Epanech").
Awaiting your response please accept my best regards.
Thank you very much.
The code of my new kernel function (for example Epanech) is:
x= faithful$eruptions
xgrid = seq(-1, 8, 0.1)
Epanech <- function(xvals, obs, h) {
h <- h * sqrt(5)
dens <- sapply(xvals, function(x) {
u <- abs(x - obs) / h
u <- ifelse(u > 1, 1, u)
sum(0.75*(1 - u^2))
})
dens/sum(dens * mean(diff(xvals)))
}

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.

Numerical Differentiation in 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.

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)

Jacobian for different variables

A differential equation might be defined as
sys <- function(t, y, p, u) {
dy <- numeric(2)
u <- u(t)
dy[1] = p$a*(1 + p$b*(y[2] - 1)/(p$c + y[2] - 1) - u*y[1])
dy[2] = u*y[1] - y[2]
list(dy)
}
Let's furthermore assume that the steady states (equilibria) are known. Now, is there a way to calculate the Jacobian matrix of the right hand side of with respect to x?
I know that I could define
f <- function(y){
c(
p$a*(1 + p$b*(y[2] - 1)/(p$c + y[2] - 1) - u*y[1]),
u*y[1] - y[2]
)
}
and calculate the Jacobian with
Jx <- jacobian(f, c(1,1))
wherein jacobian comes from the pracma package. But isn't there an easier way without that intermediate step? It might also help if one could call f within sys, e.g.
sys <- function(t, y, p, u) {
dy <- numeric(2)
u <- u(t)
dy[1] = f(y)[1]
dy[2] = f(y)[2]
list(dy)
}
And lastly, might there also be a way to calculate the Jacobian w.r.t. to u?
Thanks a lot!
There is a solution with the R package rootSolve.
For this, your function definition has to be a little bit different, but (in my opinion) more convenient. I don't know your exact parameters p or your function u, so I made a minimal example:
library(rootSolve)
sys <- function(t, y, parms) {
with(as.list(c(y,parms)),{
dy = a*(1 + b*(z - 1)/(c + z - 1) - 1*y)
dz = 1*y - z
return(list(c(dy, dz)))
})
}
parms <- list(a = 1, b = 1, c= 2)
rootSolve::jacobian.full(y = c(y = 1, z = 1), func = sys, parms = parms)
In the function jacobian.fully() you can use your steady state results, I just picked random results. The definition of sys uses the standard definition for ODEs in the package deSolve, an excellent package for solving ODEs.
The result is a normal Jacobian matrix.
So with this definition you can run solving algorithms for your equations, e.g.
library(deSolve)
ode <- deSolve::ode(y = c(y = 1, z = 0),
times = seq(1,100),
func = sys,
parms = parms)
plot(ode)
I hope this helps you a little bit!
Regards,
J_F

Resources