07
Programming a CTMC SIS model
This lesson applies Gillespie’s algorithm to an infection in which recovery gives no lasting immunity. Its new biological idea is reinfection: a recovered individual immediately becomes susceptible again.
Scenario: an infection with no lasting immunity
Consider 100 people in a community. Initially, 5 are infectious and 95 are susceptible. After recovery, a person can be infected again. This behaviour can represent some bacterial infections and other infections for which immunity is weak or short-lived.
\(S\)
← recovery
\(I\)
Because the population is closed, \(S+I=N\). Therefore, knowing \(I\) automatically gives \(S=N-I\).
Two events and their rates
Infection
\(I\) increases by 1.
The rate is zero when nobody is infectious or nobody is susceptible.
Recovery
\(I\) decreases by 1.
Recovery returns the individual to the susceptible compartment.
The total rate is \(a_0(I)=a_{\mathrm{inf}}(I)+a_{\mathrm{rec}}(I)\). Gillespie’s algorithm generates the next waiting time from \(\operatorname{Exp}(a_0(I))\) and then chooses infection or recovery in proportion to these rates.
Boundary states and extinction
| State | Possible events | Meaning |
|---|---|---|
| \(I=0\) | None | Infection is extinct. This is absorbing because the model has no importation. |
| \(0<I<N\) | Infection and recovery | Both types of event may be possible. |
| \(I=N\) | Recovery only | There are no susceptible people, so the infection rate is zero. |
These conditions are produced naturally by the rate formulas; separate artificial probabilities are not required.
Threshold intuition
Near the beginning, when almost everyone is susceptible, each infectious person produces infections at approximately rate \(\beta\) and recovers at rate \(\gamma\). The basic reproduction number is
If \(R_0>1\), infection initially has an upward tendency. This does not guarantee a major outbreak: the CTMC can still reach \(I=0\) through chance.
Interactive Python laboratory
Click Run code. The program simulates one SIS trajectory, prints its event log and summary, and draws the irregular-time step path. Change the seed to see a different possible epidemic.
Output
Run the code to see the result.
Understand the important code
| Code | Meaning |
|---|---|
S = N - I | Uses population conservation, so only \(I\) must be stored as the state. |
rng.exponential(1 / total_rate) | NumPy expects the exponential mean, which is \(1/a_0\), not the rate \(a_0\). |
infection_rate / total_rate | Converts the infection rate into the conditional probability that the next event is infection. |
0 <= I <= N | Checks the required SIS state-space condition. |
where="post" | Keeps the state constant after each jump until the next event. |
Interpret the outcome
A rising path means infection events are temporarily occurring more often than recoveries. A falling path means recoveries dominate over that part of this particular random history.
The dashed line is the positive deterministic equilibrium \(I^*=N(1-\gamma/\beta)\) when \(R_0>1\). It is a reference level, not an absorbing CTMC state. A finite stochastic SIS process can fluctuate around it for a long time and still eventually become extinct.
Try these biological experiments
- Set
I = 1and try several seeds. Record how often extinction occurs quickly. - Set
beta = 0.08, giving \(R_0<1\), and observe the stronger downward tendency. - Increase
Nwhile keeping the initial infected proportion similar. Compare the relative size of fluctuations. - Remove the fixed seed only after you understand reproducibility: the result will then vary on every run.
What is unique to this lesson?
You have used one state variable, represented recovery as a return to susceptibility, and distinguished a deterministic endemic level from stochastic extinction. The next lesson changes the biology: recovered people remain removed, so reinfection is no longer possible and final epidemic size becomes meaningful.