AI-generated content
This chapter was automatically generated by an AI agent and has not been reviewed by a human. Read with caution.
Building Models from Scratch¶
Epiworld's built-in models cover many common compartmental structures, but the real power of the library lies in defining your own states and update functions. This chapter shows you how.
Defining States with add_state()¶
Every state in the model is registered through Model::add_state(). The
function takes a human-readable name and an optional update function:
epiworld::Model<> model;
// A state with a custom update function
model.add_state("Susceptible", epiworld::default_update_susceptible<>);
// A state whose update function is provided separately (or is absorbing)
auto infected_id = model.add_state("Infected", epiworld::default_update_exposed<>);
auto removed_id = model.add_state("Removed");
add_state() returns the integer ID of the new state. You will need these IDs
when configuring viruses (see
Viruses, Tools & Global Events).
Writing Update Functions¶
An update function is called once per day for every agent in that state. Its signature is:
Inside the function you can:
- Inspect or change the agent's state (
agent->change_state()). - Add or remove viruses (
agent->add_virus(),agent->rm_virus()). - Add or remove tools (
agent->add_tool(),agent->rm_tool()). - Query the agent's neighbors (
agent->get_neighbors()). - Access the model's random number generator (
model->runif()). - Read or write model parameters (
model->par()).
Example: A Custom "Isolated" State¶
template<typename TSeq>
void update_isolated(
epiworld::Agent<TSeq>* agent,
epiworld::Model<TSeq>* model
) {
// Each day there is a 5% chance the agent leaves isolation
if (model->runif() < 0.05)
agent->change_state(
*model, model->get_state_id("Susceptible")
);
}
// Register it:
model.add_state("Isolated", update_isolated<>);
Building a Simple SIR from Scratch¶
Putting it all together, here is a minimal SIR model that does not use
the built-in ModelSIR:
#include "epiworld.hpp"
using namespace epiworld;
int main() {
Model<> model;
// 1. Define states
model.add_state("Susceptible", default_update_susceptible<>);
auto infected_id = model.add_state("Infected", default_update_exposed<>);
auto removed_id = model.add_state("Removed");
// 2. Create a virus
Virus<> covid("covid 19", 0.05, true);
covid.set_prob_infecting(0.8);
covid.set_state(infected_id, removed_id, removed_id);
model.add_virus(covid);
// 3. Create a tool (vaccine)
Tool<> vax("vaccine", 0.5, true);
vax.set_susceptibility_reduction(0.95);
model.add_tool(vax);
// 4. Generate a contact network
model.agents_from_adjlist(
rgraph_smallworld(1000, 5, 0.01, false, model)
);
// 5. Run
model.run(100, 123);
model.print();
return 0;
}
The key insight is that default_update_susceptible and
default_update_exposed are library-provided update functions that
implement standard infection and recovery logic. You can replace them with
entirely custom functions when you need non-standard behavior.
Custom Network Structures¶
By default, agents_smallworld() or agents_from_adjlist() create the
contact network. You can also supply a rewiring function that modifies
the network at each time step:
template<typename TSeq>
void quarantine_rewire(
std::vector<epiworld::Agent<TSeq>>* agents,
epiworld::Model<TSeq>* model,
epiworld_double proportion
) {
for (auto& agent : *agents) {
if (agent.get_status() == model->get_state_id("Infected"))
agent.clear_neighbors();
}
}
model.set_rewire_fun(quarantine_rewire<>);
model.set_rewire_prop(0.1);
When model.rewire() is called (automatically at each step), the function
executes and can add, remove, or rearrange edges. This is useful for modeling
social distancing, school closures, or other behavioral interventions.
What's Next¶
- Viruses, Tools & Global Events — Learn how to configure viruses in detail, add tools, and schedule global events.
- Built-in Models — See how the library implements standard compartmental models so you can use them as starting points.
- Extending the Library with Models — A deeper look at packaging your custom model as a reusable template class.