Sys.setenv(R_TESTS="")
library(testthat)
library(McMasterPandemic)
library(tools)
library(dplyr)
library(semver)
library(numDeriv)
library(lubridate)
## TODO/FIXME/BACKGROUND --------------------------------------------
## rename/repurpose this once the tmb engine is properly added
## to the package. for now refer to a particular version
## of the spec and store the C++ files in the
## appropriate directory within inst. also for now, assume that this
## test file is being run inside the directory in which it should
## live within the package structure
## (i.e. inside McMasterPandemic/tests/testthat). this should
## also work for `make pkgtest` because tests are run in the
## directory of the test file (as far as I can tell), but it could
## be fragile in other contexts? in any case, once we have
## the tmb-refactored code in the package, we will use the
## installed dlls and R-side utilities but retain the structure of
## these tests by spec version. possibly we can roll-up all up all
## spec versions with the same major version together (i.e. those
## that are backwards compatible).
## see https://canmod.net/misc/flex_specs for more on
## spec versioning.
## ------------------------------------------------------------------
inst_tmb = system.file('tmb', package = "McMasterPandemic")
test_that("spec v0.0.1 rate matrices match make_ratemat", {
set_spec_version("0.0.1", system.file('tmb', package = 'McMasterPandemic'))
options(MP_force_dgTMatrix = TRUE)
params <- read_params("ICU1.csv")
state <- McMasterPandemic::make_state(params = params)
M <- McMasterPandemic::make_ratemat(state, params, sparse = TRUE)
test_model <- (
flexmodel(params, state)
%>% add_rate("E", "Ia", ~ (alpha) * (sigma))
%>% add_rate("E", "Ip", ~ (1 - alpha) * (sigma))
%>% add_rate("Ia", "R", ~ (gamma_a))
%>% add_rate("Ip", "Im", ~ (mu) * (gamma_p))
%>% add_rate("Ip", "Is", ~ (1 - mu) * (gamma_p))
%>% add_rate("Im", "R", ~ (gamma_m))
%>% add_rate("Is", "H", ~ (1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("Is", "ICUs", ~ (1 - nonhosp_mort) * (1 - phi1) * (1 - phi2) * (gamma_s))
%>% add_rate("Is", "ICUd", ~ (1 - nonhosp_mort) * (1 - phi1) * (phi2) * (gamma_s))
%>% add_rate("Is", "D", ~ (nonhosp_mort) * (gamma_s))
%>% add_rate("ICUs", "H2", ~ (psi1))
%>% add_rate("ICUd", "D", ~ (psi2))
%>% add_rate("H2", "R", ~ (psi3))
%>% add_rate("H", "R", ~ (rho))
%>% add_rate("Is", "X", ~ (1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("S", "E", ~
(Ia) * (beta0) * (1 / N) * (Ca) +
(Ip) * (beta0) * (1 / N) * (Cp) +
(Im) * (beta0) * (1 / N) * (Cm) * (1 - iso_m) +
(Is) * (beta0) * (1 / N) * (Cs) * (1 - iso_s))
%>% update_tmb_indices()
)
dd <- tmb_fun(test_model)
tmb_sparse_ratemat <- dd$report()$ratemat
r_dense_ratemat <- as.matrix(M)
tmb_dense_ratemat <- as.matrix(tmb_sparse_ratemat)
r_sparse_ratemat <- M
dimnames(tmb_sparse_ratemat) <- dimnames(r_sparse_ratemat) <- dimnames(tmb_dense_ratemat) <- dimnames(r_dense_ratemat) <- NULL
expect_equal(
class(tmb_sparse_ratemat),
class(r_sparse_ratemat)
)
expect_equal(
tmb_sparse_ratemat@Dim,
r_sparse_ratemat@Dim
)
expect_equal(
tmb_dense_ratemat,
r_dense_ratemat
)
})
test_that("spec v0.0.2 simulations match run_sim", {
set_spec_version("0.0.2", system.file('tmb', package = 'McMasterPandemic'))
params <- read_params("ICU1.csv")
state <- McMasterPandemic::make_state(params = params)
test_model <- (
flexmodel(params, state = state)
%>% add_rate("E", "Ia", ~ (alpha) * (sigma))
%>% add_rate("E", "Ip", ~ (1 - alpha) * (sigma))
%>% add_rate("Ia", "R", ~ (gamma_a))
%>% add_rate("Ip", "Im", ~ (mu) * (gamma_p))
%>% add_rate("Ip", "Is", ~ (1 - mu) * (gamma_p))
%>% add_rate("Im", "R", ~ (gamma_m))
%>% add_rate("Is", "H", ~ (1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("Is", "ICUs", ~ (1 - nonhosp_mort) * (1 - phi1) * (1 - phi2) * (gamma_s))
%>% add_rate("Is", "ICUd", ~ (1 - nonhosp_mort) * (1 - phi1) * (phi2) * (gamma_s))
%>% add_rate("Is", "D", ~ (nonhosp_mort) * (gamma_s))
%>% add_rate("ICUs", "H2", ~ (psi1))
%>% add_rate("ICUd", "D", ~ (psi2))
%>% add_rate("H2", "R", ~ (psi3))
%>% add_rate("H", "R", ~ (rho))
%>% add_rate("Is", "X", ~ (1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("S", "E", ~
(Ia) * (beta0) * (1 / N) * (Ca) +
(Ip) * (beta0) * (1 / N) * (Cp) +
(Im) * (beta0) * (1 / N) * (Cm) * (1 - iso_m) +
(Is) * (beta0) * (1 / N) * (Cs) * (1 - iso_s))
%>% add_parallel_accumulators(c("X", "N", "P", "V"))
%>% update_tmb_indices()
)
dd <- tmb_fun(test_model)
tmb_traj <- (test_model$state
%>% c(dd$report()$concatenated_state_vector)
%>% matrix(length(state), 4, dimnames = list(names(state), 1:4))
%>% t()
%>% as.data.frame()
)
r_traj <- run_sim_range(
params = params, state = test_model$state, nt = 4,
step_args = list(do_hazard = FALSE)
)[, names(test_model$state)]
expect_equal(tmb_traj, r_traj)
})
test_that("spec v0.0.4 simulations with time varying parameters match run_sim", {
set_spec_version("0.0.4", system.file('tmb', package = 'McMasterPandemic'))
params <- read_params("ICU1.csv")
tv_dat <- data.frame(
Date = c("2021-09-15", "2021-09-20", "2021-10-05"),
Symbol = c("beta0", "beta0", "beta0"),
Value = c(0.5, 0.1, 0.05),
Type = c("rel_prev", "rel_orig", "rel_prev")
)
test_model <- (flexmodel(
params,
state = make_state(params = params),
start_date = "2021-09-09", end_date = "2021-10-09",
params_timevar = tv_dat
)
%>% add_rate("E", "Ia", ~ (alpha) * (sigma))
%>% add_rate("E", "Ip", ~ (1 - alpha) * (sigma))
%>% add_rate("Ia", "R", ~ (gamma_a))
%>% add_rate("Ip", "Im", ~ (mu) * (gamma_p))
%>% add_rate("Ip", "Is", ~ (1 - mu) * (gamma_p))
%>% add_rate("Im", "R", ~ (gamma_m))
%>% add_rate("Is", "H", ~ (1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("Is", "ICUs", ~ (1 - nonhosp_mort) * (1 - phi1) * (1 - phi2) * (gamma_s))
%>% add_rate("Is", "ICUd", ~ (1 - nonhosp_mort) * (1 - phi1) * (phi2) * (gamma_s))
%>% add_rate("Is", "D", ~ (nonhosp_mort) * (gamma_s))
%>% add_rate("ICUs", "H2", ~ (psi1))
%>% add_rate("ICUd", "D", ~ (psi2))
%>% add_rate("H2", "R", ~ (psi3))
%>% add_rate("H", "R", ~ (rho))
%>% add_rate("Is", "X", ~ (1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("S", "E", ~
(Ia) * (beta0) * (1 / N) * (Ca) +
(Ip) * (beta0) * (1 / N) * (Cp) +
(Im) * (beta0) * (1 / N) * (Cm) * (1 - iso_m) +
(Is) * (beta0) * (1 / N) * (Cs) * (1 - iso_s))
%>% add_parallel_accumulators(c("X", "N", "P", "V"))
%>% update_tmb_indices()
)
dd <- tmb_fun(test_model)
tmb_traj <- (test_model$state
%>% c(dd$report()$concatenated_state_vector)
%>% matrix(length(test_model$state), test_model$iters + 1,
dimnames = list(names(test_model$state), 1:(test_model$iters + 1))
)
%>% t()
%>% as.data.frame()
)
r_traj <- run_sim(
params = params,
state = test_model$state,
start_date = test_model$start_date,
end_date = test_model$end_date,
params_timevar = tv_dat,
condense = FALSE,
step_args = list(do_hazard = FALSE)
)[, names(test_model$state)] %>%
as.data.frame()
row.names(r_traj) <- row.names(tmb_traj) <- NULL
expect_equal(tmb_traj, r_traj)
})
test_that("spec v0.0.5 simulations with hazard steps match run_sim, and autodiff is working", {
set_spec_version("0.0.5", system.file('tmb', package = 'McMasterPandemic'))
r_tmb_comparable()
params <- read_params("ICU1.csv")
state = make_state(params = params)
tv_dat <- data.frame(
Date = c("2021-09-15", "2021-09-20", "2021-10-05"),
Symbol = c("beta0", "beta0", "beta0"),
Value = c(0.5, 0.1, 0.05),
Type = c("rel_prev", "rel_orig", "rel_prev")
)
test_model <- (flexmodel(
params,
state = make_state(params = params),
start_date = "2021-09-09", end_date = "2021-10-09",
params_timevar = tv_dat
)
%>% add_rate("E", "Ia", ~ (alpha) * (sigma))
%>% add_rate("E", "Ip", ~ (1 - alpha) * (sigma))
%>% add_rate("Ia", "R", ~ (gamma_a))
%>% add_rate("Ip", "Im", ~ (mu) * (gamma_p))
%>% add_rate("Ip", "Is", ~ (1 - mu) * (gamma_p))
%>% add_rate("Im", "R", ~ (gamma_m))
%>% add_rate("Is", "H", ~ (1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("Is", "ICUs", ~ (1 - nonhosp_mort) * (1 - phi1) * (1 - phi2) * (gamma_s))
%>% add_rate("Is", "ICUd", ~ (1 - nonhosp_mort) * (1 - phi1) * (phi2) * (gamma_s))
%>% add_rate("Is", "D", ~ (nonhosp_mort) * (gamma_s))
%>% add_rate("ICUs", "H2", ~ (psi1))
%>% add_rate("ICUd", "D", ~ (psi2))
%>% add_rate("H2", "R", ~ (psi3))
%>% add_rate("H", "R", ~ (rho))
%>% add_rate("Is", "X", ~ (1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("S", "E", ~
(Ia) * (beta0) * (1 / N) * (Ca) +
(Ip) * (beta0) * (1 / N) * (Cp) +
(Im) * (beta0) * (1 / N) * (Cm) * (1 - iso_m) +
(Is) * (beta0) * (1 / N) * (Cs) * (1 - iso_s))
%>% add_parallel_accumulators(c("X", "N", "P", "V"))
%>% update_tmb_indices()
)
dd <- tmb_fun(test_model)
tmb_traj <- (dd$report()$concatenated_state_vector
%>% matrix(length(test_model$state), test_model$iters + 1,
dimnames = list(names(test_model$state), 1:(test_model$iters + 1))
)
%>% t()
%>% as.data.frame()
)
r_traj <- run_sim(
params = params,
state = test_model$state,
start_date = test_model$start_date,
end_date = test_model$end_date,
params_timevar = tv_dat,
condense = FALSE,
step_args = list(do_hazard = TRUE)
)[, names(test_model$state)] %>%
as.data.frame()
row.names(r_traj) <- row.names(tmb_traj) <- NULL
# simulated state trajectories are equal
expect_equal(tmb_traj, r_traj)
# mock objective function is correct
expect_equal(sum(tmb_traj[31, ]), dd$fn(dd$par))
# tmb-computed gradient equals numerical gradient
## numerical differentiation settings:
## used defaults from `?grad` with one exception: d = 0.1, not 0.0001.
## i don't understand why this helps, but it allows us to take the
## tolerance from 1e-4 down to 1e-6
numerical_deriv_args <-
list(
eps = 1e-4, d = 0.1,
zero.tol = sqrt(.Machine$double.eps / 7e-7), r = 4, v = 2,
show.details = FALSE
)
numeric_gradient <- numDeriv::grad(dd$fn, dd$par,
method.args = numerical_deriv_args
)
tmb_gradient <- dd$gr(dd$par)
attributes(numeric_gradient) <- attributes(tmb_gradient) <- NULL
expect_equal(tmb_gradient, numeric_gradient,
tolerance = 1e-5
)
# use_flex flag does not change results
tmb_sim <- run_sim(
params, state = state,
start_date = "2021-09-10",
end_date = "2021-10-10",
params_timevar = tv_dat,
condense = FALSE,
step_args = list(do_hazard = TRUE),
use_flex = TRUE,
flexmodel = make_base_model(
params = params,
state = state,
start_date = "2021-09-10",
end_date = "2021-10-10",
params_timevar = tv_dat,
do_make_state = FALSE,
do_hazard = TRUE
)
)
r_sim <- run_sim(
params = params, state = state,
start_date = "2021-09-10",
end_date = "2021-10-10",
params_timevar = tv_dat,
condense = FALSE,
step_args = list(do_hazard = TRUE),
use_flex = FALSE
)
compare_sims(r_sim, tmb_sim)
})
test_that('spec v0.0.6 time-varying parameters are correctly updated on C++ side', {
set_spec_version("0.0.6", system.file('tmb', package = 'McMasterPandemic'))
params <- read_params("ICU1.csv")
state <- make_state(params = params)
M <- McMasterPandemic::make_ratemat(state, params, sparse = TRUE)
tv_dat <- data.frame(
Date = c("2021-09-15", "2021-09-20", "2021-10-05"),
Symbol = c("beta0", "beta0", "beta0"),
Value = c(0.5, 0.1, 0.05),
Type = c("rel_prev", "rel_orig", "rel_prev")
)
mm = make_base_model(
params, state,
start_date = "2021-09-10",
end_date = "2021-10-10",
params_timevar = tv_dat,
step_args = list(do_hazard = TRUE)
)
# change beta0, which is time-varying, so that
# we can check that the parameter updates are
# happening correctly in the C++ side
test_pars = params
test_pars[1] = 3
tmb_sim <- run_sim(
params = test_pars, state = state,
start_date = "2021-09-10",
end_date = "2021-10-10",
params_timevar = tv_dat,
condense = FALSE,
step_args = list(do_hazard = TRUE, flexmodel = mm),
use_flex = TRUE,
flexmodel = mm
)
r_sim <- run_sim(
params = test_pars, state = state,
start_date = "2021-09-10",
end_date = "2021-10-10",
params_timevar = tv_dat,
condense = FALSE,
step_args = list(do_hazard = TRUE),
use_flex = FALSE
)
compare_sims(r_sim, tmb_sim)
})
test_that('spec v0.0.6 that it remains ok to _not_ use time-varying parameters', {
set_spec_version("0.0.6", system.file('tmb', package = 'McMasterPandemic'))
params <- read_params("ICU1.csv")
state <- make_state(params = params)
M <- McMasterPandemic::make_ratemat(state, params, sparse = TRUE)
tmb_sim <- run_sim(
params = params, state = state,
start_date = "2021-09-10",
end_date = "2021-10-10",
condense = TRUE,
step_args = list(do_hazard = TRUE),
use_flex = TRUE,
flexmodel = make_base_model(
params = params,
state = state,
start_date = "2021-09-10",
end_date = "2021-10-10",
do_make_state = FALSE,
do_hazard = TRUE
)
)
r_sim <- run_sim(
params = params, state = state,
start_date = "2021-09-10",
end_date = "2021-10-10",
condense = TRUE,
step_args = list(do_hazard = TRUE),
use_flex = FALSE
)
compare_sims(r_sim, tmb_sim)
})
test_that('spec v0.1.1 tmb outflow can be set to match exponential simulation', {
reset_spec_version()
params <- read_params("PHAC.csv")
# modify parameters and state for eigenvector calculation ('by hand')
state <- make_state(params = params)[1:12]
params[['N']] = 1
params[['E0']] = 1e-5
state[] = 0
state[['S']] = 1 - params[['E0']]
state[['E']] = params[['E0']]
iters = 100
r_sim = run_sim_range(params, state, nt = iters,
step_args = list(do_hazard = FALSE,
do_exponential = TRUE))
start_date = ymd(20000101)
model <- (flexmodel(params, state,
start_date = start_date,
end_date = start_date + days(iters - 1),
do_hazard = FALSE,
do_make_state = FALSE)
%>% add_rate("E", "Ia", ~ (alpha) * (sigma))
%>% add_rate("E", "Ip", ~ (1 - alpha) * (sigma))
%>% add_rate("Ia", "R", ~ (gamma_a))
%>% add_rate("Ip", "Im", ~ (mu) * (gamma_p))
%>% add_rate("Ip", "Is", ~ (1 - mu) * (gamma_p))
%>% add_rate("Im", "R", ~ (gamma_m))
%>% add_rate("Is", "H", ~
(1 - nonhosp_mort) * (phi1) * (gamma_s))
%>% add_rate("Is", "ICUs", ~
(1 - nonhosp_mort) * (1 - phi1) * (1 - phi2) * (gamma_s))
%>% add_rate("Is", "ICUd", ~
(1 - nonhosp_mort) * (1 - phi1) * (phi2) * (gamma_s))
%>% add_rate("Is", "D", ~ (nonhosp_mort) * (gamma_s))
%>% add_rate("ICUs", "H2", ~ (psi1))
%>% add_rate("ICUd", "D", ~ (psi2))
%>% add_rate("H2", "R", ~ (psi3))
%>% add_rate("H", "R", ~ (rho))
%>% add_rate("S", "E", ~
(Ia) * (beta0) * (1 / N) * (Ca) +
(Ip) * (beta0) * (1 / N) * (Cp) +
(Im) * (beta0) * (1 / N) * (Cm) * (1 - iso_m) +
(Is) * (beta0) * (1 / N) * (Cs) * (1 - iso_s))
%>% add_outflow("^S$", "^S$")
%>% add_outflow("^(E|I|H|ICU|D|R)", "^(S|E|I|H|ICU|D|R)")
%>% update_tmb_indices
)
# trim off S, D, & R -- for eigenvector calculation 'by hand'
r_final_state = unlist(r_sim[100, names(state)])[2:10]
tmb_final_state = c(final_state_vector(model)[2:10])
norm_vec = McMasterPandemic:::norm_vec
expect_equal(norm_vec(r_final_state), norm_vec(tmb_final_state))
})
test_that("flex models made with null state can be used", {
reset_spec_version()
r_tmb_comparable()
params = read_params("PHAC.csv")
model = make_base_model(
params = params,
start_date = "1900-01-01",
end_date = "1900-02-01")
tmb_sims = run_sim(
params = params,
start_date = model$start_date,
end_date = model$end_date,
flexmodel = model
)
r_sims = run_sim(
params = params,
start_date = model$start_date,
end_date = model$end_date
)
compare_sims(r_sims, tmb_sims, na_is_zero = TRUE)
})
test_that("simple sir models produce correct simulations", {
S0 = 20000
I0 = 100
R0 = 0
sir_model = (
flexmodel(
params = c(
N = S0 + I0,
gamma = 0.06, # per-infected recovery rate
beta = 0.15 # per-contact transmission rate
),
state = c(S = S0, I = I0, R = R0),
start_date = "2000-01-01",
end_date = "2000-05-01",
do_hazard = FALSE,
do_make_state = FALSE
)
%>% add_rate("S", "I", ~ (1/N) * (beta) * (I))
%>% add_rate("I", "R", ~ (gamma))
%>% add_outflow(".+", ".+")
%>% update_tmb_indices
)
i <- 1
lenSim <- 122
S <- E <- I <- R <- D <- numeric(lenSim)
S[1] <- 20000
I[1] <- 100
N <- S[1] + I[1]
R[1] <- 0
gamma <- 0.06
beta<- 0.15
while (i <= lenSim - 1){
S[i+1] <- S[i] - (beta) * (S[i]) * (I[i])/N
I[i+1] <- I[i] - gamma * I[i] + (beta) * (S[i]) * (I[i])/N
R[i+1] <- R[i] + gamma * I[i]
i <- i + 1
}
sim <- data.frame("S" = S, "I" = I, "R" = R, "t" = 1:lenSim)
macpan_sim <- simulate_state_vector(sir_model)
expect_equal(macpan_sim$S, sim$S)
expect_equal(macpan_sim$I, sim$I)
expect_equal(macpan_sim$R, sim$R)
})
test_that("one may specify different rates for the same flow", {
reset_spec_version()
tmb_mode()
options(MP_warn_repeated_rates = TRUE)
model_rep = model_one = (flexmodel(
params = c(alpha = 0.1),
state = c(A = 100, B = 0),
start_date = "2000-01-01",
end_date = "2000-02-01",
do_hazard = FALSE, do_make_state = FALSE
)
%>% add_rate("A", "B", ~ (alpha))
%>% add_outflow()
)
expect_warning(model_rep <- (model_rep
%>% add_rate("A", "B", ~ (alpha))
%>% update_tmb_indices()
))
model_one$params = c(alpha = 0.2)
model_one = update_tmb_indices(model_one)
expect_equal(
simulate_state_vector(model_one),
simulate_state_vector(model_rep))
})
test_that("an informative error is returned if variables are missing", {
reset_spec_version()
tmb_mode()
tv = data.frame(
Date = "2000-02-01",
Symbol = "a",
Value = 1,
Type = 'abs'
)
msg = "the following variables were used but not found in the model"
msg2 = "regular expressions did not match any state variables or parameters to sum."
expect_error(
flexmodel(
params = c(b = 1),
state = c(X = 0),
start_date = "2000-01-01",
end_date = "2000-03-01",
params_timevar = tv
),
regexp = msg
)
expect_error(
(
flexmodel(
params = c(a = 1),
state = c(X = 0, Y = 0),
start_date = "2000-01-01",
end_date = "2000-01-01"
)
%>% add_rate("X", "Y", ~ (b) + (c))
),
regexp = msg
)
expect_error(
(
flexmodel(
params = c(a = 1),
state = c(X = 0, Y = 0),
start_date = "2000-01-01",
end_date = "2000-01-01"
)
%>% add_state_param_sum("Zsum", "Z")
),
regexp = msg2
)
})
test_that("invalid state and parameter sum specification returns informative error msg", {
reset_spec_version()
tmb_mode()
msg1 = "sums cannot have the same name as state variables or parameters"
msg2 = "sum_name must be character-valued"
msg3 = "can only specify one sum at a time"
expect_error(
(
flexmodel(
params = c(a = 1),
state = c(X = 0, Y = 0),
start_date = "2000-01-01",
end_date = "2000-01-01"
)
%>% add_state_param_sum("X", "X")
),
regexp = msg1
)
expect_error(
(
flexmodel(
params = c(a = 1),
state = c(X = 0, Y = 0),
start_date = "2000-01-01",
end_date = "2000-01-01"
)
%>% add_state_param_sum(1, "X")
),
regexp = msg2
)
expect_error(
(
flexmodel(
params = c(a = 1),
state = c(X = 0, Y = 0),
start_date = "2000-01-01",
end_date = "2000-01-01"
)
%>% add_state_param_sum(c("X", "Y"), "X")
),
regexp = msg3
)
})
test_that("informative error is thrown if no rates are specified", {
reset_spec_version()
tmb_mode()
msg = "no rates have been added to this model"
expect_error(
(
flexmodel(
params = c(a = 1),
state = c(X = 0),
start_date = "2000-01-01",
end_date = "2000-01-02"
)
%>% update_tmb_indices()
),
regexp = msg
)
})
test_that("informative error is thrown if no rates are specified", {
reset_spec_version()
tmb_mode()
op1 = options(MP_auto_outflow = FALSE)
op2 = options(MP_warn_no_outflow = TRUE)
msg = "model does not contain any outflow"
expect_warning(
(
flexmodel(
params = c(a = 1),
state = c(X = 10, Y = 0),
start_date = "2000-01-01",
end_date = "2000-01-02"
)
%>% add_rate("X", "Y", ~ (a))
%>% update_tmb_indices
),
regexp = msg
)
options(op1)
options(op2)
})
test_that("start_date <= end_date in flex models", {
expect_error(
flexmodel(
params = read_params("ICU1.csv"),
start_date = "2000-01-02",
end_date = "2000-01-01"
),
regexp = "start_date must be less than or equal to end_date"
)
})
test_that("an error is thrown when params is not params_pansim and state is not provided", {
expect_error(
flexmodel(
params = c(S = 0),
start_date = "2000-01-01",
end_date = "2000-01-02"
),
regexp = "an initial state vector is required, because"
)
})
test_that("pre-defined factors give the same answer as defining the rate with raw factors", {
mm = flexmodel(
params = c(a = 0.5, b = 0.25, c = 0.1),
state = c(X = 1, Y = 2),
start_date = "2000-01-01",
end_date = "2000-02-05",
do_make_state = FALSE
)
mm1 = (mm
%>% add_rate("X", "Y", ~ (a) * (c) * (X) + (c) * (b) * (Y))
%>% add_outflow %>% update_tmb_indices
)
mm2 = (mm
%>% add_factr("alpha", ~ (a) * (X) + (b) * (Y))
%>% add_rate("X", "Y", ~ (alpha) * (c))
%>% add_outflow %>% update_tmb_indices
)
expect_equal(
simulate_state_vector(mm1),
simulate_state_vector(mm2)
)
mm = flexmodel(
params = c(beta = 0.5, N = 100),
state = c(S = 99, I = 1),
start_date = "2000-01-01",
end_date = "2000-01-05",
do_make_state = FALSE
)
mm1 = (mm
%>% add_factr("foi", ~ (beta) * (1/N) * (I))
%>% add_rate("S", "I", ~ (foi))
%>% add_outflow
%>% update_tmb_indices
)
mm2 = (mm
%>% add_rate("S", "I", ~ (beta) * (1/N) * (I))
%>% add_outflow
%>% update_tmb_indices
)
expect_equal(
simulate_state_vector(mm1),
simulate_state_vector(mm2)
)
})
test_that("vector-valued pre-defined factors give consistent results", {
strains = c("wild", "variant")
state = c(
S = 20000,
I_wild = 49, I_variant = 1,
R_wild = 0, R_variant = 0
)
two_strain_model =
flexmodel(
params = c(
gamma = 0.06,
beta_wild = 0.15,
beta_variant = 0.25,
N = sum(state)
),
state = state,
start_date = "2000-01-01",
end_date = "2000-01-02",
do_hazard = TRUE,
do_make_state = FALSE
)
two_strains_factr = (two_strain_model
%>% vec_factr(
"foi" %_% strains,
vec("beta" %_% strains) * struc("1/N") * vec("I" %_% strains))
%>% vec_rate("S", "I" %_% strains, vec("foi" %_% strains))
%>% rep_rate("I", "R", ~ (gamma))
%>% add_outflow()
%>% update_tmb_indices
)
two_strains_no_factr = (two_strain_model
%>% vec_rate(
"S",
"I" %_% strains,
vec("beta" %_% strains) * struc("1/N") * vec("I" %_% strains)
)
%>% rep_rate("I", "R", ~ (gamma))
%>% add_outflow()
%>% update_tmb_indices
)
sims_factrs = simulate_state_vector(two_strains_factr)
sims_no_factrs = simulate_state_vector(two_strains_no_factr)
expect_equal(
sims_factrs,
sims_no_factrs
)
})
test_that("sim_report expressions give correct results", {
strains = c("wild", "variant")
state = c(
S = 20000,
I_wild = 49, I_variant = 1,
R_wild = 0, R_variant = 0
)
two_strain_model =
flexmodel(
params = c(
gamma = 0.06,
beta_wild = 0.15,
beta_variant = 0.25,
N = sum(state),
c_prop = 1e-1,
c_delay_cv = 2.5e-1,
c_delay_mean = 1.1
),
state = state,
start_date = "2000-01-01",
end_date = "2000-01-02",
do_hazard = TRUE,
do_make_state = FALSE
)
model = (two_strain_model
%>% vec_factr(
"foi" %_% strains,
vec("beta" %_% strains) * struc("1/N") * vec("I" %_% strains)
)
%>% vec_rate("S", "I" %_% strains, vec("foi" %_% strains))
%>% rep_rate("I", "R", ~ (gamma))
%>% add_sim_report_expr('report', ~ (I_wild) + (I_variant))
%>% add_sim_report_expr('recov', ~ (S) * (S_to_I_wild) + (S) * (S_to_I_variant))
%>% add_lag_diff("^report$")
%>% add_conv("^recov$")
)
simulation_history(model)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.