Differential Equations in R: Tutorial User Conference 2011
Differential Equations in R: Tutorial User Conference 2011
Outline
Outline
Installing
or via commandline
install.packages("deSolve", dependencies = TRUE)
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Installing
Installing
Necessary packages
Getting help
Getting help
One equation
Model specification
Let’s begin . . .
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
One equation
Logistic growth
Differential equation
dN N
=r ·N · 1−
dt K
Analytical solution
KN0 e rt
Nt =
K + N0 (e rt − 1)
R implementation
> logistic <- function(t, r, K, N0) {
+ K * N0 * exp(r * t) / (K + N0 * (exp(r * t) - 1))
+ }
> plot(0:100, logistic(t = 0:100, r = 0.1, K = 10, N0 = 0.1))
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
One equation
Numerical simulation in R
Why R?
I If standard tool for statistics, why x$$$ for dynamic simulations?
I Other reasons will show up at this conference (useR!2011).
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
One equation
http://desolve.r-forge.r-project.org
library(deSolve)
model <- function (time, y, parms) {
with(as.list(c(y, parms)), {
dN <- r * N * (1 - N / K) Differential equation
list(dN) „similar to formula on paper"
})
}
plot(out)
One equation
Inspecting output
I Print to screen
> head(out, n = 4)
time N
[1,] 0 0.1000000
[2,] 1 0.1104022
[3,] 2 0.1218708
[4,] 3 0.1345160
I Summary
> summary(out)
N
Min. 0.100000
1st Qu. 1.096000
Median 5.999000
Mean 5.396000
3rd Qu. 9.481000
Max. 9.955000
N 101.000000
sd 3.902511
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
One equation
I Plotting
> plot(out, main = "logistic growth", lwd = 2)
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
One equation
--------------------
INTEGER values
--------------------
Coupled equations
Problem [3]
I Euler equations of a rigid body without external forces.
I Three dependent variables (y1 , y2 , y3 ), the coordinates of the
rotation vector,
I I1 , I2 , I3 are the principal moments of inertia.
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Coupled equations
Differential equation
y10 = (I2 − I3 )/I1 · y2 y3
y20 = (I3 − I1 )/I2 · y1 y3
y30 = (I1 − I2 )/I3 · y1 y2
Parameters
I1 = 0.5, I2 = 2, I3 = 3
Initial conditions
y1 (0) = 1, y2 (0) = 0, y3 (0) = 0.9
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Coupled equations
R implementation
> library(deSolve)
> rigidode <- function(t, y, parms) {
+ dy1 <- -2 * y[2] * y[3]
+ dy2 <- 1.25* y[1] * y[3]
+ dy3 <- -0.5* y[1] * y[2]
+ list(c(dy1, dy2, dy3))
+ }
> yini <- c(y1 = 1, y2 = 0, y3 = 0.9)
> times <- seq(from = 0, to = 20, by = 0.01)
> out <- ode (times = times, y = yini, func = rigidode, parms = NULL)
> head (out, n = 3)
time y1 y2 y3
[1,] 0.00 1.0000000 0.00000000 0.9000000
[2,] 0.01 0.9998988 0.01124925 0.8999719
[3,] 0.02 0.9995951 0.02249553 0.8998875
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Coupled equations
Exercise
y10 = −y2 − y3
y20 = y1 + a · y2
y30 = b + y3 · (y1 − c)
Parameters
a = 0.2, b = 0.2, c = 5
Initial Conditions
y1 = 1, y2 = 1, y3 = 1
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Exercise
Tasks:
I Solve the ODEs on the interval [0, 100]
I Produce a 3-D phase-plane plot
I Use file examples/rigidODE.R.txt as a template
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Solvers ...
Solvers
Euler
Solvers
Function Description
lsoda [9] IVP ODEs, full or banded Jacobian, automatic choice for
stiff or non-stiff method
lsodar [9] same as lsoda; includes a root-solving procedure.
lsode [5], IVP ODEs, full or banded Jacobian, user specifies if stiff
vode [2] (bdf) or non-stiff (adams)
lsodes [5] IVP ODEs; arbitrary sparse Jacobian, stiff
rk4, rk, IVP ODEs; Runge-Kutta and Euler methods
euler
radau [4] IVP ODEs+DAEs; implicit Runge-Kutta method
daspk [1] IVP ODEs+DAEs; bdf and adams method
zvode IVP ODEs, like vode but for complex variables
adapted from [19].
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Solvers
Lags (DDE)
F(y’,t,y)=0
My’=f(t,y)
Nesting
y’=f(t,y)
Events
Roots
stiff
Solver Notes
adapted
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Solvers
Solvers
Problem type?
I ODE: use ode,
I DDE: use dede,
I DAE: daspk or radau,
I PDE: ode.1D, ode.2D, ode.3D,
. . . others for specific purposes, e.g. root finding, difference equations (euler,
iteration) or just to have a comprehensive solver suite (rk4, ode45).
Stiffness
I default solver lsoda selects method automatically,
I adams or bdf may speed up a little bit if degree of stiffness is known,
I vode or radau may help in difficult situations.
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Stiffness
But: “stiff solvers” slightly less efficient for “well behaving” systems.
I Good news: lsoda selects automatically between stiff solver (bdf)
and nonstiff method (adams).
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Stiffness
y10 = y2
y20 = µ · (1 − y1 2 ) · y2 − y1
Stiffness
Model implementation
> library(deSolve)
> vdpol <- function (t, y, mu) {
+ list(c(
+ y[2],
+ mu * (1 - y[1]^2) * y[2] - y[1]
+ ))
+ }
> yini <- c(y1 = 2, y2 = 0)
> stiff <- ode(y = yini, func = vdpol, times = 0:3000, parms = 1000)
> nonstiff <- ode(y = yini, func = vdpol, times = seq(0, 30, 0.01), parms = 1)
> head(stiff, n = 5)
time y1 y2
[1,] 0 2.000000 0.0000000000
[2,] 1 1.999333 -0.0006670373
[3,] 2 1.998666 -0.0006674088
[4,] 3 1.997998 -0.0006677807
[5,] 4 1.997330 -0.0006681535
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Stiffness
Interactive exercise
Stiffness
Plotting
Stiffness
Results
Accuracy
Accuracy
Overview
Example: Chaos
Chaos
The Lorenz equations
I chaotic dynamic system of ordinary differential equations
I three variables, X , Y and Z represent idealized behavior of the
earth’s atmosphere.
> chaos <- function(t, state, parameters) {
+ with(as.list(c(state)), {
+
+ dx <- -8/3 * x + y * z
+ dy <- -10 * (y - z)
+ dz <- -x * y + 28 * y - z
+
+ list(c(dx, dy, dz))
+ })
+ }
> yini <- c(x = 1, y = 1, z = 1)
> yini2 <- yini + c(1e-6, 0, 0)
> times <- seq(0, 100, 0.01)
> out <- ode(y = yini, times = times, func = chaos, parms = 0)
> out2 <- ode(y = yini2, times = times, func = chaos, parms = 0)
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Example: Chaos
Example: Chaos
Important:
upon returning the default mfrow is **NOT** restored
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Example: Chaos
Example: Chaos
Example: Chaos
Multiple scenarios
Multiple scenarios
Multiple scenarios
Observed data
Arguments obs and obspar are used to add observed data
> obs2 <- data.frame(time = c(1, 5, 10, 20, 25), y = c(12, 10, 8, 9, 10))
> plot(out, out2, obs = obs2, obspar = list(col = "red", pch = 18, cex = 2))
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Multiple scenarios
Observed data
A list of observed data is allowed
> obs2 <- data.frame(time = c(1, 5, 10, 20, 25), y = c(12, 10, 8, 9, 10))
> obs1 <- data.frame(time = c(1, 5, 10, 20, 25), y = c(1, 6, 8, 9, 10))
> plot(out, out2, col = c("blue", "red"), lwd = 2,
+ obs = list(obs1, obs2),
+ obspar = list(col = c("blue", "red"), pch = 18, cex = 2))
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
A solver does not have large problems with first two types of
discontinuities, but changing the values of state variables is much more
difficult.
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
External Variables
External Variables
Implementation in R
I R has an ingenious function that is especially suited for this task:
function approxfun
I It is used in two steps:
I First an interpolating function is constructed, that contains the data.
This is done before solving the differential equation.
afun <- approxfun(data)
I Within the derivative function, this interpolating function is called to
provide the interpolated value at the requested time point (t):
tvalue <- afun(t)
External Variables
External Variables
External Variables
Events
Events in R
I Events are part of a model; no restart necessary
I Separate dynamics inbetween events from events themselves
I Very neat and efficient!
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Events
Events
Problem Formulation
I Describe the concentration of the drug in the blood
I Drug injection occurs at known times → data.frame
Events
Events
Solve model
I Pass events to the solver in a list
I All solvers in deSolve can handle events
I Here we use the “implicit Adams” method
Events
Events
Events
A Bouncing Ball
> library(deSolve)
> ball <- function(t, y, parms) {
+ dy1 <- y[2]
+ dy2 <- -9.8
+
+ list(c(dy1, dy2))
+ }
> yini <- c(height = 0, velocity = 10)
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Events
Events
Events
Events
Events
r = 1, K = 10, y0 = 2
Events
This population is being harvested according to several strategies:
I There is no harvesting
I Every 2 days the population’s density is reduced to 50%
I When the species has reached 80% of its carrying capacity, its
density is halved.
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Events
Tasks:
I Run the model for 20 days
I Implement first strategy in a data.frame
I Second strategy requires root and event function
I Use file examples/logisticEvent.R.txt as a template
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
What?
Delay Differential Equations are similar to ODEs except that they involve
past values of variables and/or derivatives.
y0 1
= ayτ 1+y c − by
τ
yτ = y (t − τ ) (1)
yt = 0.5 for t ≤ 0
Solution in R
> library(deSolve)
> retarded <- function(t, y, parms, tau) {
+ tlag <- t - tau
+ if (tlag <= 0)
+ ylag <- 0.5
+ else
+ ylag <- lagvalue(tlag)
+
+ dy <- 0.2 * ylag * 1/(1+ylag^10) - 0.1 * y
+ list(dy = dy, ylag = ylag)
+ }
> yinit <- 0.5
> times <- seq(from = 0, to = 300, by = 0.1)
> yout1 <- dede(y = yinit, times = times, func = retarded, parms = NULL, tau = 10)
> yout2 <- dede(y = yinit, times = times, func = retarded, parms = NULL, tau = 20)
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Solution in R
> plot(yout1, lwd = 2, main = "tau=10", ylab = "y", mfrow = c(2, 2), which = 1)
> plot(yout1[,-1], type = "l", lwd = 2, xlab = "y")
> plot(yout2, lwd = 2, main = "tau=20", ylab = "y", mfrow = NULL, which = 1)
> plot(yout2[,-1], type = "l", lwd = 2, xlab = "y")
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
A nice variant of the logistic model is the DDE lemming model [14]:
y (t − τ )
y 0 = r · y (1 − ) (2)
K
Use file examples/ddelemming.R.txt as a template to implement this
model
I initial condition y (t = 0) = 19.001
∂C ∂C ∂2C
= −v + D 2 + f (t, x, C )
∂t ∂x ∂x
same for 2-D and 3-D
1-D PDEs
library(ReacTran) http://desolve.r-forge.r-project.org
image(out, grid = x)
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
1-D PDEs
1-D PDEs
1-D PDEs
1-D PDEs
1-D PDEs
Tasks
I The grid x extends from 0 to 1, and consists of 50 cells.
I Initial conditions:
2-D PDEs
Problem formulation
The Sine-Gordon equation is a non-linear hyperbolic (wave-like) partial
differential equation involving the sine of the dependent variable.
2-D PDEs
2-D Sine-Gordon in R
grid:
> Nx <- Ny <- 100
> xgrid <- setup.grid.1D(-7, 7, N = Nx); x <- xgrid$x.mid
> ygrid <- setup.grid.1D(-7, 7, N = Ny); y <- ygrid$x.mid
derivative function:
> sinegordon2D <- function(t, C, parms) {
+ u <- matrix(nrow = Nx, ncol = Ny, data = C[1 : (Nx*Ny)])
+ v <- matrix(nrow = Nx, ncol = Ny, data = C[(Nx*Ny+1) : (2*Nx*Ny)])
+ dv <- tran.2D (C = u, C.x.up = 0, C.x.down = 0, C.y.up = 0, C.y.down = 0,
+ D.x = 1, D.y = 1, dx = xgrid, dy = ygrid)$dC - sin(u)
+ list(c(v, dv))
+ }
initial conditions:
> peak <- function (x, y, x0, y0) return(exp(-( (x-x0)^2 + (y-y0)^2)))
> uini <- outer(x, y, FUN = function(x, y) peak(x, y, 2,2) + peak(x, y,-2,-2)
+ + peak(x, y,-2,2) + peak(x, y, 2,-2))
> vini <- rep(0, Nx*Ny)
solution:
> out <- ode.2D (y = c(uini,vini), times = 0:3, parms = 0, func = sinegordon2D,
+ names = c("u", "v"), dimens = c(Nx, Ny), method = "ode45")
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
2-D PDEs
2-D PDEs
2-D PDEs
2-D PDEs
2 2
∂X2
∂t = DX2 ∂∂xX21 + DX2 ∂∂yX21 + 3X1 − X12 X2
Tasks
I The grids x and y extend from 0 to 1, and consist of 50 cells.
I Parameter settings: diffusion coefficient:
I Use matrices,
I Implement essential parts in compiled code (Fortran, C),
I Implement the full method in compiled code.
Using matrices
Use of matrices
Source: examples/lv-plain-or-matrix.R.txt
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Using matrices
Use of matrices
A Lotka-Volterra model with 4 species
> model <- function(t, n, parms) {
+ with(parms, {
+ dn <- r * n + n * (A %*% n)
+ return(list(c(dn)))
+ })
+ }
> parms <- list(
+ r = c(r1 = 0.1, r2 = 0.1, r3 = -0.1, r4 = -0.1),
+ A = matrix(c(0.0, 0.0, -0.2, 0.0, # prey 1
+ 0.0, 0.0, 0.0, -0.1, # prey 2
+ 0.2, 0.0, 0.0, 0.0, # predator 1; eats prey 1
+ 0.0, 0.1, 0.0, 0.0), # predator 2; eats prey 2
+ nrow = 4, ncol = 4, byrow = TRUE)
+ )
> system.time(out <- ode(n0, times, model, parms))
user system elapsed
1.66 0.00 1.70
Source: examples/lv-plain-or-matrix.R.txt
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Using matrices
Results
Compiled code
examples/compiled_lorenz/compiledcode.svg
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Compiled code
The End
Thank you!
More Info:
http://desolve.r-forge.r-project.org
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Finally
Acknowledgments
Citation
A lot of effort went in creating this software; please cite it when using it.
I to cite deSolve: [20], rootSolve [19], ReacTran [16],
I Some complex examples can be found in [18],
I A framework to fit differential equation models to data is FME [17],
I A framework for ecological modelling is simecol [10].
Acknowledgments
I None of this would be possible without the splendid work of the R
Core Team [11],
I This presentation was created with Sweave [7],
I Creation of the packages made use of Rforge [21].
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Finally
Bibliography I
[1] K E Brenan, S L Campbell, and L R Petzold.
Numerical Solution of Initial-Value Problems in Differential-Algebraic Equations.
SIAM Classics in Applied Mathematics, 1996.
[2] P N Brown, G D Byrne, and A C Hindmarsh.
Vode, a variable-coefficient ode solver.
SIAM Journal on Scientific and Statistical Computing, 10:1038–1051, 1989.
[3] E Hairer, S. P. Norsett, and G Wanner.
Solving Ordinary Differential Equations I: Nonstiff Problems. Second Revised Edition.
Springer-Verlag, Heidelberg, 2009.
[4] E Hairer and G Wanner.
Solving Ordinary Differential Equations II: Stiff and Differential-Algebraic Problems. Second Revised Edition.
Springer-Verlag, Heidelberg, 2010.
[5] A. C. Hindmarsh.
ODEPACK, a systematized collection of ODE solvers.
In R. Stepleman, editor, Scientific Computing, Vol. 1 of IMACS Transactions on Scientific Computation, pages 55–64. IMACS /
North-Holland, Amsterdam, 1983.
[6] R. Lefever, G. Nicolis, and I. Prigogine.
On the occurrence of oscillations around the steady state in systems of chemical reactions far from equilibrium.
Journal of Chemical Physics, 47:1045–1047, 1967.
[7] Friedrich Leisch.
Dynamic generation of statistical reports using literate data analysis.
In W. Härdle and B. Rönz, editors, COMPSTAT 2002 – Proceedings in Computational Statistics, pages 575–580, Heidelberg, 2002.
Physica-Verlag.
[8] M. C. Mackey and L. Glass.
Oscillation and chaos in physiological control systems.
Science, 197:287–289, 1977.
Introduction Model Specification Solvers Plotting Forcings + Events Delay Diff. Equations Partial Diff. Equations Speeding up
Finally
Bibliography II
[9] Linda R. Petzold.
Automatic selection of methods for solving stiff and nonstiff systems of ordinary differential equations.
SIAM Journal on Scientific and Statistical Computing, 4:136–148, 1983.
[10] Thomas Petzoldt and Karsten Rinke.
simecol: An object-oriented framework for ecological modeling in R.
Journal of Statistical Software, 22(9):1–31, 2007.
Finally
Bibliography III