library(hmer)
library(deSolve)
library(ggplot2)
library(reshape2)
library(purrr)
library(tidyverse)
library(lhs)
set.seed(123)
############################# HELPER FUNCTIONS #############################
# `ode_results` provides us with the solution of the differential equations for a given
# set of parameters. This function assumes an initial population of
# 900 susceptible individuals, 100 exposed individuals, and no infectious
# or recovered individuals.
ode_results <- function(parms, end_time = 365*2) {
forcer = matrix(c(0, parms['beta1'], 100, parms['beta2'], 180, parms['beta2'], 270, parms['beta3']),
ncol = 2, byrow = TRUE)
force_func = approxfun(x = forcer[,1], y = forcer[,2], method = "linear", rule = 2)
des = function(time, state, parms) {
with(as.list(c(state, parms)), {
dS <- b*(S+E+I+R)-force_func(time)*I*S/(S+E+I+R) + omega*R - mu*S
dE <- force_func(time)*I*S/(S+E+I+R) - epsilon*E - mu*E
dI <- epsilon*E - alpha*I - gamma*I - mu*I
dR <- gamma*I - omega*R - mu*R
return(list(c(dS, dE, dI, dR)))
})
}
yini = c(S = 900, E = 100, I = 0, R = 0)
times = seq(0, end_time, by = 1)
out = deSolve::ode(yini, times, des, parms)
return(out)
}
# `get_results` acts as `ode_results`, but has the additional feature
# of allowing us to decide which outputs and times should be returned.
# For example, to obtain the number of infected and susceptible individuals
# at t=25 and t=50, we would set `times=c(25,50)` and `outputs=c('I','S')`.
get_results <- function(params, times, outputs) {
t_max <- max(times)
all_res <- ode_results(params, t_max)
actual_res <- all_res[all_res[,'time'] %in% times, c('time', outputs)]
shaped <- reshape2::melt(actual_res[,outputs])
return(setNames(shaped$value, paste0(shaped$Var2, actual_res[,'time'], sep = "")))
}
# `space_filling_design` generates a space filling design of parameter sets
space_filling_design <- function(num_points, num_params, ranges){
initial_LHS_training <- maximinLHS(num_points/2, num_params)
initial_LHS_validation <- maximinLHS(num_points/2, num_params)
initial_LHS <- rbind(initial_LHS_training, initial_LHS_validation)
initial_points <- setNames(data.frame(t(apply(initial_LHS, 1,
function(x) x*unlist(lapply(ranges, function(x) x[2]-x[1])) +
unlist(lapply(ranges, function(x) x[1]))))), names(ranges))
return(initial_points)
}