context("DCM Standard Models") # SI Models --------------------------------------------------------------- test_that("SI, 1G, CL: 1 run", { param <- param.dcm(inf.prob = 0.2, act.rate = 0.25) init <- init.dcm(s.num = 500, i.num = 1) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) test_that("SI, 1G, CL: varying inf.prob", { param <- param.dcm(inf.prob = seq(0.1, 0.9, 0.1), act.rate = 0.25) init <- init.dcm(s.num = 500, i.num = 1) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) test_that("SI, 1G, CL: varying inf.prob and act.rate", { param <- param.dcm(inf.prob = seq(0.1, 0.8, 0.1), act.rate = seq(0.25, 2, 0.25)) init <- init.dcm(s.num = 500, i.num = 1) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) test_that("SI, 1G, OP: varying inf.prob", { param <- param.dcm(inf.prob = seq(0.1, 0.5, 0.05), act.rate = 0.25, a.rate = 1 / 100, ds.rate = 1 / 100, di.rate = 1 / 90) init <- init.dcm(s.num = 500, i.num = 1) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) test_that("SI, 2G, OP: varying inf.prob", { param <- param.dcm(inf.prob = seq(0.1, 0.5, 0.05), act.rate = 0.25, inf.prob.g2 = 0.1, balance = "g1", a.rate = 1 / 100, a.rate.g2 = NA, ds.rate = 1 / 100, ds.rate.g2 = 1 / 100, di.rate = 1 / 90, di.rate.g2 = 1 / 90) init <- init.dcm(s.num = 500, i.num = 1, s.num.g2 = 500, i.num.g2 = 0) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) # SIR Models -------------------------------------------------------------- test_that("SIR, 1G, CL: varying inf.prob", { param <- param.dcm(inf.prob = seq(0.1, 0.5, 0.05), act.rate = 0.25, rec.rate = 1 / 50) init <- init.dcm(s.num = 500, i.num = 1, r.num = 0) control <- control.dcm(type = "SIR", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) test_that("SIR, 1G, OP: 1 run", { param <- param.dcm(inf.prob = 0.2, act.rate = 2, rec.rate = 1 / 50, a.rate = 1 / 100, ds.rate = 1 / 100, di.rate = 1 / 90, dr.rate = 1 / 100) init <- init.dcm(s.num = 500, i.num = 1, r.num = 0) control <- control.dcm(type = "SIR", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) test_that("SIR, 2G, OP: varying inf.prob", { param <- param.dcm(inf.prob = seq(0.1, 0.5, 0.05), inf.prob.g2 = 0.1, act.rate = 1, balance = "g1", rec.rate = 1 / 50, rec.rate.g2 = 1 / 50, a.rate = 1 / 100, a.rate.g2 = NA, ds.rate = 1 / 100, ds.rate.g2 = 1 / 100, di.rate = 1 / 90, di.rate.g2 = 1 / 90, dr.rate = 1 / 100, dr.rate.g2 = 1 / 100) init <- init.dcm(s.num = 500, i.num = 1, r.num = 0, s.num.g2 = 500, i.num.g2 = 1, r.num.g2 = 0) control <- control.dcm(type = "SIR", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) # SIS Models -------------------------------------------------------------- test_that("SIS, 1G, CL: 1 run", { param <- param.dcm(inf.prob = 0.2, act.rate = 0.25, rec.rate = 1 / 50) init <- init.dcm(s.num = 500, i.num = 1) control <- control.dcm(type = "SIS", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) test_that("SIS, 2G, CL: varying inf.prob", { param <- param.dcm(inf.prob = seq(0.1, 0.9, 0.1), act.rate = 0.25, inf.prob.g2 = 0.1, balance = "g1", rec.rate = 1 / 100, rec.rate.g2 = 1 / 100) init <- init.dcm(s.num = 500, i.num = 1, s.num.g2 = 500, i.num.g2 = 0) control <- control.dcm(type = "SIS", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) test_that("SIS, 1G, OP: 1 run", { param <- param.dcm(inf.prob = 0.2, act.rate = 0.5, rec.rate = 1 / 50, a.rate = 1 / 100, ds.rate = 1 / 100, di.rate = 1 / 90) init <- init.dcm(s.num = 500, i.num = 1) control <- control.dcm(type = "SIS", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") }) # Check flows ------------------------------------------------------------- test_that("si.flow correct for closed SI model, lsoda method", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4) init <- init.dcm(s.num = 28650, i.num = 100) control <- control.dcm(type = "SI", nsteps = 2) mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(df$i.num[2], df$i.num[1] + df$si.flow[1]) expect_equal(df$s.num[2], df$s.num[1] - df$si.flow[1]) expect_equal(df$si.flow[1], 96.72141, tol = 0.0001) }) test_that("si.flow correct for open SI model, lsoda method", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4, a.rate = 0.02, ds.rate = 0.01, di.rate = 0.01) init <- init.dcm(s.num = 28650, i.num = 100) control <- control.dcm(type = "SI", nsteps = 2) mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(df$num[2], df$num[1] + df$a.flow[1] - df$ds.flow[1] - df$di.flow[1]) expect_equal(df$i.num[2], df$i.num[1] + df$si.flow[1] - df$di.flow[1]) expect_equal(df$si.flow[1], 96.19311, tol = 0.0001) }) test_that("si.flow correct for closed SI model, Euler method", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4) init <- init.dcm(s.num = 28650, i.num = 100) control <- control.dcm(type = "SI", nsteps = 2, odemethod = "euler") mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(df$i.num[2], df$i.num[1] + df$si.flow[1]) expect_equal(df$s.num[2], df$s.num[1] - df$si.flow[1]) expect_equal(df$si.flow[1], 67.76348, tol = 0.0001) }) test_that("si.flow correct for closed SI model, Euler method", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4, a.rate = 0.02, ds.rate = 0.01, di.rate = 0.01) init <- init.dcm(s.num = 28650, i.num = 100) control <- control.dcm(type = "SI", nsteps = 2, odemethod = "euler") mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(df$num[2], df$num[1] + df$a.flow[1] - df$ds.flow[1] - df$di.flow[1]) expect_equal(df$i.num[2], df$i.num[1] + df$si.flow[1] - df$di.flow[1]) expect_equal(df$si.flow[1], 67.76348, tol = 0.0001) }) # Check dt fractional ----------------------------------------------------- test_that("fractional dt returns, RK4 method", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4) init <- init.dcm(s.num = 28650, i.num = 100) control <- control.dcm(type = "SI", nsteps = 10, dt = 0.5) mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(df$time, seq(1, 10, 0.5)) }) test_that("fractional dt returns, Euler method", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4) init <- init.dcm(s.num = 28650, i.num = 100) control <- control.dcm(type = "SI", nsteps = 10, dt = 0.5, odemethod = "euler") mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(df$time, seq(1, 10, 0.5)) }) test_that("test extension model, NA output", { eMod2 <- function(t, t0, parms) { with(as.list(c(t0, parms)), { # Total population size num <- s.num + i.num + r.num # Define lambdas lambda.direct <- beta.direct * i.num lambda.envirn <- beta.envirn * e.num # Differential equations dS <- -lambda.direct*s.num - lambda.envirn*s.num + mu*num - mu*s.num dI <- lambda.direct*s.num + lambda.envirn*s.num - mu*i.num - gamma*i.num dR <- gamma*i.num - mu*r.num dE <- xi*i.num - delta*e.num # Outputs list(c(dS, dI, dR, dE, si.direct.flow = lambda.direct*s.num, si.envirn.flow = lambda.envirn*s.num)) }) } # Parameterize the model with the following parameters this time param <- param.dcm(beta.direct = 0.0001, beta.envirn = 0.00001, mu = 0.01, gamma = 0.2, xi = 2, delta = 0.5) # Use similar initial conditions and control settings as the first model, but # make sure to update the new.mod function name! init <- init.dcm(s.num = 10000, i.num = 1, r.num = 0, e.num = 0, si.direct.flow = 0, si.envirn.flow = 0) control <- control.dcm(nsteps = 10, dt = 0.1, new.mod = eMod2) # Run the simulation and examine the output as a data frame sim <- dcm(param, init, control) expect_s3_class(sim, "dcm") df <- as.data.frame(sim) expect_true(all(!is.na(df))) }) # DCM interventions ------------------------------------------------------- test_that("DCM interventions, SI model", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4, inter.eff = 1) expect_equal(param$inter.start, 1) param <- param.dcm(inf.prob = 0.2, act.rate = 3.4, inter.eff = 1, inter.start = 5) expect_equal(param$inter.start, 5) init <- init.dcm(s.num = 28650, i.num = 100) control <- control.dcm(type = "SI", nsteps = 10) mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(sum(df$si.flow[5:10], na.rm = TRUE), 0, tol = 0.01) expect_equal(max(df$i.num[5:10]) - min(df$i.num[5:10]), 0, tol = 0.01) expect_equal(max(df$s.num[5:10]) - min(df$s.num[5:10]), 0, tol = 0.01) }) test_that("DCM interventions, SIS model", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4, rec.rate = 0.1, inter.eff = 1, inter.start = 5) expect_equal(param$inter.start, 5) init <- init.dcm(s.num = 28650, i.num = 100) control <- control.dcm(type = "SIS", nsteps = 10) mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(sum(df$si.flow[5:10], na.rm = TRUE), 0, tol = 0.01) expect_equal(df$s.num[10], 28155.07472, tol = 0.0001) expect_equal(df$i.num[10], 594.92528, tol = 0.0001) }) test_that("DCM interventions, SIR model", { param <- param.dcm(inf.prob = 0.2, act.rate = 3.4, rec.rate = 0.1, inter.eff = 1, inter.start = 5) expect_equal(param$inter.start, 5) init <- init.dcm(s.num = 28650, i.num = 100, r.num = 0) control <- control.dcm(type = "SIR", nsteps = 10) mod <- dcm(param, init, control) df <- as.data.frame(mod) expect_equal(sum(df$si.flow[5:10], na.rm = TRUE), 0, tol = 0.01) expect_equal(max(df$s.num[5:10]) - min(df$s.num[5:10]), 0, tol = 0.01) expect_equal(df$i.num[10], 592.14131, tol = 0.5) }) # param, init, control ------------------------------------------------------ test_that("control checks", { control <- control.dcm(type = "SI", nsteps = 10, foo = "boo") expect_true(control$foo == "boo") expect_error(control.dcm(type = "SI"), "Specify nsteps") expect_error(control.dcm(type = "SEIR", nsteps = 10), "Specify type as") }) # dcm extension check ----------------------------------------------------- context("DCM Delayed Differential Equation Models") test_that("Delayed differntial equation models function", { lagsi <- function(t, t0, parms) { with(as.list(c(t0, parms)), { num <- s.num + i.num if (t < 2) { i.num.foi <- 0 } else { i.num.foi <- lagvalue(t - 1, 2) } lambda <- inf.prob * act.rate * i.num.foi / num dS <- -lambda * s.num dI <- lambda * s.num list(c(dS, dI), num = num, si.flow = lambda * s.num, i.num.foi = i.num.foi) }) } param <- param.dcm(inf.prob = 0.5, act.rate = 0.25) init <- init.dcm(s.num = 100, i.num = 10) control <- control.dcm(nsteps = 25, new.mod = lagsi, dede = TRUE) mod <- dcm(param, init, control) expect_is(mod, "dcm") expect_true(mod$control$dede) }) context("New DCM Models") test_that("New DCMs Example 1", { ## SI function intSI <- function(t, t0, parms) { with(as.list(c(t0, parms)), { ## Dynamic Calculations # Population size num <- s.num + i.num # Intervention start time: if time > start, # then multiply lambda by relative hazard if (t < start.time) { lambda <- inf.prob * act.rate * i.num / num } else { lambda <- (inf.prob * act.rate * i.num / num) * rel.haz } ## Flows si.flow <- lambda * s.num ## Differential Equations dS <- -lambda * s.num dI <- lambda * s.num ## Output list(c(dS, dI, si.flow), num = num) }) } init <- init.dcm(s.num = 999, i.num = 1, si.flow = 0) control <- control.dcm(nsteps = 250, dt = 1, new.mod = intSI, verbose = FALSE) param1 <- param.dcm(inf.prob = 0.5, act.rate = 0.1, start.time = seq(100, 200, 100), rel.haz = 1) param05 <- param.dcm(inf.prob = 0.5, act.rate = 0.1, start.time = seq(100, 200, 100), rel.haz = 0.5) mod1 <- dcm(param1, init, control) mod2 <- dcm(param05, init, control) expect_is(mod1, "dcm") expect_is(mod2, "dcm") }) test_that("New DCMs Example 2", { ## Q Mod Function Qmod <- function(t, t0, parms) { with(as.list(c(t0, parms)), { ## Dynamic Calculations ## # Popsize and prevalence h.num <- sh.num + ih.num l.num <- sl.num + il.num num <- h.num + l.num prev <- (ih.num + il.num) / num # Contact rates for high specified as a function of # mean and low rates c.high <- (c.mean * num - c.low * l.num) / h.num # Mixing matrix calculations based on variable Q statistic g.hh <- ((c.high * h.num) + (Q * c.low * l.num)) / ((c.high * h.num) + (c.low * l.num)) g.lh <- 1 - g.hh g.hl <- (1 - g.hh) * ((c.high * h.num) / (c.low * l.num)) g.ll <- 1 - g.hl # Probability that contact is infected based on mixing probabilities p.high <- (g.hh * ih.num / h.num) + (g.lh * il.num / l.num) p.low <- (g.ll * il.num / l.num) + (g.hl * ih.num / h.num) # Force of infection for high and low groups lambda.high <- rho * c.high * p.high lambda.low <- rho * c.low * p.low ## Differential Equations ## dS.high <- -lambda.high * sh.num + nu * ih.num dI.high <- lambda.high * sh.num - nu * ih.num dS.low <- -lambda.low * sl.num + nu * il.num dI.low <- lambda.low * sl.num - nu * il.num ## Output ## list(c(dS.high, dI.high, dS.low, dI.low), num = num, prev = prev) }) } param <- param.dcm(c.mean = 2, c.low = 1.4, rho = 0.75, nu = 6, Q = c(-0.45, 0.5, 1)) init <- init.dcm(sh.num = 2e7 * 0.02, ih.num = 1, sl.num = 2e7 * 0.98, il.num = 1) control <- control.dcm(nsteps = 6, dt = 0.02, new.mod = Qmod, verbose = FALSE) mod <- dcm(param, init, control) expect_is(mod, "dcm") }) test_that("DCM inital conditions ordering correct", { SEIR <- function(t, t0, parms) { with(as.list(c(t0, parms)), { num <- s.num + e.num + i.num + r.num lambda <- inf.prob * act.rate * i.num / num se.flow <- lambda * s.num ei.flow <- sx.rate * e.num ir.flow <- rec.rate * i.num dS <- -lambda * s.num dE <- lambda * s.num - sx.rate * e.num dI <- sx.rate * e.num - rec.rate * i.num dR <- rec.rate * i.num list(c(dS, dE, dI, dR, se.flow, ei.flow, ir.flow), num = num) }) } init <- init.dcm(s.num = 980, e.num = 10, i.num = 10, r.num = 0, se.flow = 0, ei.flow = 0, ir.flow = 0) expect_identical(names(init), c("s.num", "e.num", "i.num", "r.num", "se.flow", "ei.flow", "ir.flow")) param <- param.dcm(inf.prob = 0.2, act.rate = 0.5, sx.rate = 0.1, rec.rate = 0.05) control <- control.dcm(nsteps = 10, dt = 1, new.mod = SEIR) mod <- dcm(param, init, control) expect_is(mod, "dcm") expect_identical(names(as.data.frame(mod))[3], "e.num") }) test_that("Non-sensitivity parameter vector", { ## SI function intSI <- function(t, t0, parms) { with(as.list(c(t0, parms)), { ## Dynamic Calculations # Population size num <- s.num + i.num if (t < start.time) { lambda <- inf.prob[1] * act.rate * i.num / num } else { lambda <- inf.prob[2] * act.rate * i.num / num } ## Flows si.flow <- lambda * s.num ## Differential Equations dS <- -si.flow dI <- si.flow ## Output list(c(dS, dI, si.flow), num = num) }) } param <- param.dcm(inf.prob = c(0.5, 0.05), act.rate = 0.1, start.time = 100) init <- init.dcm(s.num = 999, i.num = 1, si.flow = 0) control <- control.dcm(nsteps = 250, new.mod = intSI, sens.param = FALSE) mod <- dcm(param, init, control) expect_is(mod, "dcm") expect_true(any(!is.na(as.data.frame(mod)))) }) # Init sensitivity analysis ------------------------------------------------ test_that("SI, 1G, CL: varying i.num in init", { param <- param.dcm(inf.prob = 0.2, act.rate = 0.25) init <- init.dcm(s.num = 500, i.num = c(1, 5, 10)) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") expect_equal(x$control$nruns, 3) expect_equal(x$epi$i.num[1, 1], 1) expect_equal(x$epi$i.num[1, 2], 5) expect_equal(x$epi$i.num[1, 3], 10) }) test_that("SIR, 1G, CL: varying init and param together", { param <- param.dcm(inf.prob = c(0.1, 0.2, 0.3), act.rate = 0.25, rec.rate = 1 / 50) init <- init.dcm(s.num = c(500, 400, 300), i.num = c(1, 5, 10), r.num = 0) control <- control.dcm(type = "SIR", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") expect_equal(x$control$nruns, 3) expect_equal(x$epi$s.num[1, 1], 500) expect_equal(x$epi$s.num[1, 3], 300) }) test_that("DCM init sensitivity: mismatched init vector lengths error", { param <- param.dcm(inf.prob = 0.2, act.rate = 0.25) init <- init.dcm(s.num = c(500, 400), i.num = c(1, 5, 10)) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) expect_error(dcm(param, init, control), "same length") }) test_that("DCM init sensitivity: mismatched param and init vector lengths error", { param <- param.dcm(inf.prob = c(0.1, 0.2), act.rate = 0.25) init <- init.dcm(s.num = 500, i.num = c(1, 5, 10)) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) expect_error(dcm(param, init, control), "same length") }) test_that("DCM init sensitivity: as.data.frame works", { param <- param.dcm(inf.prob = 0.2, act.rate = 0.25) init <- init.dcm(s.num = 500, i.num = c(1, 5, 10)) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) df <- as.data.frame(x) expect_true("run" %in% names(df)) expect_equal(length(unique(df$run)), 3) }) test_that("DCM init sensitivity: custom model with varying init", { my_mod <- function(t, t0, parms) { with(as.list(c(t0, parms)), { num <- s.num + i.num lambda <- inf.prob * act.rate * i.num / num dS <- -lambda * s.num dI <- lambda * s.num list(c(dS, dI)) }) } param <- param.dcm(inf.prob = 0.2, act.rate = 0.25) init <- init.dcm(s.num = 500, i.num = c(1, 5, 10)) control <- control.dcm(nsteps = 10, new.mod = my_mod, verbose = FALSE) x <- dcm(param, init, control) expect_is(x, "dcm") expect_equal(x$control$nruns, 3) }) test_that("DCM init sensitivity: print method shows init", { param <- param.dcm(inf.prob = 0.2, act.rate = 0.25) init <- init.dcm(s.num = 500, i.num = c(1, 5, 10)) control <- control.dcm(type = "SI", nsteps = 10, verbose = FALSE) x <- dcm(param, init, control) out <- capture.output(print(x)) expect_true(any(grepl("Initial Conditions", out))) expect_true(any(grepl("i.num", out))) })