[R-sig-dyn-mod] better implementation of variable species ode.2D model

Thomas Petzoldt thomas.petzoldt at tu-dresden.de
Sat Feb 25 23:36:14 CET 2017


Hi,

loops are not always bad, but one should avoid them in functions that 
are repeatedly called. As said, matrix-computations can help. See the 2D 
L&V model at page 10 of

http://dx.doi.org/10.18637/jss.v033.i09

or the 2D SIR model below with or without ReacTran.

ThPe



-------------- next part --------------
library(deSolve)
library(ReacTran)


## The model equations
SIR2D <- function (t, y, parms)  {
  S  <- matrix(y[ndx], N, N)
  I  <- matrix(y[N^2 + ndx], N, N)
  R  <- matrix(y[2*(N^2) + ndx], N, N)

  infect <- beta * I * S
  recovr <- nu * I

  dS <- -infect
  dI <- infect - recovr
  dR <- recovr

  if (reactran) {
    dI <- dI + tran.2D(I, dx = dx, dy = dy, D.x = D, D.y = D)$dC
  } else {
    Flux.Ix <- -D * rbind(zero, (I[2:N,] - I[1:(N-1),]), zero)/dx
    Flux.Iy <- -D * cbind(zero, (I[,2:N] - I[,1:(N-1)]), zero)/dy

    dFlux.I  <- (Flux.Ix[1:N,] - Flux.Ix[2:(N+1),])/dx +
                (Flux.Iy[,1:N] - Flux.Iy[,2:(N+1)])/dy

    dI <- dI + dFlux.I
  }
  list(c(dS, dI, dR))
}

## grid
N     <- 101
zero <- rep(0, N)
ndx <- 1:N^2
dx <- 10/N
dy <- 10/N

## model parameters
D     <- 1e-3
S0    <- 100
I0    <- 1
R0    <- 0.0
beta  <- 0.001
nu    <- 0.02


# initial conditions
S  <- matrix(nrow = N, ncol = N, data = S0)
I  <- matrix(nrow = N, ncol = N, data = 0)
R  <- matrix(nrow = N, ncol = N, data = R0)

set.seed(123)
I[sample(1:length(I), 10)] <- I0
#dim(I) <- c(N, N)  # redundant

y <- c(S = S, I = I, R = R)

times <- 0:200

reactran <- TRUE

system.time(
  out <- ode.2D (y = y, func = SIR2D, t = times, nspec=3, parms = NULL,
                dim = c(N, N), method = "adams")
)


windows(width=15, height=5)
image(out, select=1:3, legend = TRUE, ask=FALSE, main=c("Susceptible", "Infectious", "Recovered"), mfrow=c(1,3))



More information about the R-sig-dynamic-models mailing list