← Discrete-Time Markov Chains

08

Programming a DTMC SIR model

The SIR model describes an infection followed by removal with lasting immunity. Recovery is irreversible, so the final removed population records how many people experienced infection during the modelled outbreak.

The new biological idea: irreversible recovery

Susceptible\(S\)
→
Infectious\(I\)
→
Removed\(R\)
\[ S\xrightarrow{\text{infection}}I \xrightarrow{\text{recovery}}R. \]

A removed person does not return to susceptibility. Depending on the application, “removed” may mean recovered and immune, isolated, or otherwise no longer able to transmit.

How SIR differs from SIS

FeatureSISSIR
After recovery\(I\to S\)\(I\to R\)
ReinfectionAllowedNot allowed in the basic model
State reductionOne count: \(I\)Two counts are needed, such as \((S,I)\)
Disease-free statesOnly \(I=0,S=N\)Many states with \(I=0\)
Final epidemic sizeNo permanent removed totalRecorded by the final removed count

The SIR state and state space

For a closed population:

\[ S_n+I_n+R_n=N. \]

We may store the full state \((S_n,I_n,R_n)\) because it is biologically easy to read. Mathematically, only two counts are independent because:

\[ R_n=N-S_n-I_n. \]

Using \((S,I)\), the state space is the finite triangular set:

\[ \mathcal S= \{(s,i):s\ge0,\ i\ge0,\ s+i\le N\}. \]

Not every pair from \(\{0,\ldots,N\}^2\) is possible. For example, \(S=150,I=100\) is impossible when \(N=200\) because their sum already exceeds the population.

Possible transitions from ((s,i,r))

Infection

\[ (s,i,r)\longrightarrow(s-1,i+1,r). \]

One susceptible person becomes infectious.

Recovery

\[ (s,i,r)\longrightarrow(s,i-1,r+1). \]

One infectious person is removed permanently from transmission.

No change

\[ (s,i,r)\longrightarrow(s,i,r). \]

No event occurs during the fixed step.

Impossible reverse movements

The basic model has no \(R\to S\), \(R\to I\) or \(I\to S\) transition.

Transition probabilities

At current state \((s,i,r)\), the short-step probabilities are:

\[ \begin{aligned} p_{\mathrm{inf}}(s,i) &=\beta\frac{si}{N}\Delta t,\\ p_{\mathrm{rec}}(i) &=\gamma i\Delta t,\\ p_{\mathrm{stay}}(s,i) &=1-p_{\mathrm{inf}}(s,i)-p_{\mathrm{rec}}(i). \end{aligned} \]

The removed count does not appear directly in these probabilities. It still matters because population conservation restricts how large \(s\) and \(i\) can be.

The absorbing boundary is a whole set of states

If \(i=0\), then infection and recovery probabilities are both zero. Therefore every state:

\[ (s,0,N-s),\qquad s=0,1,\ldots,N, \]

is absorbing.

These states represent different completed outbreak histories. A large final susceptible count describes a small outbreak; a small final susceptible count describes a large outbreak.

Quantities obtained from one completed SIR path

Peak size\(I_{\max}\): the largest infectious count in this realisation.
Peak timeThe first time at which this path reaches \(I_{\max}\).
Final epidemic sizeThe number ever infected by the end of this realisation.

If initially \(R_0=0\), everyone who has experienced infection is either still infectious or removed. At extinction \(I_\infty=0\), so:

\[ Z=R_\infty=N-S_\infty. \]

If some people are already removed initially, the number infected during the simulated outbreak is:

\[ Z=R_\infty-R_0=S_0-S_\infty+I_0. \]

The attack proportion is \(Z/N\). It is a realised outcome for one trajectory, not yet an expected value.

Interactive Python laboratory

The code generates one SIR outbreak, checks all stored states, calculates the peak and final epidemic size, and produces both a time trajectory and a state-space path.

Interactive PythonDTMC SIR outbreak

Output

Run the code to see the result.

Why use a sufficient probability bound?

Across the SIR state space:

\[ SI\le\frac{N^2}{4}, \qquad I\le N. \]

Therefore:

\[ p_{\mathrm{inf}}+p_{\mathrm{rec}} \le \left(\frac{\beta N}{4}+\gamma N\right)\Delta t. \]

This bound is deliberately conservative because both separate maxima need not occur at the same state. If the bound is at most 1, every state is guaranteed to have a non-negative no-change probability.

Why check monotonicity?

In the basic closed SIR model:

\[ S_{n+1}\le S_n, \qquad R_{n+1}\ge R_n. \]

The susceptible count can fall or stay unchanged but cannot increase. The removed count can rise or stay unchanged but cannot decrease. The code uses .diff() to calculate consecutive changes and checks these model-specific directions.

Read the state-space graph

The first graph uses time on its horizontal axis. The second graph removes time from the axes and plots each realised pair \((S_n,I_n)\).

Final epidemic size when the horizon is too short

If the simulation stops with \(I>0\), final_R is not yet the completed final epidemic size. Some currently infectious people may recover, and additional infections may occur later.

For this reason, the code reports the stopping reason. A completed final size should be claimed only when extinction has occurred or when an explicitly justified approximation is being used.

Understand the model-specific code

CodeMeaning
initial_R = RRetains the starting removed count so infections occurring during the simulation can be separated from earlier removals.
trajectory["S"].diff()Calculates each susceptible count minus the preceding susceptible count.
.dropna()Removes the undefined first difference, because the first row has no preceding row.
initial_S - final_SCounts new transmission infections, because only infection can reduce \(S\).
initial_I + new_transmission_infectionsCounts everyone infected in this outbreak so far, including those infectious initially.
final_epidemic_size / NCalculates the realised attack proportion only after extinction completes the outbreak.
plt.scatter(...)Marks the initial and final points on the state-space path.

Try these experiments

  1. Change the seed. Compare peak size, peak time and final epidemic size.
  2. Set initial_I = 1 by using S, I, R = 199, 1, 0. Look for early extinction.
  3. Use beta = 0.08 and gamma = 0.10. Compare the outbreak outcome when \(\beta/\gamma<1\).
  4. Set max_days = 20. Explain why the displayed removed count may not be the completed final size.
  5. Use S, I, R = 147, 3, 50. Confirm that new infections are measured relative to the initial removed count.

Biological interpretation

In this realisation, infection consumes susceptible people and recovery accumulates removed people. Early random events influence whether the outbreak disappears quickly or reaches a substantial peak.

Permanent removal gives the SIR process a direction that SIS does not have. Once susceptibility has been lost, it is not restored. This makes the final susceptible and removed counts informative summaries of the completed outbreak.

Peak size, peak time and final epidemic size from one run remain random outcomes. Their probability distributions require many independent trajectories, introduced in Lesson 12.

What this lesson has added

  • SIR recovery is irreversible and prevents reinfection.
  • The independent state can be represented by \((S,I)\) in a triangular state space.
  • Every state with \(I=0\) is absorbing.
  • \(S\) is non-increasing and \(R\) is non-decreasing.
  • A completed path gives a realised final epidemic size and attack proportion.
  • A state-space path displays transitions differently from a time trajectory.

Lesson 9 adds an exposed compartment and a new progression event to construct a DTMC SEIR model.