03
Total event rate and exponential waiting time
Several biological events may be possible from the current state. Their rates combine to determine how long the CTMC waits before the next event of any type.
Separate “when?” from “which?”
When does the next event occur?
The total event rate determines the random waiting time.
This lessonWhich event occurs?
Relative event rates determine whether the jump is infection, recovery or another event.
Lesson 4Keeping these questions separate makes the Gillespie algorithm easier to understand and program.
Add competing event rates
At SIS state \(I=i\), infection and recovery are both possible:
The total event rate is the sum of the rates of all events currently possible. It measures the instantaneous rate at which the process leaves its present state.
Worked current state
For \(N=1000\), \(i=10\), \(\beta=0.3\) and \(\gamma=0.1\):
A larger total rate produces a shorter typical waiting time. A smaller total rate produces a longer typical waiting time.
The exponential waiting-time model
If the process is currently in a state with total rate \(a>0\), the waiting time \(\tau\) to the next event is exponentially distributed:
The rate \(a\) remains fixed only while the state remains unchanged. When an event occurs, the state changes, the rates are recalculated, and a new waiting time is generated.
Three descriptions of the same distribution
Probability that no event has occurred by time \(t\).
Probability that the next event occurs by time \(t\).
Describes how waiting-time probability is distributed over continuous time.
The density can exceed 1 for some parameter values; it is not a point probability. Probabilities are obtained from areas under the density curve.
Mean and median waiting times
The mean waiting time is:
At \(a=3.97\) events/day:
The median solves \(\Pr(\tau\le t)=0.5\):
The mean exceeds the median because the exponential distribution has a long right tail: most waits are relatively short, but occasional long waits raise the average.
Connection with the previous lesson
The exact no-event probability over length \(h\) is:
For very small \(h\), the exponential expansion gives:
This recovers the first-order no-event approximation \(1-ah\) from Lesson 2. The exponential distribution provides the exact waiting-time description without advancing through artificial small fixed steps.
Generate a waiting time from a uniform number
Let \(U\sim\operatorname{Uniform}(0,1)\). Inverse-transform sampling gives:
Because \(0<U\le1\), \(\log U\le0\) and therefore \(\tau\ge0\).
- Generate one uniform value.
- Take its natural logarithm.
- Change the sign.
- Divide by the current total rate.
Why use 1 - rng.random()?
NumPy's rng.random() generates values in \([0,1)\). The logarithm of zero is not finite. Therefore the code uses:
u = 1.0 - rng.random()
This gives \(U\in(0,1]\) and guarantees that np.log(u) is defined. The transformation has the same uniform distribution apart from irrelevant endpoint conventions.
The memoryless property
Conditional on no event having occurred during the first \(s\) time units, the distribution of the additional waiting time is the same as it was initially.
Memorylessness does not mean the process has no state. It means that while the state and its rates remain unchanged, elapsed waiting time alone does not alter the future waiting-time distribution.
Competing-clock intuition
Imagine an exponential clock with rate \(b(i)\).
Imagine another exponential clock with rate \(d(i)\).
The first clock to ring gives the next-event time. The minimum of these independent exponential clocks is exponential with rate \(b(i)+d(i)\).
This intuition explains why rates add. Lesson 4 uses the same competing rates to determine which clock wins.
What if the total rate is zero?
No event is possible from the current state. The process remains there indefinitely, so the code must not divide by zero or try to generate a finite waiting time.
For the closed SIS model, this occurs at \(I=0\), the absorbing extinction state.
Interactive Python laboratory
The code generates 10,000 waiting times at the current state and compares their empirical mean, histogram and survival curve with the exponential theory. It does not choose event types.
Output
Run the code to see the result.
Understand the new code
| Code | Meaning |
|---|---|
np.log(u) | Calculates the natural logarithm required by inverse-transform sampling. |
-np.log(u) / total_rate | Transforms one uniform value into an exponential waiting time. |
rng.random(10000) | Generates 10,000 uniform values in one NumPy array. |
density=True | Scales histogram area to 1 so it can be compared with a probability-density curve. |
(waiting_times > t).mean() | Calculates the proportion of simulated waits exceeding \(t\), an empirical survival probability. |
np.percentile(..., 99.5) | Limits the plotted range so a few extreme waits do not compress the main histogram. |
Biological interpretation
At the current state, the CTMC waits a random amount of continuous time before either infection or recovery occurs. The mean wait is about 6.05 hours, but individual waits may be much shorter or considerably longer.
The exponential model determines only when the next event occurs. It does not yet say whether that event is infection or recovery. That conditional selection is the unique purpose of Lesson 4.
What this lesson has—and has not—done
You can now:
- add competing transition rates to obtain the total leaving rate;
- interpret exponential survival, cumulative probability and density;
- calculate mean and median waiting times;
- generate waiting times by inverse transformation;
- explain memorylessness and the zero-total-rate case; and
- connect the exact survival function to the short-interval approximation.
Not yet: no event type has been selected and no state has been updated. Lesson 4 converts competing rates into conditional event probabilities.