Reputation: 3
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
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
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