The Euler–Lotka Equation: From Growth Rate to R₀
Early in an outbreak the one thing you can measure cleanly is the growth rate: cases are doubling every few days. What you actually want is the reproduction number, because that is what tells you how hard the epidemic is to stop. The Euler–Lotka (renewal) equation is the exact bridge between the two, and it carries a surprise: the same growth rate implies a different depending on the shape of the generation interval.
The renewal equation
Write for the number of new infections at time and for the generation-interval distribution, the normalized probability that transmission from an infected person happens a time after their own infection. Each person infected at time contributes, on average, new infections a time later. Summing over all past infection times gives the renewal equation:
Today’s incidence is a convolution of past incidence with the infectiousness profile, scaled by . This is the continuous-time parent of the discrete renewal equation used to estimate the effective reproduction number, and it is the same accounting that a branching process does one generation at a time.
From to
During the early phase incidence grows exponentially, , where is the growth rate. Substitute into the renewal equation:
The cancels, leaving the Euler–Lotka equation:
where is the moment-generating function of the generation interval. So : read off the growth rate, know the generation-interval distribution, and follows exactly.
This is the epidemiological twin of the demographic Euler–Lotka equation for an age-structured population,
where is survival to age and is fecundity at age (the machinery behind reproductive value). An infection’s generation interval plays the role of a mother’s age-specific reproduction, and is the net reproduction number.
Why the shape of the generation interval matters
The map depends on the whole distribution , not just its mean. Three tractable cases make the point, all with the same mean generation interval and the same growth rate .
Fixed delay. If everyone transmits exactly after infection, is a spike at and , so
This is the largest any distribution with mean can give.
Exponential interval. If is exponential with mean , then and
the familiar linear approximation, and the smallest in the gamma family.
Gamma interval. A gamma generation interval with mean and shape (so scale ) gives
which interpolates between the two: is exponential, and recovers the fixed-delay .
Two lessons follow. For a fixed , a longer mean generation interval implies a larger , because the same growth has to be packed into slower cycles. For a fixed mean, less variable intervals (larger shape ) imply a larger , because concentrating transmission in time makes a given growth rate demand more secondary cases per generation. Assuming an exponential interval when the truth is nearly fixed can badly understate .
Practical caution
Two cautions matter in practice.
First, we almost never observe the generation interval directly, because the moment of infection is unseen; the serial interval (onset to onset) is the usual proxy. The serial interval has the same mean as the generation interval under simple assumptions but a larger variance, so plugging it into Euler–Lotka as if it were biases .
Second, mis-specifying propagates straight into . Wallinga & Lipsitch showed that the relationship between and is governed entirely by the generation-interval distribution, and that different plausible distributions consistent with the same data can yield materially different (Wallinga & Lipsitch 2007, doi:10.1098/rspb.2006.3754). Park et al. developed a practical generation-interval-based approach that makes these dependencies explicit and quantifies how uncertainty in maps to uncertainty in the inferred strength of an epidemic (Park et al. 2019, doi:10.1016/j.epidem.2018.12.002).
A worked example
Take a gamma generation interval with mean days and shape , and an observed growth rate per day (roughly a 4.6-day doubling time). The Euler–Lotka answer is
The exponential-interval approximation for the same mean would give , and the fixed-delay extreme would give . The same growth rate spans from to purely through the assumed interval shape.
In code
We compute from via , then simulate the renewal equation forward at that and recover the growth rate as a round-trip check.
R
r <- 0.15; shape <- 4; mean_gi <- 6; scale <- mean_gi / shape
# Continuous Euler-Lotka: R0 = 1 / M(-r), M(-r) = (1 + r*scale)^(-shape)
R0_mgf <- (1 + r * scale)^shape
# Discretized generation interval on days 1..40
tau <- 1:40
g <- dgamma(tau, shape = shape, scale = scale); g <- g / sum(g)
R0_disc <- 1 / sum(exp(-r * tau) * g) # discrete Euler-Lotka
# Round-trip: seed the renewal recursion, recover the growth rate
T <- 160; inc <- numeric(T); inc[1] <- 1
for (t in 2:T) {
s <- 1:min(t - 1, length(g))
inc[t] <- R0_disc * sum(inc[t - s] * g[s])
}
r_hat <- coef(lm(log(inc[90:140]) ~ I(90:140)))[2]
c(R0_mgf = R0_mgf, R0_disc = R0_disc, r_hat = r_hat)
Python
We use SciPy for the gamma density and NumPy for the renewal recursion.
import numpy as np
from scipy.stats import gamma as gamma_dist
r, shape, mean_gi = 0.15, 4.0, 6.0
scale = mean_gi / shape
# Continuous Euler-Lotka: R0 = 1 / M(-r), M(-r) = (1 + r*scale)^(-shape)
R0_mgf = (1 + r * scale) ** shape
print(f"R0 (continuous MGF) = {R0_mgf:.3f}")
# Discretized generation interval on days 1..40
tau = np.arange(1, 41)
g = gamma_dist.pdf(tau, a=shape, scale=scale)
g = g / g.sum()
R0_disc = 1.0 / np.sum(np.exp(-r * tau) * g) # discrete Euler-Lotka
print(f"R0 (discrete kernel) = {R0_disc:.3f}")
# Round-trip: seed the renewal recursion, recover the realized growth rate
T = 160
inc = np.zeros(T); inc[0] = 1.0
for t in range(1, T):
s = np.arange(1, min(t, len(g)) + 1)
inc[t] = R0_disc * np.sum(inc[t - s] * g[s - 1])
win = np.arange(90, 140)
r_hat = np.polyfit(win, np.log(inc[win]), 1)[0]
print(f"target r = {r:.3f}, realized r = {r_hat:.3f}")
R0 (continuous MGF) = 2.252
R0 (discrete kernel) = 2.251
target r = 0.150, realized r = 0.150
The realized growth rate returns the value we started from, confirming that and the renewal equation are two views of the same relationship.
Julia
using Distributions, Statistics
r, shape, mean_gi = 0.15, 4.0, 6.0
scale = mean_gi / shape
R0_mgf = (1 + r * scale)^shape # continuous Euler-Lotka
tau = 1:40
g = pdf.(Gamma(shape, scale), tau); g ./= sum(g)
R0_disc = 1 / sum(exp.(-r .* tau) .* g) # discrete Euler-Lotka
T = 160; inc = zeros(T); inc[1] = 1.0
for t in 2:T
s = 1:min(t - 1, length(g))
inc[t] = R0_disc * sum(inc[t .- s] .* g[s])
end
X = hcat(ones(51), 90:140)
r_hat = (X \ log.(inc[90:140]))[2]
(R0_mgf = R0_mgf, R0_disc = R0_disc, r_hat = r_hat)
Why it matters
The Euler–Lotka equation is why a growth rate alone is never enough to name a reproduction number. Report a doubling time and you have pinned , but still depends on the generation interval you assume, and the gap between plausible assumptions can be the difference between “hard to stop” and “very hard to stop.” This is the exact link that turns the messy, early-outbreak signal we can see (speed) into the control-relevant quantity we care about (strength), and it is why estimating the generation interval well is inseparable from estimating .