Syncs the C++ core with epiworld 0.19.0 (commit c340f87).
The new generic clone_epi() creates an independent copy of an
epiworld_tool, epiworld_virus, or epiworld_model (the assignment
operator only copies the pointer). Copies keep their C++ type and settings,
so, e.g., cloning a model's vaccine with clone_epi(get_tool(model, 0))
gives another all-or-nothing vaccine with a different efficacy or
distribution, which tool() cannot create. Once added to a model, copies of
tools and viruses are recorded as new tools and viruses (with their own id
and, for viruses, lineage).
clone_model() is deprecated in favor of clone_epi().
Tools can now target specific viruses. New functions add_target_tool(),
set_targets_tool(), get_targets_tool() and clear_targets_tool()
restrict all of a tool's effects to the given viruses (e.g., a vaccine that
only protects against measles), and get_lineage_virus() returns the id
they use. Targets match a virus lineage, so a tool targeting a virus also
acts on its mutations. By default a tool still acts on every virus, so
existing models give the same results. See ?"tool-targets".
Exposed agents no longer transmit in ModelSEIR() and ModelSEIRD(). The
susceptible update of these network models took every neighbor carrying the
virus as a source, Exposed ones included, unlike the other SEIR models
(ModelSEIRCONN() and the mixing models) and the model documentation. Epidemics
from these two models now start more slowly, and results for a given seed
change.
load_agents_entities_ties() ties now apply in every run. Before, they were
applied in the first run only, so every replicate after the first in
run_multiple() (and any second run()) ran without them.
add_virus() now works on ModelSIRMixing(), ModelSEIRMixing(), and
ModelSEIRMixingQuarantine(). Adding a virus to these models failed with
The virus "..." has no -init- state, because only the other canonical
models set the states of the virus being added.
The model builder examples now exclude the states whose agents must not
infect others from the susceptible update function. The SIR example (vignette
and ?model_builder) excluded none, so recovered agents, who keep the virus,
kept transmitting (ever infected by day 30: 3,709 against 1,303 for
ModelSIR(), in 10,000 agents). The SEIRD example excluded Recovered and
Deceased but not Exposed (exclude = c(3L, 4L)); it now uses
c(1L, 3L, 4L). The model builder test uses c(1L, 3L).
run_multiple() now runs every simulation when OpenMP provides fewer
threads than nthreads asks for (e.g., because of OMP_THREAD_LIMIT,
OMP_DYNAMIC, or a call from inside another parallel region). Previously,
the simulations assigned to the missing threads were silently skipped,
although they were still counted. Results with the full set of threads are
unchanged.
Syncs the C++ core with epiworld 0.18.0.
ModelSIRMixing(), ModelSEIRMixing() and ModelSEIRMixingQuarantine()
no longer scan the whole population every day to find infected agents, so
they are faster on large populations. Seeded results are unchanged.Syncs the C++ core with epiworld 0.17.1.
set_transmission_mode(), get_transmission_mode(),
get_last_transmission_mode() and get_transmission_kappa() control how
network models compute transmission each day. "push" has each infected
agent add its infection odds to its susceptible neighbors, "pull" has
each susceptible agent look at its infected neighbors, and "auto" (the
default) picks the cheaper one each day. Both give the same distribution of
infections but draw different random numbers, so "pull" reproduces the
runs of epiworldR 0.15 and earlier. See ?"transmission-mode".The "auto" transmission mode picks the cheaper step more reliably around
the peak of large outbreaks on heterogeneous networks, where it used to
pull although pushing was cheaper. Its threshold kappa now defaults to
0.5 (was 0.25). Seeded results of network models can change, since a
different day-by-day choice draws different random numbers; the
distribution of outcomes is the same.
Pulling is slightly faster (about 5% on small-world networks).
system.file("extdata", "geopops", package = "epiworldR") is gone). The
data now lives next to the article in the GitHub repository, under
vignettes/articles/geopops. This keeps the package within CRAN's size
limit.man/figures. Both
reduce the package size.Syncs the C++ core with epiworld 0.17.0.
bubbles() gains a ties argument that controls what being in a bubble
together does to the contact network. "existing", the default, keeps the
previous behaviour: the bubble is only a transmission rule. "complete"
also ties every pair of agents sharing a bubble while the policy is in
force, so households become complete and merged households meet in full.
The ties are withdrawn when the bubbles are redrawn, when the policy lifts,
and on the last day of the run, so a run always leaves the network as it
found it. "complete" requires an undirected network. See the updated
"Social bubbles" vignette for an example.Directed networks are now directed. Networks built with
agents_from_edgelist(..., directed = TRUE) or
agents_smallworld(..., d = TRUE) were silently made undirected. A tie
source -> target is now kept by the source only: target is one of
source's neighbors, and since agents are exposed to their own neighbors,
target can infect source but not the reverse. get_network() now
returns the ties as given. Results change for directed networks;
undirected networks give the same results as before.
Directed networks no longer use the queuing system, so large directed networks may run slower.
agents_from_edgelist() builds the network about 10 times faster (under
20 ms instead of about 150 ms for 100,000 agents with 10 ties each).
agents_smallworld() and agents_sbm() are somewhat faster too. The
networks, and so the results for a given seed, are unchanged.
agents_smallworld() again)
after run_multiple() now takes effect. Before, the next run restored the
network backed up by run_multiple(), population size included.Syncs the C++ core with epiworld 0.16.1.
Network models (ModelSIR(), ModelSIS(), ModelSISD(), ModelSIRD(),
ModelSEIR(), ModelSEIRD(), and models built with
update_fun_susceptible()) now simulate transmission faster.
At each step, the model either has infected agents push infection to
their neighbors or has susceptible agents pull it from theirs, whichever
is cheaper. Both give the same distribution of outcomes.
Results for a given seed change in those models, and wherever the random distribution functions below are used. Only the random draws change; the model's behaviour does not.
distribute_tool_to_set() and distribute_virus_to_set() no longer take
time quadratic in the number of agents: the set of IDs was copied every
time an agent received the tool or virus. Protecting 24,000 of 100,000
agents went from about 0.75 seconds to a few milliseconds.
distribute_tool_randomly() with agents_ids now picks agents from that
set. It used to pick among the first length(agents_ids) agents of the
model instead.
distribute_tool_randomly(), distribute_virus_randomly(),
distribute_tool_to_entities() and distribute_virus_to_entities() now
pick every candidate with the same probability. The last candidate was
never picked for the first recipient, and the one before it was picked
twice as often.
A transition or contact with probability exactly 1 now always happens. Before, the last option was chosen instead, so a death probability of 1 could end in recovery.
get_hist_tool() now labels the tool column with the model's tool names.
It previously used the virus names instead, and could read past the end of
the name list (undefined behaviour) when a model had more tools than
viruses.
The new function bubbles() implements social-bubble contact restrictions on
network models, with the household- and peer-based rules used during COVID-19
(see the "Social bubbles on a small-world network" vignette). How leaky the
bubbles are is held in a model parameter ("Bubble transmission factor" by
default), which scales transmission along out-of-bubble contacts and can be
read with get_param() and changed with set_param() at any point.
Each copy of a model keeps its own bubbles, so replicates run on any number
of threads. sample_household_sizes() draws household sizes to go with it.
New vignette, "Using external network data: GeoPops synthetic populations",
showing how to bring an externally-generated population and its contact
networks into a model with agents_from_edgelist(), and how to give
transmission a weekday/weekend rhythm with the global events module. It comes
with a small extract of a GeoPops synthetic population in
system.file("extdata", "geopops", package = "epiworldR").
The new functions get_contact_matrix() and set_contact_matrix() allow users to access contact matrices in mixing models.
Saved run_multiple() results now have documented plotting support, including transition-matrix diagrams through plot_multiple_transition().
The new helper compute_ts_ci_area() computes polygon and median-line data for plotting uncertainty intervals in time series.
draw_mermaid() is now documented with the model-diagram helpers and consistently returns an epiworld_diagram object.
The ModelSEIRMixingQuarantine model was not officially tracking hospitalizations. This means that using the saver to extract hospitalizations would return zero.
Using globalevent_fun() with run_multiple(..., nthreads > 1) was not compatible because R is not thread-safe. run_multiple() now warns the user and automatically switches to nthreads = 1.
The ModelSEIRMixingQuarantine now features a single hospitalization state instead of two. The model now assumes that hospitalized individuals are detected immediately and trigger the quarantine process.
The package now includes the function agents_sbm(), which implements the Stochastic-Block Model by Batahelj and Brandes (2005).
The mixing models--ModelSEIRMixing(), ModelSIRMixing(), and ModelSEIRMixingQuarantine()--lost the contact_rate parameter in favor of a more flexible model: instead of using mixing matrices (row-stochastic), the model now uses a contact matrix, which allows groups to have different contact rates.
New model builder functions Model(), add_state(),update_fun_susceptible(), and update_fun_rate() expose a new approach to build models in the package. Using these functions, users can create models from zero (to hero!). The package includes a new vignette demonstrating its usage.
The new function compute_reproduction_number() provides a way to estimate either the basic or the effective reproductive number. This is most useful for mixing models.
Fixes a bug in how GlobalEvents polymorphism is implemented in the core library.
Removed the measles-related headers (were unused by this package).
Introduced an optimization for accelerating binomial draws based on Le Cam's inequality. The function defaults to poisson draws (faster) in case of rare events.
seed is passed to run() and run_multiple() has been modified to ensure comparability with the C++ version. Now, a random seed number is drawn only if seed is not specified.(epiworld#189) Addressing memory access issues that arise when calling run_multiple using OpenMP. The latest version reduces usage of points (including smart) to make the code more reliable. No penalties on its performance are expected.
Switch vignette building engine to quarto.
No significant changes on the user side.
(epiworld#169) The Entities system was still causing issues. The system was refactored to use indices instead without any pointers.
(same issue) The system completely avoids binding via pointers (with the exception of DataBase). This provides a cleaner API reducing issues related to memory/address problems. Model::clone_ptr now returns smart pointers instead.
(epiworld#163) Changed the main engine for Pseudo Random Number Generation to xorshiro** (more in this website and this paper by Blackman and Vigna). This change makes random number generation significantly faster (twice as much, compared to Mersenne Twister).
Updates to epiworld version 0.12.0, including a patch to the ModelSEIRMixingQuarantine model. It was underestimating the outbreak size. This is a similar issue detected in the collection of the measles models.
The ModelSEIRMixingQuarantine gained a couple of extra checks for validating the inputs.
Simplified build configuration to comply with CRAN policies: removed custom
configure script, using R's built-in OpenMP settings
($(SHLIB_OPENMP_CXXFLAGS)) and specifying C++17 via CXX_STD in Makevars
and SystemRequirements in DESCRIPTION.
Changing how Entities are managed in the system, moved away from using pointers and instead use reference_wrapper.
epiworld version 0.11.2 including minor patches to avoid warnings and notes from clang.These changes will be reflected in the measles R package (so no changes for the epiworldR package):
The measles school model was not including the number of recovered agents in the population that it could sample from, which resulted in a minor overestimation of the outbreak size (about 5 to 10 percent).
The measles mixing models were assuming the number of available agents did not change when sampling contacts. This has been corrected. Outbreak sizes are now expected to be larger on average.
New distribution functions distribute_virus_to_entities() and distribute_tool_to_entities() that allow distributing viruses and tools to agents based on their entity membership (new in epiworld 0.11.0).
New function add_entities_from_dataframe() that allows adding multiple entities to a model based on a data.frame (wrapper around add_entity()).
New functions get_outbreak_size() and get_active_cases() allow extracting timeseries of the outbreak size and number of active cases (individuals with a virus) (new in epiworld 0.11.0).
New function get_hospitalizations() that allows extracting timeseries of hospitalizations from the model results (new in epiworld 0.11.0).
virus_hist and tools_hist, respectively. This has been fixed (new in epiworld 0.11.0).ModelMeaslesSchool, ModelMeaslesMixing, ModelMeaslesMixingRiskQuarantine, and the deprecated ModelMeaslesQuarantine) have been moved to a separate package. Users who need measles models should install the measles package.New model ModelMeaslesMixingRiskQuarantine that implements a measles model with mixing, risk-based contacts, and quarantine has been added. This is part of a joint effort with our partners at the Utah Department of Health and Human Services (DHHS).
Added print and plot methods for epiworld_diagram objects. This allows easy visualization of model diagrams generated with DiagrammeR.
run_multiple_get_results() has two new arguments: freader and ..., which allows the user to specify a custom function to read the results of each simulation (e.g., data.table::fread).The rewiring algorithm was not changing the edges, but only the weights of the edges. This has been fixed in epiworld 0.9.4.
The saver associated with tools_hist had a bug that caused it to not save the history of tools correctly. This has been fixed in epiworld 0.10.0. This was detected during work with @margowheatley and @AliseMendoza.
The ModelMeaslesQuarantine model has been updated to warn the user if the deprecated parameter vax_improved_recovery is used. This parameter is no longer used and has been removed.
Various legacy C++ files have been removed from the inst/include/epiworld folder.
We now include model diagrams in the documentation of each model (new feature of epiworld 0.10.0).
Various improvements to the documentation of the package and models.
The C++ library has been updated to version 0.9.1, which includes several speed improvements. Some preliminary tests show x10 speedups.
New model ModelSEIRMixingQuarantine that implements a SEIR model with quarantine and mixing has been added.
ModelMeaslesQuarantine has been deprecated in favor of ModelMeaslesSchool (change of name).The run_multiple() function was failing to correctly backup the agents' edgelist in the case of network models. This was due to a bug in the C++ library that was not correctly copying the edgelist. This has been fixed.
When multiple transitions happened in a single step, e.g., I->E->S, the model was only recording E->S, but not I->S (which is the correct).
In the ModelMeaslesQuarantine model, isolated individuals now have a different parameter for the number of days in isolation. Previously, the same parameter was used for both isolated and quarantined individuals. The new parameter is isolation_period.
The ModelMeaslesQuarantine model changed a couple of parameter names to improve consistency. We also improved the documentation of the model.
The mixing models were using the wrong sampling scheme for the contact event between agents. The new implementation allows using the regular basic reproductive number calculation for its calibration.
The functions distribute_(virus|tool)_to_set now have an additional argument that allows restricting the set of agents.
Added more tests to the ModelMeaslesQuarantine model, as well as to the set_distribution*, distribute_*, and get_agents_states functions.
A large overhaul memory management was performed (C++ side), decreasing the memory footprint by one order of magnitude in some cases.
Adds the ModelMeaslesQuarantine model, which implements a
measles model with quarantine.
Adds the capability of generating model diagrams using mermaid through the draw_mermaid() model function and the ModelDiagram set of functions.
Adds an advanced usage vignette.
Adds more extensive input parameter checks during model creation.
Updates to reflect changes in the epiworld C++ library (mostly bug fixes)
Package now requires R version >=4.1.0, because it uses the pipe |>
The package now includes the LFMCMC module that implements
the likelihood-free Markov Chain Monte Carlo algorithm. This
module is used to estimate the parameters of the models.
The new function add_param() allows the user to add parameters
to the model.
The new function rm_globalevent() allows the user to remove
global events from the model.
The function today() returns the current day (step) of the
simulation.
We changed the versioning system. To allow the R package to increase version number while preserving epiworld (C++) versioning, we added a fourth number that indicates R-only patches (similar to RcppArmadillo).
Starting version 0.3-0, epiworldR is versioned using the same version as the C++ library, epiworld.
Adds the new mixing models ModelSIRMixing and ModelSEIRMixing.
Ports the Entity class. Entities are used to group agents within a model.
Refactors add_tool, add_virus, and add_entity simplifying syntax. Now,
these functions only receive the model and object. Prevalence is
specified in the object itself. add_tool_n and add_virus_n are now
deprecated.
globalaction_* are now defunct. Use globalevent_* instead.
New functions to specify how viruses, tools, and entities are distributed
among agents: distribute_viruses, distribute_tools, and distribute_entities.
run_multiple() after a single
call of run(). Reported on 14.Added missing checks of tool class when adding a model with add_too_n.
Various small improvements.
Added the following models: ModelSEIRD, ModelSEIRDCONN, ModelSIRD, ModelSIRDCONN, and ModelSISD.
Fixed a bug reported on issue 6.
Added a NEWS.md file to track changes to the package.
Fixed bug reported by CRAN about reference to nullptr.
Renamed arguments across Models in favor of consistency.
Figures now show virus/tool name instead of id.
Fixed bug in run_multiple and added more tests (C++).
Redid autoconf and Makevars using RcppArmadillo as a template for checking for OpenMP.