Project 32: Epidemic Growth Simulator

A self-contained deep-dive from the canonical Math from Foundations to Machine Learning curriculum.

  • Difficulty: Intermediate
  • Time: 1-2 weeks
  • Language: Python with NumPy and Matplotlib
  • Prerequisites: Projects 6, 12, and 26
  • Source: HS P11

What You Will Build

Build a discrete SIR-style epidemic simulator with susceptible, infected, and recovered compartments. Start with exponential growth to reveal why a constant percentage produces nonlinear curves, then add finite population, contact/infection rate, recovery rate, and optional vaccination or intervention schedules. Update the coupled recurrences from the same previous state so population is conserved. Plot all compartments, daily new infections, cumulative cases, and effective reproduction intuition. Provide seeded stochastic and deterministic modes, parameter sweeps, and scenarios such as delayed distancing or increased recovery. Frame outputs as model behavior under assumptions, not forecasts or medical advice; every run must display limitations and units.

Real World Outcome

The dashboard compares baseline and intervention scenarios, reports peak infected count and day, final attack fraction, and verifies S+I+R=N at every step. A heatmap shows how peak size or timing changes across transmission and recovery rates, with parameters and random seed exported alongside plots.

Core Question

How can simple coupled rate equations create rapid growth, a peak, and decline, and which assumptions control whether those curves resemble reality?

Concepts You Must Understand First

  1. Exponential versus logistic effects: unrestricted proportional growth differs from growth limited by a finite susceptible pool.
  2. Compartment recurrence: flows leaving one compartment enter another; use a consistent time index.
  3. Rates and units: transmission and recovery parameters depend on the chosen time step.
  4. Equilibria and thresholds: infection grows initially when effective transmission exceeds recovery.
  5. Model uncertainty: parameter sensitivity and structural assumptions matter more than precise-looking curves. See Guttag, Introduction to Computation and Programming Using Python, modeling chapters.

Build Milestones

  1. Implement and graph pure exponential growth with doubling-time checks.
  2. Add deterministic SIR recurrences and assert nonnegative compartments and population conservation.
  3. Compute observable summaries: incidence, prevalence, peak timing, and final sizes.
  4. Add interventions, vaccination, and a seeded stochastic transition option.
  5. Build one- and two-parameter sweeps with side-by-side scenario reports.

Hints in Layers

  1. Calculate all flows from copies of the old S, I, and R values before updating any compartment.
  2. Clamp only tiny floating-point negatives; large negative populations indicate a step-size or formula bug.
  3. Express intervention schedules as functions of time so scenarios remain reproducible and testable.

Common Pitfalls and Debugging

  • Symptom: total population drifts. Cause: flows were added or removed inconsistently. Fix: model each flow once and assert conservation every step.
  • Symptom: results change drastically when switching days to hours. Cause: rates were not rescaled with dt. Fix: attach units and convert rates explicitly.
  • Symptom: compartments become negative. Cause: one step moves more people than available. Fix: reduce dt or bound discrete transition counts.

Definition of Done

  • Exponential growth matches a hand-computed doubling example.
  • SIR runs preserve population and nonnegative state within tolerance.
  • Plots distinguish incidence, prevalence, and cumulative quantities.
  • At least three interventions can be compared reproducibly.
  • Parameter sweeps expose sensitivity rather than one “correct” curve.
  • Every report states assumptions, units, seed, and non-forecast limitations.

Previous: Project 31 · Complete learning path · Next: Project 33