-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Develop model_default_odin() for compatibility with vignettes #254
Comments
Input checking and output formatting for All the failing test are related to your slack comment about allowing vectorised inputs. All commits are in the odin-default-model branch. Below is the summary of Passing tests✅ Default odin model: basic expectations, scalar arguments Warning test
Failing tests🐛 Default model: time dependence
🐛 Default model: infection parameters as vectors
🐛 Default model: composable elements as lists
🐛 Default model: multi-parameter, multi-composables
|
epidemics_odin.Rmd is a clone of epidemics.Rmd that compares |
Nice work, thanks for putting together! Should be fine to close this issue now these have been added, once below point about potential mismatch clarified? Then can move follow up steps to future issues. A few quick questions just to make sure I'm following the changes:
|
Contact matrix normalisation code is in .prepare_population() which is called from .check_prepare_args_default() which in turn is called from model_default() and model_default_odin() respectively. I mirrored the first 122 lines of
Another potential source of the difference can be in the way odin expects its parameters to be supplied. |
I think from a user's perspective it'll compile on
Yes. My preference would be to rename this issue and keep all things model_default_odin together here. |
I revisited the tolerance check in > output[4548,]
time demography_group compartment value
<num> <char> <char> <num>
1: 303 40+ susceptible 27816495
> output_odin[4548,]
time demography_group compartment value
<num> <char> <char> <num>
1: 303 40+ susceptible 16413209 Noticed there was a discrepancy in the default R0 for the two models (1.5 vs 1.3 - also relates to issue #253 on misdescribed default in another vignette). Have pushed a fix and now this returns |
Thanks. Yep, {seir} uses odin.dust to compile odin models to dust (e.g. SIR model). But agree that as only {odin} on CRAN, makes sense to focus on this. And having run with fresh install, compilation is nice and quick (actually, seems smoother than the original
Yes please |
Any thoughts on how to fix the warning. I spent all day trying to debug it. No luck yet.
The code below (adapted from the test file test-model_default_odin.R includes everything required to replicate it. rm(list = ls())
devtools::load_all()
generate_population <- function() {
# Prepare contact matrix and demography vector
polymod <- socialmixr::polymod
contact_data <- socialmixr::contact_matrix(
polymod,
countries = "United Kingdom",
age.limits = c(0, 60),
symmetric = TRUE
)
contact_matrix <- t(contact_data$matrix)
demography_vector <- contact_data$demography$population
# make initial conditions - order is important
initial_conditions <- c(
S = 1 - 1e-6, E = 0,
I = 1e-6, R = 0, V = 0
)
initial_conditions <- rbind(
initial_conditions,
initial_conditions
)
# create a population
population(
name = "UK population",
contact_matrix = contact_matrix,
demography_vector = demography_vector,
initial_conditions = initial_conditions
)
}
uk_population <- generate_population()
data_baseline <- model_default(uk_population)
data_baseline_odin <- model_default_odin(uk_population)
all.equal(data_baseline, data_baseline_odin)
## [1] TRUE
all.equal(epidemic_size(data_baseline), epidemic_size(data_baseline_odin))
## [1] "Mean relative difference: 3.632693e-07"
single_vaccination <- vaccination(
name = "double_vaccination",
nu = matrix(1e-3, nrow = 2),
time_begin = matrix(0, nrow = 2),
time_end = matrix(100, nrow = 2)
)
data <- model_default(uk_population, vaccination = single_vaccination)
data_odin <- model_default_odin(uk_population, vaccination = single_vaccination)
all.equal(data, data_odin)
## [1] "Column 'value': Mean relative difference: 1.898998"
all.equal(epidemic_size(data), epidemic_size(data_odin))
## [1] "Mean relative difference: 0.9805965"
high_rate_vax <- vaccination(
time_begin = matrix(200, nrow(uk_population$contact_matrix)),
time_end = matrix(200 + 150, nrow(uk_population$contact_matrix)),
nu = matrix(0.01, nrow = nrow(uk_population$contact_matrix))
)
data_high_rate_vax <- model_default(
uk_population,
vaccination = high_rate_vax, time_end = 600
)
data_high_rate_vax_odin <- model_default_odin(
uk_population,
vaccination = high_rate_vax, time_end = 600
)
## Warning messages:
## 1: In lsoda(y, times, func, parms, ...) :
## an excessive amount of work (> maxsteps ) was done, but integration was not successful - increase maxsteps
## 2: In lsoda(y, times, func, parms, ...) :
## Returning early. Results are accurate, as far as they go
c(nrow(data_high_rate_vax), nrow(data_high_rate_vax_odin))
## [1] 6010 2010
rows_to_compare <- seq_len(nrow(data_high_rate_vax_odin))
all.equal(
data_high_rate_vax[rows_to_compare, ],
data_high_rate_vax_odin[rows_to_compare, ]
)
## [1] "Column 'value': Mean relative difference: 1.666696e-05"
all.equal(
epidemic_size(data_high_rate_vax[rows_to_compare, ]),
epidemic_size(data_high_rate_vax_odin[rows_to_compare, ])
)
## [1] "Numeric: lengths (2, 0) differ" I've also microbenchmark::microbenchmark(
model_default(uk_population),
model_default_odin(uk_population),
model_default(uk_population, vaccination = single_vaccination),
model_default_odin(uk_population, vaccination = single_vaccination)
)
## Unit: milliseconds
## expr min
## model_default(uk_population) 4.819167
## model_default_odin(uk_population) 2.531334
## model_default(uk_population, vaccination = single_vaccination) 4.622542
## model_default_odin(uk_population, vaccination = single_vaccination) 2.493667
## lq mean median uq max neval
## 4.944188 5.187382 5.014063 5.147542 12.064501 100
## 2.601313 3.541654 2.691938 2.832730 70.017876 100
## 4.787147 4.943179 4.842876 4.941834 8.213376 100
## 2.605500 2.850439 2.681106 2.799334 6.832918 100 |
Looks like that's happening because the underlying ODE solver has ended with a very small (~0) time step, likely as the result of a sudden change in dynamics that it's struggling to integrate – maybe from a large influx of vaccination? Strange that it doesn't seem to be an issue for the |
I spotted the problem by checking the values of # calculate vax_nu as the NUMBER of vaccinations per timestep
# rather than a fraction/rate. See issue #198 for more details.
vax_nu <- vax_nu * mod_args[["population"]][["demography_vector"]] So {odin} returns an error because we're removing susceptible at an order of magnitude too high rate, turning the ODEs into a system that can't be accurately solved. I've pushed an edit to the {odin} model that I think fixes this, i.e. swapping removal rate from |
I'm getting a test failure when I tried swapping out
|
Don't think I understand why We could try passing what the odin model expects instead of what the C++ implementation expects? |
The min is to ensure that we don't vaccinate more people than there are susceptibles remaining. Basically there are two main ways to implement vaccination: 1) vaccinate a relative % per day (i.e. |
Looks like the issue is a very small amount of overshoot in the solver because min() used (i.e. it removes a large number of vaccinated individuals from S before the solver catches up to fact S is now slightly smaller). So we get a value of Using a scaling like in issue #198 may fix this, but could introduce some solver ineffeciencies. |
In the latest commit beta <- rnorm(10, 1.3 / 7, sd = 0.01)
sigma <- rnorm(10, 0.5, sd = 0.01)
gamma <- rnorm(10, 1 / 7, sd = 0.01)
test_that("Default odin model: infection parameters as vectors", { |
Thanks! I've run through the vignettes using a version of the package with the odin model (i.e. Modelling interventions
Vaccination
Time dependence
Advanced modelling
Package vignettes
Other observations
|
I also noticed that the odin multiplicative interventions weren't consistent with the additive spec in the design principles (see issue #255) so have pushed a fix (which actually has the result of simplifying the odin code – although will still need a bit more thought for the |
We have an initial example of {odin} implementation of the overlapping interventions vignette on the
odin-default-model
branch.The next step will to add the relevant input checking and output formatting so
model_default_odin()
behaves the same asmodel_default()
(i.e. could swap out in the vignette and user wouldn't notice if both compiled models provided).The text was updated successfully, but these errors were encountered: