thanhleviet
5/9/2016 - 9:42 AM

SIR metapopulation model for humans (page 242) (http://modelinginfectiousdiseases.org/)

SIR metapopulation model for humans (page 242) (http://modelinginfectiousdiseases.org/)

rm(list = ls())
p_load(deSolve)

# Thanh Le Viet
# May, 2016
# Human Metapopulation
# http://modelinginfectiousdiseases.org/
# Ported from python version at
# http://homepages.warwick.ac.uk/~masfz/ModelingInfectiousDiseases/Chapter7/Program_7.2/Program_7_2.py

n <- 5 #Number of population

# Setup the state and parameters
N0 <- S0 <- rep(0, n*n)
steps <- seq(1,n*n,n+1)
N0[steps] <- 1000
S0[steps] <- 800
I0 <- c(1,rep(0,n*n-1))

ll <- matrix(rep(0,n*n),nrow = n)
for (i in seq_len(n))
  for (j in seq_len(n))
    if (abs(i-j)==1)
      ll[i,j] <- 0.1

beta <- rep(1,n)*1 #Homogeneous

# beta <- rpois(n,2) #Inhomogeneous

gamma <- rep(1,n)*0.3
r <- matrix(rep(2,n*n),nrow = n)
diag(r) <- 0

INPUT0 <- c(S0,I0,N0)

INPUT <- rep(0, 3*n*n)

INPUT[seq(1,n*n*3,3)]  <- INPUT0[seq(1,n*n,1)]
INPUT[seq(2,n*n*3,3)] <- INPUT0[seq(n*n+1,2*n*n,1)]
INPUT[seq(3,n*n*3,3)] <- INPUT0[seq(n*n*2+1,3*n*n,1)]

metapop <- function(t, state, parameters){
  with(parameters, {
    Y <- rep(0,3*N*N)
    V <- state
    sumY <- rep(0,N)
    sumN <- rep(0,N)

    # R style: try to reduce the for loop and vectorise
    # for (i in seq_len(N)){
    #   k <- seq(1,3*N*N,3*N)
    #   iI <- seq(k[i]+1,3*N+k[i],3)
    #   iN <- seq(k[i]+2,3*N+k[i],3)
    #   sumY[i] <- sum(V[iI])
    #   sumN[i] <- sum(V[iN])
    # }

    # The following block returns the results as same as the block above
    for (I in seq_len(N)){
      for (J in seq_len(N)){
        i <- I - 1
        j <- J - 1
        k <- 3 * (j + i*N) + 1
        sumY[I] <- sumY[I] + V[1+k]
        sumN[I] <- sumN[I] + V[2+k]
      }
    }


    for (I in seq_len(N)){
      for (J in seq_len(N)){
        i <- I - 1
        j <- J - 1
        #Rate
        k <- 3*(j+i*N) + 1
        K <- 3*(i+j*N) + 1
        h <- 3*(i+i*N) + 1
        H <- 3*(j+j*N) + 1

        Y[k] <-  Y[k] - beta[I]*V[k]*(sumY[I]/sumN[I])
        Y[k+1] <-  Y[k+1] + beta[I]*V[k]*(sumY[I]/sumN[I])
        Y[k+1] <- Y[k+1] - gamma[I]*V[k+1]

        #Movement
        Y[h] <-  Y[h] + r[J,I]*V[K]
        Y[h] <- Y[h] - ll[J,I]*V[h]

        Y[h+1] <-  Y[h+1] + r[J,I]*V[K+1]
        Y[h+1] <- Y[h+1] - ll[J,I]*V[h+1]

        Y[h+2] <- Y[h+2] + r[J,I]*V[K+2]
        Y[h+2] <- Y[h+2] - ll[J,I]*V[h+2]

        Y[k] <- Y[k] + ll[I,J]*V[H]
        Y[k] <- Y[k] - r[I,J]*V[k]

        Y[1+k] <- Y[1+k] + ll[I,J]*V[1+H]
        Y[1+k] <- Y[1+k] - r[I,J]*V[1+k]

        Y[2+k] <- Y[2+k] + ll[I,J]*V[2+H]
        Y[2+k] <- Y[2+k] - r[I,J]*V[2+k]
      }
    }
    list(Y)
  })
}
#Set up
parameters <- list(N = n, ll = ll, r = r)
state <- INPUT
ND <- 80
t <- seq(0,ND,1)
# Perform the model
meta_outcome <- as.data.frame(ode(y = state, times = t, func = metapop, parms = parameters))
times <- meta_outcome[,1]
meta_outcome <- meta_outcome[,-1]
# Plot function
plot.meta <- function(meta_outcome, times){
  totalS <- matrix(0, nrow = length(times), ncol = n)
  totalI <- matrix(0, nrow = length(times), ncol = n)

  for (I in seq_len(n)){
    for (J in seq_len(n)){
      i <- I - 1
      j <- J - 1
      k <- 3*(j + i*n) + 1
      totalS[,I] <- totalS[,I] + meta_outcome[,k]
      totalI[,I] <- totalI[,I] + meta_outcome[,k+1]
    }
  }
  I.y.lim <- max(totalI)
  S.y.lim <- max(totalS)
  par(mfrow = c(2,1))
  plot(1, type="n", xlab="", ylab="", xlim=c(0, max(times)), ylim=c(0, S.y.lim), main = paste0("S, pop = ",n))
  for (i in seq(n)){
    lines(times, totalS[,i], col = i)
  }
  plot(1, type="n", xlab="", ylab="", xlim=c(0, max(times)), ylim=c(0, I.y.lim), main = "I")
  for (i in seq(n)){
    lines(times, totalI[,i], col = i)
  }
}
#Plot outcome
plot.meta(meta_outcome = meta_outcome, times = times)