Memory of one step
In 1913 Andrei Markov took the first letters of Pushkin's Eugene Onegin and counted how often a vowel follows a vowel and a consonant follows a consonant. He was making a mathematical point: the law of large numbers does not need independence. Letters are far from independent, but if each letter depends on the past only through the letter before it, averages still settle down. Processes of this kind — Markov chains — are now everywhere:
- Board games. In snakes and ladders (which originated in India as Moksha Patam), your next square depends only on your current square and the die. How long does a game last?
- The web. Google's PageRank ranks pages by the long-run fraction of time a random surfer spends on each — the stationary distribution of a chain on billions of states.
- Genetics. In the Wright–Fisher model of a population, the number of copies of a gene in the next generation depends only on the number in this one. Will a new variant spread or vanish?
- Computation. Markov chain Monte Carlo methods sample from distributions too complicated to write down, by running a chain that has them as equilibrium.
The questions are always the same: Where will the chain be after steps? Will it reach a given set of states, and how long will it take? Does it return to where it started? Does it settle into an equilibrium, and how fast? This lesson answers them for chains with countably many states, with complete proofs for finite chains. It uses probability theory (conditional probability, expectation) and linear algebra (matrices, eigenvalues, rank).
A two-state chain
Each day in a highland town is dry or rainy. If today is dry, tomorrow is rainy with probability ; if today is rainy, tomorrow is dry with probability . Let be the probability that day is rainy. Conditioning on day ,
This is a straight-line map with slope and fixed point ; when it is a contraction, and from any start, at the geometric rate .
The probability of rain, day by day
Start from a dry day (x₀ = 0). Every orbit is drawn to a/(a + b). Try a = b = 1: the slope is −1 and the orbit oscillates forever.
Iterates xₖ against k
- y = f(x)
- y = x
- cobweb path
Last iterates: x18 = 0.375, x19 = 0.375, x20 = 0.375
The orbit appears to settle at a fixed point x* ≈ 0.375.
Fixed points in view (numerical): x* = 0.375 (attracting: |f′(x*)| < 1)
Based on 3,000 iterations in floating-point arithmetic: numerical evidence, not proof.
Three phenomena are already visible. The chain has an equilibrium, the stationary probability of rain. It forgets its starting point geometrically fast. And when the weather alternates deterministically — a periodic chain, which never settles down. The rest of the lesson is about these three phenomena on general state spaces.
Definitions
Let be a countable set, the state space. A distribution on is a row vector with and .
Definition— transition matrix and Markov chain
A transition matrix (or stochastic matrix) is with and for every : each row is a distribution. A sequence of random variables with values in is a Markov chain with initial distribution and transition matrix if and, for all and all states,
whenever the conditioning event has positive probability. Equivalently, .
The Markov property says that, given the present state , the future is independent of the past and is itself a Markov chain started at . The strong Markov property says the same at a random time that is a stopping time (whether is decided by ), such as the first time the chain hits a given state. We write and for probabilities and expectations when .
Definition— hitting times, recurrence and transience
The hitting time of a set is and the first return time to is (with ). A state is recurrent if and transient otherwise. A recurrent state is positive recurrent if moreover , its mean return time.
Definition— communicating classes, irreducibility, period
State is accessible from , written , if for some , where . States communicate, , if and ; this is an equivalence relation, whose classes are the communicating classes. A class is closed if and imply . The chain is irreducible if there is a single class. The period of is , and is aperiodic if .
Definition— stationary distribution and detailed balance
A distribution is stationary (or invariant) if , that is, for all : a chain started from has distribution at every time. A distribution satisfies detailed balance with if for all ; the chain is then reversible: started from , it looks the same run forwards or backwards in time.
The total-variation distance between distributions is .
Examples
Example— The two-state chain in matrix form
With states dry and rainy, . Its eigenvalues are and , the stationary distribution is , and (proved by induction in the Lean section)
Each row is plus a correction of size . If , then ; if , then and alternates.
A transposed transition matrix acting on distributions
This is Pᵀ for a = 0.3, b = 0.1, so that column vectors (dry, rain) map to their next-day distributions. The invariant line for eigenvalue 1 is spanned by (b, a) = (0.1, 0.3) — the stationary distribution — and the other invariant line, with eigenvalue 1 − a − b = 0.6, is the direction (1, −1) that dies away.
- image of the grid
- image of the unit square
- image of the flag
- before the transformation
- invariant line
The columns of A are the images of e₁ = (1, 0) and e₂ = (0, 1): Ae₁ = (0.7, 0.3), Ae₂ = (0.1, 0.9)
det A = ad − bc = 0.6
The unit square (area 1) becomes a parallelogram of area |det A| = 0.6. Since det A > 0, orientation is preserved.
Invariant lines (real eigenvectors)
- λ₁ = 1, v₁ = (0.333, 1)
- λ₂ = 0.6, v₂ = (1, −1)
Vectors on the two dashed lines are only stretched, by the factors λ₁ = 1 and λ₂ = 0.6; every other direction is turned.
Example— Random walk on a graph
On a finite connected graph, let the walker move from a vertex to a uniformly random neighbour: for each edge . Then satisfies detailed balance, since for every edge; so it is stationary. The walk is irreducible (the graph is connected) and aperiodic exactly when the graph is not bipartite. On the wheel below, the hub has degree and the rim vertices degree , so in the long run the walker is at the hub a quarter of the time.
Random walk on a wheel
Stationary probability is proportional to degree: 5/20 at the hub, 3/20 at each rim vertex. In the matrix tab, entries of A^k count walks of length k.
3 + 3 + 3 + 3 + 3 + 5 = 20 = 2 × 10
Every edge has two ends, so it adds exactly 2 to the total: the degrees add up to 20 = 2 × 10. This is the handshake lemma, Σ deg(v) = 2|E|.
Vertices of odd degree: 6. This number is always even, because the total is even.
Example— Gambler's ruin
A gambler with coins bets one coin at a time, winning with probability and losing with probability , and stops at or . This is a chain on with , for and absorbing states and (). The classes are , (closed, recurrent) and (not closed, transient). Its hitting probabilities are computed below.
Example— The Ehrenfest urn: periodic and reversible
Paul and Tatjana Ehrenfest (1907) modelled the diffusion of gas between two containers: balls are split between two urns, and at each step a uniformly random ball changes urn. With the number of balls in the first urn, and . The binomial distribution satisfies detailed balance: . The chain is irreducible but has period ( changes parity at each step), so does not converge, although the long-run fraction of time spent at does tend to .
n-step transitions and first-step analysis
Theorem— Theorem (Chapman–Kolmogorov)
For a Markov chain with initial distribution and transition matrix : and . In particular .
Proof
By the law of total probability and the Markov property, , i.e. the row vector of probabilities at time is that at time times ; induct on . The last identity is .
∎
Products and powers of stochastic matrices are stochastic, so each is again a transition matrix — the matrix of the chain observed every steps.
Theorem— Theorem (hitting probabilities)
Let and . Then is the minimal non-negative solution of the system
meaning that solves it, and any solution with for all satisfies for all .
Proof
is a solution ("first-step analysis"): if then ; if , condition on and use the Markov property: .
Minimality. Let be a solution and . Substituting the equation into itself,
After substitutions, . Letting , .
∎
Expected hitting times are, in the same way, the minimal non-negative solution of for and for .
Example— Solving gambler's ruin
With , the probability of reaching satisfies for , with and (on a finite set the solution is unique, so minimality is automatic). The characteristic equation has roots and . Hence:
- Fair game (, double root ): , so .
- Unfair game (): , so .
The expected duration of the fair game solves , , so : starting with coins and playing to or takes bets on average. Betting on red at roulette (, ), the chance of turning coins into is . Against an infinitely rich opponent () the fair gambler is ruined with probability , while a gambler with survives forever with probability — here the minimality in the theorem is essential, since on an infinite state space the equations have many solutions.
Recurrence and transience
Theorem— Theorem (recurrence criterion)
Let and let be the number of returns to . Then for , and
So is recurrent if and only if , and then the chain started at returns infinitely often with probability .
Proof
Let be the time of the -th return (a stopping time). On the chain is at at time , so by the strong Markov property the future is a fresh chain started at , and the probability of a further return is , independently of the past. By induction . Then , which is if and infinite if . On the other hand, by linearity, . If , for every , so almost surely.
∎
Theorem— Corollary (recurrence is a class property; finite closed classes are recurrent)
If , then and are both recurrent or both transient. Every closed class with finitely many states is recurrent; in particular every state of an irreducible finite chain is recurrent.
Proof
Choose with and . Then (one way of returning to ), so implies ; by symmetry the converse holds too. For a finite closed class and , the chain stays in , so , and some has . With , , so is recurrent, and hence so is the whole class.
∎
On infinite state spaces recurrence becomes a deep question. Simple random walk on moves at each step to one of the neighbours, each with probability .
Theorem— Theorem (Pólya, 1921)
Simple random walk on is recurrent for and transient for .
Proof
A return to is only possible at even times. Write .
. , the probability of exactly steps to the right among . The binomial coefficients add up to and the middle one is the largest, so , and by comparison with the harmonic series.
. Rotate by : if is the walker's position, and change by at each step, with all four sign patterns equally likely. So and are independent simple random walks on , and . From and , induction gives for , so again .
(sketch). Counting paths with steps out and back along the three axes,
because the trinomial probabilities sum to . Stirling's formula shows that and that the maximum (attained near ) is , so , which is summable. In the walk restricted to its first three coordinates, watched only when they move, is a three-dimensional walk, so it too is transient.
∎
The cases and — the divergence of and — are formalised in Lean below. The precise asymptotics are , and in the walk returns with probability about (Watson, 1939). "A drunk man will find his way home, but a drunk bird may get lost forever" (attributed to Shizuo Kakutani). Simple random walk on is recurrent but null recurrent: , and it has no stationary distribution.
Random walks on the integers
Each walk returns to 0 again and again, but the typical distance grows like √n — so the returns get rarer, which is why their expected number, though infinite, grows only like √n.
- 8 of the walks
- root-mean-square distance (300 walks)
- ±√n (exact)
Root-mean-square distance after 400 steps
Simulated20.48
Exact√400 ≈ 20
Simulation of 300 walks of 400 steps: root-mean-square distance 20.48. The exact value is √n, about 20.
Evidence, not proofThis is a simulation of 300 walks (run 1) using a seeded random number generator. It is evidence, not proof: the exact values come from mathematics, and a new run gives slightly different numbers.
Exactly: the average of (position)² after n steps is n, so the root-mean-square distance is √n. Going twice as far takes four times as many steps.
Stationary distributions
Theorem— Theorem (existence and uniqueness)
Every Markov chain on a finite state space has a stationary distribution. If the chain is irreducible, the stationary distribution is unique and for every .
Proof
Existence. Fix a distribution and consider the averages . They are distributions, which form a compact subset (a simplex) of , so a subsequence converges to a distribution . Now has entries of absolute value at most , so letting gives .
Positivity. If is stationary, then for all . Some ; for any , irreducibility gives with , and .
Uniqueness. First, every with (a harmonic function) is constant. Let , attained at . Since is an average of values that equals , every with has . So the set contains every state reachable in one step from any of its members, hence (by irreducibility) every state. Thus is spanned by the all-ones vector, and . A matrix and its transpose have the same rank, so the space of row vectors with is also one-dimensional. Two stationary distributions are therefore proportional, and since both sum to , they are equal.
∎
The unique stationary distribution has a probabilistic meaning: , the reciprocal of the mean return time (Kac's formula), and the ergodic theorem for Markov chains says that, for an irreducible finite chain and any starting distribution, the fraction of time spent in up to time tends to with probability — and more generally . (We state these without proof; see Norris, §1.7–1.10.) On infinite state spaces, an irreducible chain has a stationary distribution if and only if it is positive recurrent.
Solving is a linear system, but detailed balance is often easier: if for all , then , so is stationary (proved in Lean below). The random walk on a graph and the Ehrenfest urn were solved this way. Not every stationary distribution satisfies detailed balance: a chain that cycles with probability and goes backwards with probability has uniform but a net probability flow around the cycle.
Convergence to equilibrium
Theorem— Theorem (convergence theorem)
Let be irreducible and aperiodic on a finite state space with states, and let be its stationary distribution. Then there are and such that, for every initial distribution and every ,
In particular for all , exponentially fast.
The proof has three steps: a lemma from number theory, a positivity lemma, and Doeblin's contraction.
Theorem— Lemma 1 (numerical semigroups)
If is closed under addition and , then contains every sufficiently large integer.
Proof
The gcd of is the gcd of finitely many of its elements, so by Bézout there are and integers with . Let be the sum of the terms with and minus the sum of those with ; both are sums of elements of , hence in (if then and we are done), and . For , write with ; then with , so .
∎
Theorem— Lemma 2 (some power is positive)
If is irreducible and aperiodic on a finite set, there is with for all and all .
Proof
For each , is closed under addition (Chapman–Kolmogorov: ) and has gcd , so by Lemma 1 it contains all . Given , choose with ; then for . Take .
∎
Theorem— Lemma 3 (Doeblin's contraction)
Let be a stochastic matrix on states whose entries are all at least . Then for every row vector with , .
Proof
Since , , with . Hence .
∎
Proof of the theorem. Let with from Lemma 2 and (then , as rows sum to ). The vector sums to , and multiplying by a stochastic matrix keeps the sum at and never increases (the same computation with ). Writing and using ,
since .
Aperiodicity is necessary: for , alternates between and , although is stationary. For a periodic irreducible chain, the averages still converge to , and the "lazy" chain is aperiodic with the same .
The rate. Doeblin's bound is crude but universal. The true rate is governed by the eigenvalues of : is an eigenvalue (with right eigenvector ), all eigenvalues satisfy , and for an irreducible aperiodic chain all others satisfy ; decays like , where is the second-largest eigenvalue in modulus. For the two-state chain . The first experiment below compares the actual distance, and Doeblin's bound for a three-state weather chain.
Doeblin (1938) also invented the other classical proof, by coupling: run two copies of the chain, one from and one from , independently until they meet, and together afterwards; then . Coupling extends to countable state spaces, where the theorem holds for irreducible, aperiodic, positive recurrent chains.
Three applications
PageRank. Let be the random-surfer matrix of the web (follow a uniformly random link from the current page), and the matrix with every entry . Google's matrix , with damping in the original paper (Brin and Page, 1998), has every entry at least . So Doeblin's lemma applies with : repeated multiplication converges to the unique stationary distribution — the PageRank vector — with error shrinking by a factor per iteration, however large is.
Markov chain Monte Carlo. To sample from a distribution on a huge finite set known only up to a constant (a posterior distribution in statistics, a Gibbs distribution in physics), the Metropolis algorithm (Metropolis, Rosenbluth, Rosenbluth, Teller and Teller, 1953) proposes a move from a symmetric proposal and accepts it with probability . The resulting chain satisfies detailed balance with — only ratios are needed — so if it is irreducible and aperiodic, its distribution converges to , and ergodic averages estimate expectations under . How fast it mixes is the hard part.
Genetic drift. In the Wright–Fisher model, a population carries copies of a gene, of them of type A. Each copy in the next generation picks its parent uniformly at random, so given is Binomial. The states and are absorbing, all others transient, so one type is eventually lost. Since (the chain is a martingale), the probability that type A takes over is — a neutral mutation present in one copy fixes with probability . Selection and mutation modify the transition probabilities; see mathematical biology.
Markov chains in Lean and Mathlib
A finite chain is a matrix P : Matrix S S ℝ over a finite type S; a distribution is a row vector μ : S → ℝ, and one step is μ ᵥ* P. Mathlib provides the submonoid Matrix.rowStochastic ℝ S of stochastic matrices with its basic lemmas, and the general theory of Markov kernels on measurable spaces (ProbabilityTheory.Kernel, with irreducibility in Kernel.IsIrreducible). Classification of states, the strong Markov property and the ergodic theorem for chains are not yet in Mathlib.
Transition matrices. Products and powers of stochastic matrices are stochastic, and one step maps distributions to distributions:
/-- **The product of two transition matrices is a transition matrix.** If `P` and `Q` have
non-negative entries and rows summing to `1`, so does `PQ`: its entries `∑ₖ Pᵢₖ Qₖⱼ` are sums
of non-negative terms, and its row sums are
`∑ⱼ ∑ₖ Pᵢₖ Qₖⱼ = ∑ₖ Pᵢₖ ∑ⱼ Qₖⱼ = ∑ₖ Pᵢₖ = 1`. By Chapman–Kolmogorov, `PQ` is "first a step of
`P`, then a step of `Q`". -/
theorem stochastic_mul {P Q : Matrix S S ℝ}
(hP : (∀ i j, 0 ≤ P i j) ∧ ∀ i, ∑ j, P i j = 1)
(hQ : (∀ i j, 0 ≤ Q i j) ∧ ∀ i, ∑ j, Q i j = 1) :
(∀ i j, 0 ≤ (P * Q) i j) ∧ ∀ i, ∑ j, (P * Q) i j = 1 := by
refine ⟨fun i j => ?_, fun i => ?_⟩
· rw [mul_apply]
exact sum_nonneg fun k _ => mul_nonneg (hP.1 i k) (hQ.1 k j)
· simp only [mul_apply]
rw [sum_comm]
simp only [← mul_sum, hQ.2, mul_one]
exact hP.2 i/-- **n-step transition matrices are stochastic.** Mathlib's `Matrix.rowStochastic ℝ S` is a
submonoid of the matrix monoid, so it contains every power `Pⁿ` of its elements
(`Submonoid.pow_mem`). The entry `(Pⁿ)ᵢⱼ` is the probability of being at `j` after `n` steps
from `i`. -/
theorem stochastic_pow [DecidableEq S] {P : Matrix S S ℝ} (hP : P ∈ rowStochastic ℝ S) (n : ℕ) :
P ^ n ∈ rowStochastic ℝ S :=
Submonoid.pow_mem _ hP n/-- **One step of the chain maps distributions to distributions.** If `μ ≥ 0` sums to `1`, so
does `μ P`. These are Mathlib's `nonneg_vecMul_of_mem_rowStochastic` and
`vecMul_dotProduct_one_eq_one_rowStochastic` (`x ⬝ᵥ 1` is the sum of the entries of `x`). -/
theorem distribution_step [DecidableEq S] {P : Matrix S S ℝ} (hP : P ∈ rowStochastic ℝ S) {μ : S → ℝ}
(hμ0 : ∀ i, 0 ≤ μ i) (hμ1 : μ ⬝ᵥ 1 = 1) :
(∀ j, 0 ≤ (μ ᵥ* P) j) ∧ (μ ᵥ* P) ⬝ᵥ 1 = 1 :=
⟨nonneg_vecMul_of_mem_rowStochastic hP hμ0, vecMul_dotProduct_one_eq_one_rowStochastic hP hμ1⟩Stationarity. Detailed balance implies stationarity, on any finite state space:
/-- **Detailed balance implies stationarity.** If `πᵢ Pᵢⱼ = πⱼ Pⱼᵢ` for all states (the flow
of probability from `i` to `j` equals the flow back), and the rows of `P` sum to `1`, then
`π P = π`. Proof: `(πP)ⱼ = ∑ᵢ πᵢ Pᵢⱼ = ∑ᵢ πⱼ Pⱼᵢ = πⱼ ∑ᵢ Pⱼᵢ = πⱼ`. -/
theorem detailed_balance_stationary {P : Matrix S S ℝ} (hrow : ∀ i, ∑ j, P i j = 1)
{π : S → ℝ} (hdb : ∀ i j, π i * P i j = π j * P j i) : π ᵥ* P = π := by
funext j
simp only [vecMul, dotProduct]
simp_rw [hdb _ j]
rw [← mul_sum, hrow j, mul_one]The two-state chain, its stationary distribution, the closed form of by induction, and convergence of to :
/-- The general **two-state chain**: from state `0` jump with probability `a`, from state `1`
jump back with probability `b`. -/
def twoState (a b : ℝ) : Matrix (Fin 2) (Fin 2) ℝ :=
!![1 - a, a; b, 1 - b]/-- The two-state chain (with `a + b ≠ 0`) has stationary distribution
`π = (b/(a + b), a/(a + b))`: a direct computation of `π P`. -/
theorem two_state_stationary {a b : ℝ} (hab : a + b ≠ 0) :
![b / (a + b), a / (a + b)] ᵥ* twoState a b = ![b / (a + b), a / (a + b)] := by
funext j
fin_cases j <;>
· simp [twoState, vecMul, dotProduct, Fin.sum_univ_two]
field_simp
ring/-- **The n-step matrix of the two-state chain.** With `λ = 1 − a − b` (the second eigenvalue),
`(a + b) Pⁿ = [[b + a λⁿ, a − a λⁿ], [b − b λⁿ, a + b λⁿ]]`. Each row is the stationary
distribution plus a correction that decays like `λⁿ`. Proof: induction on `n`, using
`Pⁿ⁺¹ = Pⁿ P`. -/
theorem two_state_pow (a b : ℝ) (n : ℕ) :
(a + b) • twoState a b ^ n =
!![b + a * (1 - a - b) ^ n, a - a * (1 - a - b) ^ n;
b - b * (1 - a - b) ^ n, a + b * (1 - a - b) ^ n] := by
induction n with
| zero =>
ext i j
fin_cases i <;> fin_cases j <;> simp [add_comm]
| succ n ih =>
rw [pow_succ, ← smul_mul_assoc, ih]
ext i j
fin_cases i <;> fin_cases j <;>
· simp [twoState, mul_apply, Fin.sum_univ_two]
ring/-- **Convergence to equilibrium for two states.** If `|1 − a − b| < 1` (true whenever
`0 < a, b` and `a + b < 2`, i.e. the chain is irreducible and aperiodic), then the probability
of being in state `0` after `n` steps from state `0` tends to `π₀ = b/(a + b)`. Proof: by
`two_state_pow`, `(Pⁿ)₀₀ = (b + a λⁿ)/(a + b)` and `λⁿ → 0`. -/
theorem two_state_converges {a b : ℝ} (hab : a + b ≠ 0) (hlam : |1 - a - b| < 1) :
Tendsto (fun n : ℕ => (twoState a b ^ n) 0 0) atTop (𝓝 (b / (a + b))) := by
have hentry : ∀ n : ℕ, (twoState a b ^ n) 0 0 = (b + a * (1 - a - b) ^ n) / (a + b) := by
intro n
have h := congrFun (congrFun (two_state_pow a b n) 0) 0
have h' : (a + b) * (twoState a b ^ n) 0 0 = b + a * (1 - a - b) ^ n := by
simpa [Matrix.smul_apply] using h
rw [eq_div_iff hab, mul_comm]
exact h'
simp_rw [hentry]
have hpow : Tendsto (fun n : ℕ => (1 - a - b) ^ n) atTop (𝓝 0) :=
tendsto_pow_atTop_nhds_zero_of_abs_lt_one hlam
have := ((hpow.const_mul a).const_add b).div_const (a + b)
simpa using thisGambler's ruin. The fair solution and its uniqueness, the biased solution, and the expected duration:
/-- **Fair gambler's ruin.** Starting with `i` coins and betting one coin on fair coin flips
until reaching `0` or `N`, the probability `h(i)` of reaching `N` satisfies the first-step
equations `h(i) = ½ h(i − 1) + ½ h(i + 1)` with `h(0) = 0`, `h(N) = 1`. The function
`h(i) = i/N` is a solution. -/
theorem gambler_fair_solves {N : ℕ} (hN : 0 < N) (i : ℕ) :
((i + 1 : ℕ) : ℝ) / N = 1 / 2 * ((i : ℝ) / N) + 1 / 2 * (((i + 2 : ℕ) : ℝ) / N) := by
have : (N : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr hN.ne'
push_cast
field_simp
ring/-- **…and it is the only solution.** If `h(0) = 0`, `h(N) = 1` and
`h(i + 1) = 2h(i) − h(i − 1)` for `0 < i < N` (the first-step equation rearranged), then
`h(i) = i/N` for all `i ≤ N`. Proof: the increments `h(i + 1) − h(i)` are all equal, so
`h(i) = i·h(1)` by induction, and `h(N) = 1` forces `h(1) = 1/N`. -/
theorem gambler_fair_unique {N : ℕ} (hN : 0 < N) (h : ℕ → ℝ) (h0 : h 0 = 0) (hNv : h N = 1)
(hrec : ∀ i, 0 < i → i < N → h (i + 1) = 2 * h i - h (i - 1)) :
∀ i ≤ N, h i = i / N := by
-- First, `h i = i * h 1` for `i ≤ N`, proved together with the next value.
have key : ∀ i, i + 1 ≤ N → h i = i * h 1 ∧ h (i + 1) = (i + 1) * h 1 := by
intro i
induction i with
| zero => intro _; simp [h0]
| succ k ih =>
intro hk
obtain ⟨h1, h2⟩ := ih (by omega)
refine ⟨by push_cast; exact h2, ?_⟩
have := hrec (k + 1) (by omega) (by omega)
rw [this, show k + 1 - 1 = k by omega, h1, h2]
push_cast
ring
have hNR : (N : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr hN.ne'
have hN1 : h 1 = 1 / N := by
obtain ⟨_, hlast⟩ := key (N - 1) (by omega)
rw [show N - 1 + 1 = N by omega, hNv] at hlast
have : ((N - 1 : ℕ) : ℝ) + 1 = N := by
rw [Nat.cast_sub (by omega)]
push_cast
ring
rw [this] at hlast
field_simp
linarith
intro i hi
rcases Nat.lt_or_ge i N with hlt | hge
· rw [(key i (by omega)).1, hN1]
ring
· rw [show i = N by omega, hNv]
field_simp/-- **Biased gambler's ruin.** If each bet is won with probability `p` and lost with
probability `q = 1 − p`, with `r = q/p ≠ 1`, the probability of reaching `N` from `i` is
`h(i) = (1 − rⁱ)/(1 − rᴺ)`: it satisfies `h(i + 1) = p h(i + 2) + q h(i)` (first-step
analysis from `i + 1`), together with `h(0) = 0` and `h(N) = 1`. -/
theorem gambler_biased_solves {p : ℝ} (hp0 : 0 < p) (hp1 : p < 1) (hr : (1 - p) / p ≠ 1) {N : ℕ}
(hN : 0 < N) (i : ℕ) :
let r := (1 - p) / p
let h : ℕ → ℝ := fun k => (1 - r ^ k) / (1 - r ^ N)
h 0 = 0 ∧ h N = 1 ∧ h (i + 1) = p * h (i + 2) + (1 - p) * h i := by
intro r h
have hrpos : 0 ≤ r := div_nonneg (by linarith) hp0.le
have hrN : 1 - r ^ N ≠ 0 := by
intro h0
have hr1 : r ^ N = 1 := by linarith
exact hr ((pow_eq_one_iff_of_nonneg hrpos hN.ne').mp hr1)
refine ⟨by simp [h], by simp [h, div_self hrN], ?_⟩
have hq : 1 - p = r * p := by
simp only [r]
field_simp
have key : p * (1 - r ^ (i + 2)) + (1 - p) * (1 - r ^ i) = 1 - r ^ (i + 1) := by
linear_combination (r ^ i * (r - 1)) * hq
simp only [h]
rw [show p * ((1 - r ^ (i + 2)) / (1 - r ^ N)) + (1 - p) * ((1 - r ^ i) / (1 - r ^ N)) =
(p * (1 - r ^ (i + 2)) + (1 - p) * (1 - r ^ i)) / (1 - r ^ N) by ring, key]/-- **Expected duration of the fair game.** The expected number of bets `m(i)` until the
fair game ends satisfies `m(i) = 1 + ½ m(i − 1) + ½ m(i + 1)` with `m(0) = m(N) = 0`, and
`m(i) = i (N − i)` is a solution (shown here at `i + 1` for all `i`). Starting with `10`
coins and stopping at `0` or `20` takes `100` bets on average. -/
theorem duration_fair_solves (N i : ℝ) :
(i + 1) * (N - (i + 1)) = 1 + 1 / 2 * (i * (N - i)) + 1 / 2 * ((i + 2) * (N - (i + 2))) := by
ringDoeblin's contraction — Lemma 3 of the convergence theorem — and its iteration, which gives the geometric rate once some power of is positive:
/-- A step of a stochastic matrix preserves zero-sum vectors (such as the difference `μ − ν`
of two distributions): `∑ⱼ (xP)ⱼ = ∑ᵢ xᵢ ∑ⱼ Pᵢⱼ = ∑ᵢ xᵢ`. -/
theorem zero_sum_vecMul {P : Matrix S S ℝ} (hrow : ∀ i, ∑ j, P i j = 1) {x : S → ℝ}
(hx : ∑ i, x i = 0) : ∑ j, (x ᵥ* P) j = 0 := by
simp only [vecMul, dotProduct]
rw [sum_comm]
simp only [← mul_sum, hrow, mul_one]
exact hx/-- **Doeblin's contraction.** Let `P` be stochastic with every entry at least `δ`, on a state
space with `k` states. Then for every zero-sum vector `x`, `‖xP‖₁ ≤ (1 − kδ)‖x‖₁`.
Proof: since `∑ᵢ xᵢ = 0`, `(xP)ⱼ = ∑ᵢ xᵢ (Pᵢⱼ − δ)` with `Pᵢⱼ − δ ≥ 0`, so
`∑ⱼ |(xP)ⱼ| ≤ ∑ᵢ |xᵢ| ∑ⱼ (Pᵢⱼ − δ) = (1 − kδ) ∑ᵢ |xᵢ|`. Applied to `x = μ − ν`, two
distributions are pulled together by a factor `1 − kδ < 1` at every step. -/
theorem doeblin_contraction {P : Matrix S S ℝ} (hrow : ∀ i, ∑ j, P i j = 1) {δ : ℝ}
(hδ : ∀ i j, δ ≤ P i j) {x : S → ℝ} (hx : ∑ i, x i = 0) :
∑ j, |(x ᵥ* P) j| ≤ (1 - Fintype.card S * δ) * ∑ i, |x i| := by
have hshift : ∀ j, (x ᵥ* P) j = ∑ i, x i * (P i j - δ) := by
intro j
simp only [vecMul, dotProduct, mul_sub, sum_sub_distrib, ← sum_mul, hx, zero_mul, sub_zero]
calc ∑ j, |(x ᵥ* P) j| = ∑ j, |∑ i, x i * (P i j - δ)| := by simp_rw [hshift]
_ ≤ ∑ j, ∑ i, |x i| * (P i j - δ) := by
apply sum_le_sum
intro j _
refine (abs_sum_le_sum_abs _ _).trans (le_of_eq ?_)
refine sum_congr rfl fun i _ => ?_
rw [abs_mul, abs_of_nonneg (sub_nonneg.mpr (hδ i j))]
_ = ∑ i, |x i| * ∑ j, (P i j - δ) := by
rw [sum_comm]
simp only [mul_sum]
_ = (1 - Fintype.card S * δ) * ∑ i, |x i| := by
simp only [sum_sub_distrib, hrow, sum_const, card_univ, nsmul_eq_mul]
rw [mul_sum]
exact sum_congr rfl fun i _ => by ring/-- **Geometric convergence.** Iterating Doeblin's contraction (zero-sum vectors stay
zero-sum): `‖x Pⁿ‖₁ ≤ (1 − kδ)ⁿ ‖x‖₁`. With `x = μ − π` for a stationary `π`, the distribution
at time `n` approaches `π` exponentially fast. For a general irreducible aperiodic chain, apply
this to a power `Pᴺ` whose entries are all positive. -/
theorem doeblin_iterate [DecidableEq S] {P : Matrix S S ℝ} (hrow : ∀ i, ∑ j, P i j = 1) {δ : ℝ}
(hδ : ∀ i j, δ ≤ P i j) (hkδ : Fintype.card S * δ ≤ 1) {x : S → ℝ} (hx : ∑ i, x i = 0)
(n : ℕ) : ∑ j, |(x ᵥ* P ^ n) j| ≤ (1 - Fintype.card S * δ) ^ n * ∑ i, |x i| := by
have hz : ∀ m : ℕ, ∑ i, (x ᵥ* P ^ m) i = 0 := by
intro m
induction m with
| zero => simpa using hx
| succ m ihm =>
rw [pow_succ, ← vecMul_vecMul]
exact zero_sum_vecMul hrow ihm
induction n with
| zero => simp
| succ n ih =>
have hzero := hz n
rw [pow_succ, ← vecMul_vecMul]
calc ∑ j, |((x ᵥ* P ^ n) ᵥ* P) j| ≤ (1 - Fintype.card S * δ) * ∑ i, |(x ᵥ* P ^ n) i| :=
doeblin_contraction hrow hδ hzero
_ ≤ (1 - Fintype.card S * δ) * ((1 - Fintype.card S * δ) ^ n * ∑ i, |x i|) :=
mul_le_mul_of_nonneg_left ih (by linarith)
_ = (1 - Fintype.card S * δ) ^ (n + 1) * ∑ i, |x i| := by ringPólya in dimensions one and two. The bound from Mathlib, the divergence of , the sharper bound , and the divergence of :
/-- `4ⁿ ≤ (2n + 1) C(2n, n)`: the middle binomial coefficient is the largest of the `2n + 1`
coefficients `C(2n, k)`, which add up to `4ⁿ`. This is Mathlib's
`Nat.four_pow_le_two_mul_add_one_mul_centralBinom`. Since simple random walk on `ℤ` is back at
`0` at time `2n` with probability `C(2n, n)/4ⁿ`, that probability is at least `1/(2n + 1)`. -/
theorem central_binom_lower (n : ℕ) : 4 ^ n ≤ (2 * n + 1) * n.centralBinom :=
Nat.four_pow_le_two_mul_add_one_mul_centralBinom n/-- **Simple random walk on `ℤ` is recurrent.** The expected number of returns to `0` is
`∑ₙ P(S₂ₙ = 0) = ∑ₙ C(2n, n)/4ⁿ`, and this series diverges: each term is at least
`1/(2n + 1) ≥ 1/(2(n + 1))`, and the harmonic series diverges. By the recurrence criterion
(infinitely many expected returns ⇔ recurrent), the walk returns with probability `1`. -/
theorem walk_1d_returns_diverge :
¬ Summable (fun n : ℕ => (n.centralBinom : ℝ) / 4 ^ n) := by
intro hsum
-- Compare with `1/(2(n + 1))`.
have hle : ∀ n : ℕ, 1 / (2 * ((n : ℝ) + 1)) ≤ (n.centralBinom : ℝ) / 4 ^ n := by
intro n
have h := central_binom_lower n
have h' : (4 : ℝ) ^ n ≤ (2 * n + 1) * n.centralBinom := by exact_mod_cast h
rw [div_le_div_iff₀ (by positivity) (by positivity)]
nlinarith [pow_pos (show (0 : ℝ) < 4 by norm_num) n,
(Nat.cast_nonneg n.centralBinom : (0 : ℝ) ≤ _)]
have h2 : Summable (fun n : ℕ => 1 / (2 * ((n : ℝ) + 1))) :=
Summable.of_nonneg_of_le (fun n => by positivity) hle hsum
have h3 : Summable (fun n : ℕ => 1 / ((n + 1 : ℕ) : ℝ)) := by
have := h2.mul_left 2
refine this.congr fun n => ?_
push_cast
field_simp
exact Real.not_summable_one_div_natCast ((summable_nat_add_iff 1).mp h3)/-- `(C(2n, n)/4ⁿ)² ≥ 1/(4n)` for `n ≥ 1`. Proof by induction: `aₙ = C(2n, n)/4ⁿ` satisfies
`aₙ₊₁ = aₙ (2n + 1)/(2n + 2)` (Mathlib's `Nat.succ_mul_centralBinom_succ`), and
`(2n + 1)² ≥ 4n(n + 1)`. This sharper bound is what dimension two needs. -/
theorem central_binom_sq_lower (n : ℕ) (hn : 1 ≤ n) :
1 ≤ 4 * (n : ℝ) * ((n.centralBinom : ℝ) / 4 ^ n) ^ 2 := by
induction n, hn using Nat.le_induction with
| base => norm_num [Nat.centralBinom, Nat.choose]
| succ k hk ih =>
set a := (k.centralBinom : ℝ) / 4 ^ k
have hrec : ((k + 1).centralBinom : ℝ) / 4 ^ (k + 1) = a * (2 * k + 1) / (2 * k + 2) := by
have h := Nat.succ_mul_centralBinom_succ k
have h' : ((k : ℝ) + 1) * (k + 1).centralBinom = 2 * (2 * k + 1) * k.centralBinom := by
exact_mod_cast h
have hk1 : (k : ℝ) + 1 ≠ 0 := by positivity
simp only [a]
rw [pow_succ]
field_simp
have : ((k + 1).centralBinom : ℝ) = 2 * (2 * k + 1) * k.centralBinom / (k + 1) := by
field_simp
linarith
rw [this]
field_simp
ring
rw [hrec]
have hkR : (1 : ℝ) ≤ k := by exact_mod_cast hk
have hsq : 4 * (k : ℝ) * (k + 1) ≤ (2 * k + 1) ^ 2 := by nlinarith
have hpos : (0 : ℝ) < 2 * k + 2 := by positivity
push_cast
have hsimp : 4 * ((k : ℝ) + 1) * (a * (2 * k + 1) / (2 * k + 2)) ^ 2 =
a ^ 2 * (2 * k + 1) ^ 2 / (k + 1) := by
field_simp
ring
rw [hsimp, le_div_iff₀ (by positivity)]
have hchain : (2 * (k : ℝ) + 1) ^ 2 ≤ (2 * k + 1) ^ 2 * (4 * k * a ^ 2) := by
nlinarith [sq_nonneg (2 * (k : ℝ) + 1)]
nlinarith [hchain, hsq, hkR]/-- **Simple random walk on `ℤ²` is recurrent.** Rotating the lattice by 45° turns the planar
walk into two independent walks on `ℤ` (the coordinates `x + y` and `x − y`), so
`P(S₂ₙ = 0) = (C(2n, n)/4ⁿ)²`. These probabilities are not summable: from `n = 1` on they are
at least `1/(4n)`. (The rotation argument itself is in the lesson, not formalised.) -/
theorem walk_2d_returns_diverge :
¬ Summable (fun n : ℕ => ((n.centralBinom : ℝ) / 4 ^ n) ^ 2) := by
intro hsum
have hshift := (summable_nat_add_iff 1).mpr hsum
have hle : ∀ n : ℕ, 1 / 4 * (1 / ((n + 1 : ℕ) : ℝ)) ≤
(((n + 1).centralBinom : ℝ) / 4 ^ (n + 1)) ^ 2 := by
intro n
have h := central_binom_sq_lower (n + 1) (by omega)
have hn : (0 : ℝ) < ((n + 1 : ℕ) : ℝ) := by positivity
rw [show 1 / 4 * (1 / ((n + 1 : ℕ) : ℝ)) = 1 / (4 * ((n + 1 : ℕ) : ℝ)) by field_simp]
rw [div_le_iff₀ (by positivity)]
linarith
have h2 : Summable (fun n : ℕ => 1 / 4 * (1 / ((n + 1 : ℕ) : ℝ))) :=
Summable.of_nonneg_of_le (fun n => by positivity) hle hshift
have h3 : Summable (fun n : ℕ => 1 / ((n + 1 : ℕ) : ℝ)) :=
(summable_mul_left_iff (by norm_num : (1 / 4 : ℝ) ≠ 0)).mp h2
exact Real.not_summable_one_div_natCast ((summable_nat_add_iff 1).mp h3)What is and is not formalised. Proved here: stochasticity of products, detailed balance ⇒ stationarity, everything about the two-state chain, the gambler's-ruin formulas (and uniqueness in the fair case), Doeblin's contraction and its iteration, and the divergence of the expected number of returns in (as statements about the series and ). Cited from Mathlib: powers of stochastic matrices, one-step preservation of distributions, and the central binomial bound. Not formalised: the identification of and as return probabilities (including the rotation), the recurrence criterion, transience in , existence and uniqueness of stationary distributions, Lemmas 1 and 2, and the ergodic theorem.
Equilibrium, ruin and returns, computed
First, convergence to equilibrium: the exact stationary distribution of a three-state weather chain, the total-variation distance to it day by day, the eigenvalue rate and Doeblin's bound — and a periodic chain that never settles.
"""Convergence to equilibrium: a weather chain forgets where it started.
A three-state chain (dry, cloudy, rainy) has a strictly positive transition
matrix, so it is irreducible and aperiodic. We find its stationary
distribution exactly (rational arithmetic), then follow the distribution mu P^n
from a dry start and measure its total-variation distance to pi. The distance
falls geometrically, at the rate |lambda_2| of the second-largest eigenvalue,
and always below Doeblin's bound (1 - k delta)^n. A periodic chain, by
contrast, never settles down; making it "lazy" restores convergence.
"""
from fractions import Fraction
import numpy as np
STATES = ["dry", "cloudy", "rainy"]
WEATHER = [["3/5", "3/10", "1/10"],
["3/10", "2/5", "3/10"],
["1/5", "3/10", "1/2"]]
def as_fractions(matrix):
"""Convert a matrix of strings or numbers into Fractions."""
return [[Fraction(x) for x in row] for row in matrix]
def is_stochastic(matrix):
"""True if all entries are non-negative and every row sums to 1."""
return all(min(row) >= 0 and sum(row) == 1 for row in matrix)
def stationary_exact(matrix):
"""Solve pi P = pi, sum(pi) = 1 exactly by Gauss-Jordan elimination.
The equations are pi (P - I) = 0 with one equation replaced by the
normalisation; for an irreducible chain the solution is unique.
"""
p = as_fractions(matrix)
k = len(p)
# Unknowns pi_0..pi_{k-1}; equation j: sum_i pi_i (P_ij - [i = j]) = 0.
rows = [[p[i][j] - (1 if i == j else 0) for i in range(k)] + [Fraction(0)]
for j in range(k)]
rows[-1] = [Fraction(1)] * k + [Fraction(1)]
for col in range(k):
pivot = next(r for r in range(col, k) if rows[r][col] != 0)
rows[col], rows[pivot] = rows[pivot], rows[col]
rows[col] = [x / rows[col][col] for x in rows[col]]
for r in range(k):
if r != col and rows[r][col] != 0:
factor = rows[r][col]
rows[r] = [a - factor * b for a, b in zip(rows[r], rows[col])]
return [rows[i][k] for i in range(k)]
def tv_distance(mu, nu):
"""Total-variation distance: half the l1 distance."""
return 0.5 * float(np.abs(np.asarray(mu) - np.asarray(nu)).sum())
def distances(matrix, start, steps):
"""[TV(mu P^n, pi) for n = 0..steps] with mu = the point mass at start."""
p = np.array([[float(x) for x in row] for row in as_fractions(matrix)])
pi = np.array([float(x) for x in stationary_exact(matrix)])
mu = np.zeros(len(p))
mu[start] = 1.0
out = []
for _ in range(steps + 1):
out.append(tv_distance(mu, pi))
mu = mu @ p
return out
def second_eigenvalue(matrix):
"""Largest modulus among the eigenvalues other than 1."""
p = np.array([[float(x) for x in row] for row in as_fractions(matrix)])
moduli = sorted(np.abs(np.linalg.eigvals(p)), reverse=True)
return float(moduli[1])
def main():
pi = stationary_exact(WEATHER)
print("Weather chain: stationary distribution (exact)")
print(" " + ", ".join(f"{s} {x}" for s, x in zip(STATES, pi)))
lam2 = second_eigenvalue(WEATHER)
delta = min(min(as_fractions(WEATHER)[i]) for i in range(3))
factor = 1 - 3 * float(delta)
print(f" |lambda_2| = {lam2:.4f}; Doeblin factor 1 - k delta = {factor:.2f}")
print()
print(" n TV(mu P^n, pi) |lambda_2|^n Doeblin bound")
tv = distances(WEATHER, 0, 12)
for n in [0, 1, 2, 4, 6, 8, 10, 12]:
print(f"{n:>3} {tv[n]:>16.2e} {lam2 ** n:>14.2e} {factor ** n:>15.2e}")
print()
flip = [[0, 1], [1, 0]]
lazy = [["1/2", "1/2"], ["1/2", "1/2"]]
print("Periodic chain [[0, 1], [1, 0]] from state 0:",
[round(d, 2) for d in distances(flip, 0, 5)])
print("Lazy version (I + P)/2 from state 0: ",
[round(d, 2) for d in distances(lazy, 0, 5)])
print()
print("Epistemic status: pi is exact. The distances are floating-point")
print("values for one chain and one starting state; they illustrate the")
print("convergence theorem, the spectral rate and Doeblin's bound (proved")
print("in Lean), and the failure of convergence for a periodic chain.")
if __name__ == "__main__":
main()Next, gambler's ruin: the first-step equations solved in exact arithmetic, checked against the closed forms and against simulated games, for a fair coin and for betting on red at roulette.
"""Gambler's ruin: first-step analysis solved exactly, then checked by simulation.
A gambler with i coins bets one coin at a time, winning with probability p,
until she has N coins or none. The probability h(i) of reaching N and the
expected duration m(i) satisfy linear "first-step" equations. We solve these
tridiagonal systems exactly with fractions, compare with the closed-form
answers from the lesson, and then simulate the game. A fair game (p = 1/2) and
a slightly unfavourable one (p = 18/38, betting on red in roulette) behave
very differently.
"""
import random
from fractions import Fraction
def solve_tridiagonal(lower, diag, upper, rhs):
"""Solve a tridiagonal system exactly (Thomas algorithm with Fractions)."""
n = len(diag)
c, d = [Fraction(0)] * n, [Fraction(0)] * n
c[0] = Fraction(upper[0]) / diag[0] if n > 1 else Fraction(0)
d[0] = Fraction(rhs[0]) / diag[0]
for i in range(1, n):
denom = diag[i] - lower[i] * c[i - 1]
c[i] = Fraction(upper[i]) / denom if i < n - 1 else Fraction(0)
d[i] = (rhs[i] - lower[i] * d[i - 1]) / denom
x = [Fraction(0)] * n
x[-1] = d[-1]
for i in range(n - 2, -1, -1):
x[i] = d[i] - c[i] * x[i + 1]
return x
def first_step(p, n_target, durations=False):
"""Exact h(i) (or m(i)) for i = 0..N from the first-step equations.
For 0 < i < N: h(i) = p h(i+1) + q h(i-1), with h(0) = 0, h(N) = 1;
m(i) = 1 + p m(i+1) + q m(i-1), with m(0) = m(N) = 0.
"""
p = Fraction(p)
q = 1 - p
k = n_target - 1 # unknowns at 1..N-1
lower = [-q] * k
diag = [Fraction(1)] * k
upper = [-p] * k
if durations:
rhs = [Fraction(1)] * k
else:
rhs = [Fraction(0)] * k
rhs[-1] = p # the term p h(N) = p moved to the right-hand side
inner = solve_tridiagonal(lower, diag, upper, rhs)
boundary = Fraction(0) if durations else Fraction(1)
return [Fraction(0)] + inner + [boundary]
def ruin_formula(p, i, n_target):
"""Closed form: i/N if p = 1/2, else (1 - r^i)/(1 - r^N) with r = q/p."""
p = Fraction(p)
if p == Fraction(1, 2):
return Fraction(i, n_target)
r = (1 - p) / p
return (1 - r ** i) / (1 - r ** n_target)
def simulate(p, i, n_target, games, rng):
"""Fraction of games reaching N, and the mean number of bets."""
wins = total = 0
for _ in range(games):
x, steps = i, 0
while 0 < x < n_target:
x += 1 if rng.random() < p else -1
steps += 1
wins += x == n_target
total += steps
return wins / games, total / games
def main():
rng = random.Random(1654)
n_target, start, games = 20, 10, 4000
print(f"Start with {start} coins, stop at 0 or {n_target};"
f" {games} simulated games each")
for label, p in [("fair coin, p = 1/2", Fraction(1, 2)),
("roulette red, p = 18/38", Fraction(18, 38))]:
h = first_step(p, n_target)
m = first_step(p, n_target, durations=True)
assert h[start] == ruin_formula(p, start, n_target)
sim_h, sim_m = simulate(float(p), start, n_target, games, rng)
print(f"{label}:")
print(f" P(reach {n_target}): exact {float(h[start]):.4f}"
f" (formula agrees), simulated {sim_h:.4f}")
print(f" expected bets: exact {float(m[start]):.2f},"
f" simulated {sim_m:.2f}")
print()
fair_m = first_step(Fraction(1, 2), n_target, durations=True)
ok = all(fair_m[i] == i * (n_target - i) for i in range(n_target + 1))
print(f"Fair game: m(i) = i (N - i) for every i = 0..{n_target}: {ok}")
print("A house edge of 1/19 per bet cuts the chance of doubling 10 coins")
print("from 1/2 to about 1/4.")
print()
print("Epistemic status: the first-step solutions are exact rational")
print("numbers and agree with the closed forms for these parameters; the")
print("simulated frequencies are statistical evidence (standard error")
print("about 0.008 for the probabilities).")
if __name__ == "__main__":
main()Finally, Pólya's theorem in numbers: partial sums of return probabilities in one, two and three dimensions, and the fraction of simulated walks that come home.
"""Polya's theorem in numbers: does a random walk come home?
Simple random walk on Z^d returns to the origin with probability 1 when
d = 1 or 2 and with probability less than 1 when d = 3. The criterion is
whether the expected number of returns, sum_n P(S_2n = 0), is infinite. We
compute these return probabilities: exactly from C(2n, n)/4^n in d = 1 and its
square in d = 2, and from the trinomial formula in d = 3. The partial sums
grow like sqrt(n) and log(n) in d = 1 and 2, but level off in d = 3. A numpy
simulation of 1,000 walks of 1,000 steps adds the fraction that came back.
"""
import math
import numpy as np
def return_probs_1d(n_max):
"""[P(S_2n = 0) for n = 0..n_max] in d = 1, via a_(n+1) = a_n (2n+1)/(2n+2)."""
a = [1.0]
for n in range(n_max):
a.append(a[-1] * (2 * n + 1) / (2 * n + 2))
return a
def return_prob_3d(n):
"""P(S_2n = 0) in d = 3: (1/6^(2n)) C(2n, n) sum_(i+j+k=n) (n!/(i! j! k!))^2.
Computed with logarithms of factorials (math.lgamma).
"""
lf = [math.lgamma(m + 1) for m in range(2 * n + 1)]
log_c = lf[2 * n] - 2 * lf[n]
total = 0.0
for i in range(n + 1):
for j in range(n - i + 1):
k = n - i - j
total += math.exp(2 * (lf[n] - lf[i] - lf[j] - lf[k])
+ log_c - 2 * n * math.log(6))
return total
def simulate_returns(d, walks=1000, steps=1000, seed=1921):
"""Fraction of walks in Z^d that revisit the origin within ``steps``."""
rng = np.random.default_rng(seed + d)
axis = rng.integers(0, d, size=(walks, steps))
sign = rng.choice(np.array([-1, 1], dtype=np.int16), size=(walks, steps))
at_origin = np.ones((walks, steps), dtype=bool)
for c in range(d):
position = np.cumsum(np.where(axis == c, sign, 0), axis=1)
at_origin &= position == 0
return float(at_origin.any(axis=1).mean())
def main():
a = return_probs_1d(10000)
print("Expected number of returns up to time 2n: sum of P(S_2k = 0), k = 1..n")
print(f"{'n':>7} {'d = 1':>9} {'2 sqrt(n/pi)':>13} {'d = 2':>8}"
f" {'ln(n)/pi':>9}")
for n in [10, 100, 1000, 10000]:
s1 = sum(a[1:n + 1])
s2 = sum(x * x for x in a[1:n + 1])
print(f"{n:>7} {s1:>9.2f} {2 * math.sqrt(n / math.pi):>13.2f}"
f" {s2:>8.3f} {math.log(n) / math.pi:>9.3f}")
u3 = [return_prob_3d(n) for n in range(1, 61)]
print("d = 3: partial sums at n = 10, 20, 40, 60:",
", ".join(f"{sum(u3[:n]):.3f}" for n in [10, 20, 40, 60]))
tail = sum(2 * (3 / (4 * math.pi * n)) ** 1.5 for n in range(61, 200001))
print(f" plus the asymptotic tail estimate {tail:.3f}"
f" gives about {sum(u3) + tail:.3f}")
print(" (exact value 0.516..., so the return probability is")
print(" 0.516/1.516 = 0.34 < 1: the walk is transient)")
print()
print("Simulation: fraction of 1000 walks back at the origin by step 1000")
for d in [1, 2, 3]:
print(f" d = {d}: {simulate_returns(d):.3f}")
print()
print("Epistemic status: the return probabilities are computed exactly up")
print("to floating-point rounding, but a partial sum can never show that a")
print("series diverges; the divergence for d = 1, 2 is proved in Lean and")
print("convergence for d = 3 follows from P(S_2n = 0) <= C n^(-3/2). The")
print("simulation is statistical evidence about finite walks only.")
if __name__ == "__main__":
main()The stationary distributions and first-step solutions are exact; the distances and return probabilities are numerical (floating point); the simulations are statistical evidence. A partial sum can never prove that a series diverges — that is what the Lean proofs above are for.
Exercises
1. Markov chains
Warm-upHumanA Markov chain is often called memoryless. Which statement captures the Markov property?
2. Markov chains
Warm-upHumanA weather chain on (dry, cloudy, rainy) has transition matrix . Today is dry. What is the probability, in percent, that the day after tomorrow is dry?
3. Markov chains
CoreHumanFind the stationary distribution of .
4. Markov chains
CoreHumanIn the fair gambler's ruin game you start with coins and play one-coin fair bets until you have or coins. What is the expected number of bets?
5. Markov chains
CoreHumanA chain on has ; ; ; . Which statements are true? (Choose all that apply.)
6. Markov chains
CoreHumanThe lesson proves uniqueness of the stationary distribution by showing that every harmonic function () is constant. Where exactly is irreducibility used?
7. Markov chains
CoreHumanA walker moves on the vertices of a hexagon, stepping to each of the two neighbouring vertices with probability . What is the period of the chain?
8. Markov chains
StretchHumanWhich statement about simple random walk is correct?
9. Markov chains
CoreFormalWhich Lean statement formalises "detailed balance implies stationarity"? (π ᵥ* P is the row vector .)
10. Markov chains
StretchComputationalWrite step(mu, P) returning the row vector (lists of Fractions), and power_iterate(mu, P, n) applying step times. Then write is_stationary(pi, P). The tests use the two-state chain with , and check that approaches at the rate .
Common misconceptions
Misconception
"Memoryless means the chain forgets everything." The Markov property says that the future depends on the past only through the present: given , the earlier states carry no further information. The present state itself matters enormously — it is the whole of the chain's memory. And unconditionally, is usually strongly dependent on .
Misconception
"Every chain converges to its stationary distribution." Convergence of needs irreducibility (otherwise the limit depends on the starting class) and aperiodicity (otherwise the chain can cycle, as in the Ehrenfest urn or the flip chain ). On infinite state spaces positive recurrence is needed too: simple random walk on has no stationary distribution at all.
Misconception
"Recurrent means the chain comes back soon." A recurrent state is revisited with probability , but the expected return time can be infinite: for simple random walk on and , (null recurrence). Returns happen infinitely often, but ever more rarely.
Misconception
"A stationary distribution means the chain stops moving." At stationarity the distribution is constant in time; the chain itself keeps jumping. Stationarity is a balance of probability flows, , not a frozen state.
Misconception
"The fair gambler breaks even, so playing longer is harmless." In the fair game the expected fortune stays constant, yet against an opponent with unlimited resources ruin is certain, and the expected time to ruin is infinite. With any house edge, the probability of reaching a target falls exponentially with the target's distance.
Many ways of seeing
Algebra— Perron–Frobenius: the eigenvalue 1
A stochastic matrix has the eigenvalue with right eigenvector , and a stationary distribution is a left eigenvector for it with non-negative entries. The Perron–Frobenius theorem (Perron 1907, Frobenius 1912) describes non-negative matrices in general: an irreducible non-negative matrix has a positive eigenvalue equal to its spectral radius, with a one-dimensional eigenspace spanned by a positive vector; if it is moreover primitive (some power is positive — for stochastic matrices, irreducible and aperiodic), every other eigenvalue has modulus strictly less than . For stochastic , , and the theorem contains the existence, uniqueness and positivity of and the convergence theorem, with rate given by the spectral gap . A periodic irreducible chain of period has exactly the -th roots of unity as eigenvalues of modulus — the algebraic shadow of its cycling.
Topology— A fixed point in a simplex
The set of distributions on states is a simplex of dimension — a closed ball, topologically — and maps it continuously into itself. Brouwer's fixed-point theorem therefore guarantees a fixed point: a stationary distribution, for every finite chain, with no algebra at all. (Our existence proof replaced Brouwer by the more elementary averaging argument, which works because the map is affine — the Markov–Kakutani idea.) Uniqueness is not topological: a reducible chain can have a whole segment of fixed points. Topology also organises the state space itself: the communicating classes are the strongly connected components of the directed graph with an edge when , and closed classes are its sink components. See point-set topology.
Analysis— Contractions and the speed of mixing
Doeblin's lemma says that is a contraction of the simplex in the total-variation metric, so the convergence theorem is an instance of the Banach fixed-point theorem: a contraction of a complete metric space has a unique fixed point, and iterates converge to it geometrically. Quantitatively, the mixing time is studied with analytic tools — spectral gaps, isoperimetric (Cheeger) inequalities, and the comparison of Dirichlet forms . Some chains exhibit a sharp cutoff: riffle-shuffling a deck of cards stays far from random for a while and then becomes close to random within a few shuffles (Bayer and Diaconis, 1992, the source of the familiar "seven shuffles").
Physics— Detailed balance, entropy and the arrow of time
Detailed balance is the probabilistic form of microscopic reversibility in statistical mechanics: at thermal equilibrium every transition is balanced by its reverse. The Ehrenfests introduced their urn to resolve a paradox: Boltzmann's H-theorem says entropy increases, yet reversible dynamics return arbitrarily close to their initial state (Poincaré recurrence). In the urn both are true — the chain is recurrent, so it returns to "all balls in one urn", but the expected return time to that state is , astronomically long for , while from a typical state it drifts quickly towards the binomial bulk. In general the relative entropy is non-increasing in for every chain with stationary , a discrete second law of thermodynamics (see information theory). Metropolis's algorithm was invented to compute equilibrium properties of physical systems.
Combinatorics— Electrical networks and spanning trees
Random walks on graphs are combinatorial objects with a beautiful dictionary to electrical networks (Doyle and Snell, 1984): think of each edge as a unit resistor; the probability that a walk from hits before returning to is , and a walk on an infinite graph is recurrent exactly when the effective resistance to infinity is infinite. On that resistance grows like (recurrent); on it stays bounded (transient) — a second proof of Pólya's theorem. Stationary distributions of general chains also have a combinatorial formula, the Markov chain tree theorem: is proportional to the sum, over all spanning trees directed towards , of the products of the transition probabilities on their edges — a relative of Kirchhoff's matrix-tree theorem. See random geometry for where these ideas lead.
Category theory— Kernels compose
Transition matrices are morphisms in a category: sets with stochastic matrices (rows indexed by , distributions on ), composed by matrix multiplication — "first a step of , then a step of " — with identity matrices as identities. This is the finite part of the Kleisli category of the probability (Giry) monad described in probability theory, and a Markov chain is a functor from the monoid into it, sending to . Mathlib follows this pattern: ProbabilityTheory.Kernel composes like matrices, and Kernel.IsIrreducible defines irreducibility through the powers .
History and global context
- Markov and his predecessors. Andrei Andreyevich Markov introduced chains of dependent variables in 1906 to show that the law of large numbers (and later the central limit theorem) does not require independence — partly in response to Pavel Nekrasov's claim that it did — and in 1913 applied them to the sequence of vowels and consonants in Pushkin's Eugene Onegin. Earlier, the Ehrenfests' urn (1907) and Galton and Watson's study of the extinction of family names (1874) used Markovian ideas, and Bienaymé had analysed branching processes in 1845.
- Random walks. Karl Pearson posed the "problem of the random walk" in Nature in 1905 (Lord Rayleigh answered from his work in acoustics). Louis Bachelier (1900, modelling prices on the Paris Bourse) and Albert Einstein (1905, Brownian motion) independently linked random walks to diffusion. George Pólya proved his recurrence theorem in 1921, reportedly after noticing how often he met the same couple on walks in a park near Zürich.
- The general theory. Andrei Kolmogorov developed the theory of chains with countably many states (1936) and the analytic theory of continuous-time Markov processes (1931). Wolfgang Doeblin, working in Paris before his death in 1940, introduced coupling and the contraction condition that bears his name (1938); a sealed envelope he sent to the Académie des sciences, opened in 2000, showed he had anticipated parts of Itô's stochastic calculus. Oskar Perron and Georg Frobenius had meanwhile developed the theory of non-negative matrices (1907–12).
- Applications. Sewall Wright (1931) and Ronald Fisher (1930) built population genetics on the Wright–Fisher chain, later extended by Motoo Kimura's diffusion theory of neutral evolution (1968). Nicholas Metropolis, Arianna and Marshall Rosenbluth, and Augusta and Edward Teller introduced the Metropolis algorithm at Los Alamos in 1953; W. K. Hastings generalised it in 1970. Sergey Brin and Larry Page's PageRank (1998) made the stationary distribution of a Markov chain one of the most computed objects in the world.
Further reading
- J. R. Norris, Markov Chains (1997) — the standard rigorous introduction, in discrete and continuous time; the hitting-probability theorem and the treatment of recurrence follow it.
- Geoffrey Grimmett and David Stirzaker, Probability and Random Processes (4th edition, 2020), Chapter 6.
- David A. Levin and Yuval Peres (with Elizabeth Wilmer), Markov Chains and Mixing Times (2nd edition, 2017) — coupling, spectral methods and cutoff.
- Peter G. Doyle and J. Laurie Snell, Random Walks and Electric Networks (1984) — Pólya's theorem through electrical networks.
- Pierre Brémaud, Markov Chains: Gibbs Fields, Monte Carlo Simulation and Queues (2nd edition, 2020) — applications to physics, computation and queues.
- Eugene Seneta, Non-negative Matrices and Markov Chains (2nd edition, 1981) — the Perron–Frobenius theory.