shai
shai

Reputation: 3

Solving a system of multiple ODEs in R

I have a system with X connected patches, each has a simple predator-prey model like that:

C_i = r_c*C -d*C + e*P + b*\sum_j(A_ij*C_j)
P_i = r_p*P +e*P + b*\sum_j(A_ij*P_j)

where C_i and P_i are consumer and prey abundances in patch i; r_c,r_p are growth rates; d is rate of consumer death, e is rate of prey intake. The last term in each equation is the influx of consumers or prey: A_ij is a matrix indicating if patches i and j are connected, and b is a rate of migration from patch j. (My system is more complicated but this simple example will do).

This kind of system will require as many ODE systems as there are patches. Any idea how to implement this kind of system? I know how to implement it for a single patch (no indices and no influx term) with deSolve. So any solution with deSolve is preferred.

Latex version of equations: Consumer equation in patch i Prey equation in patch i

Upvotes: 0

Views: 138

Answers (2)

tpetzoldt
tpetzoldt

Reputation: 5813

Here a more meta-population related example following our off-list discussion. Please not that this is just experimental and comes WITHOUT WARRANTY. Feedback and improvements are welcome.

library(deSolve)

n <- 7 # number of metapopulations
beta  <- rep(c(-500, 500, 0), each = n)
gamma <- rep(c(0, -365/13, 365/13), each = n)

## case(1) a "fully connected" system
#mig <- 1e-10 # migration rate
#As <- matrix(mig, nrow=n, ncol=n)
#diag(As) <- 0

## case (2) directed move
mig <- 0.0001 # migration rate
As <- matrix(0, nrow=n, ncol=n)
As[1:(n-1), 2:n] <- diag(mig, n-1)
As[2:n, 1:(n-1)] <- As[2:n, 1:(n-1)] + diag(mig, n-1)

## case (3) enter migration matrix manually ...

## expand movement to full matrix, within respective states S, I, R
## assumes that all states move equally; this can of course be changed
A <- matrix(0, nrow = 3 * n, ncol = 3 * n)
A[1:n, 1:n]                     <- As
A[(n+1):(2*n), (n+1):(2*n)]     <- As
A[(2*n+1):(3*n), (2*n+1):(3*n)] <- As

## balance: what moves to other cells needs to be removed from the cell itself
diag(A) <- -rowSums(A)

## migration matrix A
##   - positive values: what moves from the neighbors
##   - negative values: what moves to the neighbors
A

S <- rep(0.99, times=n)
I <-   c(0.01, rep(0, n-1)) # only first sub-population infected
R <- rep(0, times=n)

Y0 <- c(S, I, R)

sirmodel <- function(t, Y, parameters) {
  S <- Y[1:n]
  I <- Y[(n+1):(2*n)]
  #  dS <- -beta*S*I
  #  dI <- beta*S*I-gamma*I
  #  dR <- gamma*I
  dY <- beta * S * I + gamma * I + Y %*% A
  list(dY)
}

times <-seq(from=0, to=0.2, length.out=100)

out <- ode(y = Y0, times = times, func = sirmodel, parms = NULL)
windows(height = 6, width = 2 * n) # create somewhat bigger window
plot(out, xlab = "time", ylab = "-", mfrow=c(3, n))

Upvotes: 1

tpetzoldt
tpetzoldt

Reputation: 5813

The following matrix predator-prey model may serve as a starting point:

library(deSolve)

model <- function(t, n, parms) {
  with(parms, {
    dn <- r * n  + n * (A %*% n)
    list(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)
)

times = seq(0, 500, 0.1)
n0  = c(n1 = 1, n2 = 1, n3 = 2, n4 = 2)

out <- ode(n0, times, model, parms)
plot(out)

Upvotes: 2

Related Questions