09
Programming a CTMC SEIR model
The SEIR model separates becoming infected from becoming infectious. A newly infected person first enters a random latent period in the exposed compartment.
Scenario: infection with a latent period
A closed population contains 300 people. Initially, 294 are susceptible, 4 are exposed and 2 are infectious. Exposed individuals carry the infection but are not yet infectious in this basic model.
\(S\)
\(E\)
\(I\)
\(R\)
Three events and their rates
1. Infection
2. Progression
3. Recovery
The total rate is \(a_0=a_1+a_2+a_3\). At each jump, Gillespie’s algorithm selects one and only one of these events.
Interpret the progression parameter
Each exposed individual progresses at rate \(\sigma\) per day. Under the Markov assumption, that person’s latent time is exponentially distributed:
For \(\sigma=0.20\) per day, the mean latent period is 5 days. This is a mean, not a fixed five-day delay: individual progression times vary randomly.
When has an SEIR epidemic ended?
| Condition | Can infection continue? | Reason |
|---|---|---|
| \(I=0\) but \(E>0\) | Yes | Exposed people can progress and create new infectious people. |
| \(E=0\) but \(I>0\) | Yes | Infectious people can still infect or recover. |
| \(E=0\) and \(I=0\) | No | All three event rates are zero. |
Therefore, the correct biological stopping condition is E == 0 and I == 0, not merely I == 0.
Interactive Python laboratory
Run a complete SEIR epidemic. The program prints event identities that verify the compartment bookkeeping, plots all four state paths, and compares the cumulative infection and progression processes.
Output
Run the code to see the result.
Understand the three-event selection
| Random interval | Selected event |
|---|---|
| \(0\le U<a_1/a_0\) | Infection |
| \(a_1/a_0\le U<(a_1+a_2)/a_0\) | Progression |
| \((a_1+a_2)/a_0\le U<1\) | Recovery |
np.cumsum(rates / total_rate) creates the upper boundaries of these intervals. The final boundary is 1 apart from tiny floating-point rounding.
Why the event-count checks work
Every person entering \(E\) must eventually progress before the simulation ends. Therefore:
Likewise, every person entering \(I\) must eventually recover:
These are not extra model assumptions. They are accounting identities for a completed closed SEIR epidemic and useful checks on the program.
Interpret the two plots
The compartment plot shows that the exposed peak can occur before the infectious peak. The exact timing and separation vary between trajectories.
In the cumulative-event plot, infection events usually lead progression events because people must first enter \(E\). The gap represents people currently waiting in the exposed compartment; initial exposed people explain the initial offset in the bookkeeping identity.
Try these experiments
- Reduce
sigmato0.10. The mean latent period becomes 10 days; compare the peak times. - Increase
sigmato1.0. Observe how the model approaches faster SIR-like progression. - Use
I = 0but keepE = 4. Confirm that the program does not stop prematurely. - Try several seeds and compare whether the exposed or infectious peak changes more.
What is unique to this lesson?
You have separated infection from infectiousness, interpreted the exponential latent period, selected among three competing events, used the correct SEIR extinction condition, and verified the simulation with event-count identities. The next lesson moves from trajectory simulation to the CTMC generator matrix.