Random functions of time
In 1827 the botanist Robert Brown watched particles from pollen grains in water under a microscope and saw them jitter ceaselessly, in no preferred direction. In 1900 Louis Bachelier, in a thesis on the Paris stock exchange, modelled prices by a process with independent Gaussian increments. In 1905 Albert Einstein, and independently Marian Smoluchowski, explained Brown's motion by molecular collisions and predicted that the mean square displacement grows linearly in time; Jean Perrin's measurements (1908–1909) confirmed it and fixed Avogadro's number, helping to settle the reality of atoms. Meanwhile the engineer Agner Krarup Erlang, designing the Copenhagen telephone exchange (1909), and the actuary Filip Lundberg, modelling insurance claims (1903), needed a model for events arriving "at random" in continuous time.
These are stochastic processes: random functions . They raise questions the previous lesson could not ask. What does it mean to choose a function at random? Which properties of a random path hold almost surely? And since Brownian paths turn out to be nowhere differentiable, how can one write — let alone solve — a differential equation driven by them? The answer to the last question, Itô's stochastic calculus (1944), is now used from population genetics to quantitative finance.
Two limits of coin tossing
Both basic processes are scaling limits of coin tossing.
Rare events. Divide into short slots and let an "arrival" occur in each slot independently with probability . The number of arrivals is binomial, and as it becomes Poisson with mean (the law of rare events). Counts in disjoint intervals are independent, and the waiting time for the next arrival does not care how long you have already waited. This is the Poisson process: a random step function that jumps by at random times.
Many small steps. Take a simple random walk and speed it up: steps of size every units of time. After time the position is a sum of independent steps of variance , so by the central limit theorem it is approximately . The limit is Brownian motion: a continuous random path with independent Gaussian increments. The scaling — space like the square root of time — is the source of everything strange about it. Over a time step the path moves about , far more than , so the path has no slope; but the squares of the increments add up to exactly the elapsed time. In the heuristic shorthand of stochastic calculus, . A second-order Taylor expansion therefore keeps a term that ordinary calculus discards:
This is Itô's formula. The rest of the lesson makes these heuristics into theorems.
Definitions
Definition— stochastic process, finite-dimensional distributions
A stochastic process on a probability space is a family of random variables indexed by time, or . Its finite-dimensional distributions are the laws of the vectors . For each , is a sample path. A filtration is an increasing family of sub-σ-algebras; is adapted if each is -measurable, and an adapted integrable is a martingale if almost surely for all .
The Kolmogorov extension theorem says that any consistent family of finite-dimensional distributions (consistent under permuting and forgetting coordinates) is the family of some process. It does not control paths: the event "the path is continuous" depends on uncountably many coordinates and is not even measurable in the product σ-algebra. Path regularity has to be constructed separately — for Brownian motion by Wiener's or Lévy's construction, or by the Kolmogorov–Chentsov continuity theorem.
Definition— Poisson process
A Poisson process of rate is a process with values in such that ; its paths are right-continuous, non-decreasing, and increase by jumps of size ; its increments over disjoint intervals are independent; and has the Poisson distribution with mean for :
Definition— continuous-time Markov chain
Let be a finite set. A generator (Q-matrix) on is a matrix with for and rows summing to ; write . The continuous-time Markov chain with generator sits in state for an exponential time with rate , then jumps to with probability , independently of the past. Its transition matrix is .
Definition— Brownian motion
A standard Brownian motion is a real process such that
- ;
- for the increments are independent;
- for , is normal with mean and variance ;
- almost every sample path is continuous.
A Gaussian process is one whose finite-dimensional distributions are all multivariate normal; it is determined in law by its mean and covariance .
Definition— simple integrands and the Itô integral
Let be a Brownian motion with filtration (for which is independent of ). A simple process on has the form for a partition , where each is bounded and -measurable — the integrand is decided at the left endpoint. Its Itô integral is
It extends by an limit (below) to all adapted, jointly measurable with .
Definition— Itô process, stochastic differential equation, quadratic variation
An Itô process is , written . A stochastic differential equation asks for an Itô process with and . The quadratic variation of a process over is the limit, if it exists, of as the mesh of the partition tends to .
The Poisson process
Theorem— Construction from exponential waiting times
Let be independent exponential random variables with rate (density on ), let be the -th arrival time and . Then:
- has the Gamma density on ;
- has the Poisson distribution with mean ;
- (memorylessness) for .
Proof
(1) By induction: is the exponential density, and since with independent summands, its density is the convolution .
(2) . For , exactly when . Since is independent of ,
(3) .
∎
Memorylessness characterises the exponential law among distributions on : if satisfies and is monotone with , then with (Cauchy's functional equation for ). It is also why the construction has independent, stationary increments: at any fixed time , the residual waiting time until the next arrival is again exponential with rate and independent of what happened before , so is a Poisson process independent of (Norris, Markov Chains, §2.4). In particular the counts must be consistent: a Poisson() count followed by an independent Poisson() count must total a Poisson() count.
Theorem— Poisson counts add
For and : . Equivalently, the sum of independent Poisson variables with means and is Poisson with mean .
Proof
, by the binomial theorem.
∎
Theorem— Law of rare events
If , then for every fixed .
Proof
Write . Also , so , and gives .
∎
Two further operations keep us inside the family (Kingman, Poisson Processes): the superposition of independent Poisson processes of rates and is a Poisson process of rate , and thinning — keeping each arrival independently with probability — turns a Poisson process of rate into one of rate , independent of the process of discarded arrivals.
Continuous-time Markov chains
Theorem— Kolmogorov's equations (finite state space)
Let be a generator on a finite set and . Then , , each is a stochastic matrix (non-negative entries, rows summing to ), and
Proof
The exponential series converges absolutely; because and commute, and differentiating the series termwise gives . Rows: (rows of sum to zero), so . Non-negativity: with , the matrix has non-negative entries, so does too, and (as commutes with ).
∎
One shows that the jump-and-hold chain of the definition has exactly these transition probabilities (Norris, §2.8): the backward equation comes from conditioning on the first jump, the forward equation from conditioning on the last. A distribution is stationary if for all , equivalently ; for an irreducible finite chain it is unique and as (no periodicity can arise in continuous time).
Example— The two-state chain
On with , and , the forward equation for reads : probability leaves at rate and returns at rate . With its solution is
The relaxation rate is the non-zero eigenvalue of .
The Poisson process is the chain on with . On infinite state spaces a new phenomenon appears: a pure birth chain with rates makes infinitely many jumps in finite time — it explodes — with probability one if (the expected total holding time is finite), and with probability zero if .
Brownian motion
Brownian motion exists. Wiener (1923) constructed its law on the space of continuous functions; Lévy gave a construction by successive dyadic interpolation with independent Gaussian corrections; alternatively, the finite-dimensional distributions exist by Kolmogorov's extension theorem, and since , the Kolmogorov–Chentsov theorem provides a modification whose paths are locally Hölder continuous of every order , hence of every order (Mörters–Peres, §1.1; Le Gall, Ch. 2).
Theorem— Brownian motion as a Gaussian process
A process with and continuous paths is a standard Brownian motion if and only if it is a Gaussian process with and .
Proof
() Any vector with is a linear image of the independent Gaussian increments, hence Gaussian with mean . For , independence of and gives .
() The increments over are jointly Gaussian. For , , and jointly Gaussian uncorrelated variables are independent. Finally .
∎
Theorem— Invariances
If is a standard Brownian motion, so are: (symmetry); for each (scaling); for each fixed , and it is independent of (Markov property); and (with value at ) (time inversion).
Proof
Each new process is a centred Gaussian process; by the previous theorem it suffices to compute covariances and check continuity. For scaling, . For time inversion with , . Continuity of at amounts to as , the Brownian strong law; it follows, for instance, from Doob's maximal inequality applied on dyadic blocks (Mörters–Peres, Ch. 1). The Markov property: the increments of are increments of over , independent of those over .
∎
Theorem— Brownian martingales
With respect to the natural filtration, , and (for each ) are martingales.
Proof
For write with independent of . Then ; ; and , using the Gaussian moment generating function.
∎
Theorem— Quadratic variation of Brownian motion
Let be partitions of with mesh . Then in .
Proof
Write and (dropping ). Then , so . The are independent with . Hence
∎
If (for instance dyadic partitions), Chebyshev and Borel–Cantelli upgrade this to almost-sure convergence.
Theorem— Brownian paths have infinite variation
Almost surely, the total variation of on (with ) is infinite.
Proof
Take the dyadic partitions of , along which almost surely. For every , . Each path is uniformly continuous on , so . If then , which happens only on a null set because almost surely.
∎
So Brownian paths are not of bounded variation, and cannot be defined path by path as a Riemann–Stieltjes integral. In fact much more is true.
Theorem— Nowhere differentiability (Paley–Wiener–Zygmund, 1933)
Almost surely, is differentiable at no point of .
Proof
This proof is due to Dvoretzky, Erdős and Kakutani (1961). Suppose is differentiable at some . Then there are and with for . Let and , so . For both and lie within of , and
So lies in for all large . The three increments are independent , and a density is at most , so each event in the intersection has probability at most . Hence
The set of paths differentiable somewhere in is therefore contained in , and for each .
∎
Finally, the reflection principle: for , . Reflect the path after the first time it hits ; by the strong Markov property the reflected path is again a Brownian motion (Mörters–Peres, §2.2).
Itô's stochastic calculus
Theorem— Itô isometry (simple integrands)
For a simple process on : and .
Proof
Let , independent of , with mean and variance . Since is -measurable, . Expanding the square, for the variable is -measurable, so . The diagonal terms give , and .
∎
The isometry says that is a linear isometry from simple processes, with the norm , into . Simple processes are dense in the space of adapted, jointly measurable with , so the integral extends uniquely, still isometric. The resulting process has a continuous modification which is a martingale (Karatzas–Shreve, §3.2). The choice of the left endpoint is what makes the integral a martingale: the integrand cannot anticipate the increment it multiplies.
Theorem— Integral of B dB
.
Proof
Fix partitions of with mesh and let . (These are not bounded, but they are square-integrable, which suffices for the isometry.) Then
so by the isometry in . On the other hand, the algebraic identity , summed over the partition (the discrete Itô formula, formalised in Lean below), gives
by the quadratic variation theorem.
∎
Ordinary calculus would predict . The extra is forced: the left side is a martingale with mean , and . With midpoints instead of left endpoints the sum telescopes to exactly : this is the Stratonovich integral , which obeys the ordinary chain rule but is not a martingale.
Theorem— Itô's formula
Let be continuously differentiable once in and twice in , and let be an Itô process. Then, almost surely for all ,
In particular .
About the proof. Expand by Taylor's theorem to first order in time and second order in space and sum over a partition. The first-order space terms converge to the stochastic integral, the second-order terms converge to by the same variance computation as for quadratic variation, and the remainders vanish because . A localisation argument removes boundedness assumptions (Karatzas–Shreve, §3.3; Le Gall, Ch. 5). The formula with and is exactly the previous theorem.
Example— Geometric Brownian motion
Consider with , the Black–Scholes model of a stock price. Guess with . Then , , , and Itô's formula gives
Since the coefficients are Lipschitz, this is the unique solution (Øksendal, Thm 5.2.1). Its behaviour is instructive. (the mean of a log-normal), but the median is , and since almost surely, . If , the expectation grows exponentially while almost every path tends to : the mean is carried by ever rarer, ever larger paths.
Example— The Ornstein–Uhlenbeck process
The Langevin equation () models the velocity of a particle with friction. Itô's formula for (here ) gives , so
The integral is Gaussian with mean and, by the isometry, variance . So converges in distribution to , the stationary law — in physics, the Maxwell distribution of velocities, with proportional to temperature.
Stochastic processes in Lean and Mathlib
Mathlib has no Itô integral yet, but the algebra that produces Itô's correction term can be formalised for any real sequence. The discrete Itô formula — left-point sums equal half the change of the square minus half the quadratic variation — is proved by induction, one line of ring per step:
/-- **The discrete Itô formula.** For any real sequence `S₀, S₁, …` the left-point sums satisfy
`∑_{k<n} Sₖ (Sₖ₊₁ − Sₖ) = (Sₙ² − S₀²)/2 − ½ ∑_{k<n} (Sₖ₊₁ − Sₖ)²`.
The last sum is the quadratic variation. For a smooth path it tends to `0` under refinement and we
recover `∫ S dS = (Sₙ² − S₀²)/2`; for Brownian motion it tends to `t`, which gives
`∫₀ᵗ B dB = (B_t² − t)/2`. Proof: induction on `n`; each step is the identity
`a (b − a) = (b² − a²)/2 − (b − a)²/2`. -/
theorem discrete_ito (S : ℕ → ℝ) (n : ℕ) :
∑ k ∈ Finset.range n, S k * (S (k + 1) - S k) =
(S n ^ 2 - S 0 ^ 2) / 2 - (∑ k ∈ Finset.range n, (S (k + 1) - S k) ^ 2) / 2 := by
induction n with
| zero => simp
| succ n ih =>
rw [Finset.sum_range_succ, Finset.sum_range_succ, ih]
ringWith midpoints the sum telescopes and the ordinary chain rule holds; for the simple random walk the quadratic variation is exactly , giving the discrete form of :
/-- **The discrete Stratonovich formula.** With midpoint values `(Sₖ + Sₖ₊₁)/2` instead of
left-point values, the sum telescopes exactly and the ordinary chain rule holds:
`∑_{k<n} (Sₖ + Sₖ₊₁)/2 · (Sₖ₊₁ − Sₖ) = (Sₙ² − S₀²)/2`. The two sums differ by half the quadratic
variation, so for Brownian paths the choice of evaluation point matters. -/
theorem discrete_stratonovich (S : ℕ → ℝ) (n : ℕ) :
∑ k ∈ Finset.range n, (S k + S (k + 1)) / 2 * (S (k + 1) - S k) = (S n ^ 2 - S 0 ^ 2) / 2 := by
induction n with
| zero => simp
| succ n ih =>
rw [Finset.sum_range_succ, ih]
ring/-- **Itô's formula for the simple random walk.** If `S₀ = 0` and every step is `±1`, the
quadratic variation after `n` steps is exactly `n`, so
`∑_{k<n} Sₖ (Sₖ₊₁ − Sₖ) = (Sₙ² − n)/2`. Rescaling space by `√n` and time by `n` turns this into
`∫₀¹ B dB = (B₁² − 1)/2`. Proof: the discrete Itô formula with `(±1)² = 1`. -/
theorem random_walk_ito (S : ℕ → ℝ) (h0 : S 0 = 0)
(hstep : ∀ k, S (k + 1) - S k = 1 ∨ S (k + 1) - S k = -1) (n : ℕ) :
∑ k ∈ Finset.range n, S k * (S (k + 1) - S k) = (S n ^ 2 - n) / 2 := by
have hqv : ∑ k ∈ Finset.range n, (S (k + 1) - S k) ^ 2 = n := by
rw [Finset.sum_congr rfl fun k _ => show (S (k + 1) - S k) ^ 2 = 1 by
rcases hstep k with h | h <;> rw [h] <;> norm_num]
simp
rw [discrete_ito, h0, hqv]
ringFor the Poisson process, we define the Poisson probabilities, check that they agree with the point masses of Mathlib's poissonMeasure, and prove the convolution identity from the binomial theorem, as in the human proof. Mathlib proves the measure-level statement through characteristic functions, and the law of rare events:
/-- The Poisson probabilities `pₖ(r) = e^{-r} rᵏ / k!`: the probability of exactly `k` arrivals
in a time interval of length `t` for a Poisson process of rate `λ`, with `r = λt`. -/
noncomputable def poissonPMF (r : ℝ) (k : ℕ) : ℝ :=
Real.exp (-r) * r ^ k / k.factorial/-- Our `poissonPMF` agrees with the point masses of Mathlib's Poisson distribution `Po(r)`
(`ProbabilityTheory.poissonMeasure_real_singleton`). -/
theorem poissonPMF_eq (r : ℝ≥0) (k : ℕ) : (poissonMeasure r).real {k} = poissonPMF r k :=
poissonMeasure_real_singleton r k/-- **Poisson counts add.** `∑_{j ≤ k} pⱼ(s) p_{k−j}(t) = pₖ(s + t)`: if `N_s` and `N_{s+t} − N_s`
are independent Poisson variables with means `s` and `t`, their sum is Poisson with mean
`s + t`. This is the consistency (Chapman–Kolmogorov) condition that makes the Poisson process
well defined. Proof: expand `(s + t)ᵏ` by the binomial theorem (`add_pow`) and write
`C(k, j) = k! / (j! (k − j)!)` (`Nat.cast_choose`). -/
theorem poisson_convolution (s t : ℝ) (k : ℕ) :
∑ j ∈ Finset.range (k + 1), poissonPMF s j * poissonPMF t (k - j) = poissonPMF (s + t) k := by
simp only [poissonPMF]
rw [add_pow, Finset.mul_sum, Finset.sum_div]
refine Finset.sum_congr rfl fun j hj => ?_
have hjk : j ≤ k := Nat.lt_succ_iff.mp (Finset.mem_range.mp hj)
rw [Nat.cast_choose ℝ hjk, neg_add, Real.exp_add]
have h1 : (j.factorial : ℝ) ≠ 0 := by positivity
have h2 : ((k - j).factorial : ℝ) ≠ 0 := by positivity
have h3 : (k.factorial : ℝ) ≠ 0 := by positivity
field_simp/-- Mathlib's measure-level statement of the same fact: the convolution of `Po(r₁)` and `Po(r₂)`
is `Po(r₁ + r₂)`, proved through characteristic functions
(`ProbabilityTheory.poissonMeasure_conv_poissonMeasure`). -/
theorem poisson_conv (r₁ r₂ : ℝ≥0) :
poissonMeasure r₁ ∗ poissonMeasure r₂ = poissonMeasure (r₁ + r₂) :=
poissonMeasure_conv_poissonMeasure r₁ r₂/-- **The law of rare events** (Poisson limit theorem). If `n pₙ → r`, the binomial
probabilities `C(n, k) pₙᵏ (1 − pₙ)^{n−k}` tend to `e^{-r} rᵏ / k!`. Chop `[0, t]` into `n` slots
with an arrival in each with probability `λt/n`: in the limit the count is Poisson. This is
Mathlib's `tendsto_choose_mul_pow_of_tendsto_mul_atTop`. -/
theorem law_of_rare_events {p : ℕ → ℝ} {r : ℝ} (k : ℕ)
(hr : Tendsto (fun n => n * p n) atTop (𝓝 r)) :
Tendsto (fun n => n.choose k * p n ^ k * (1 - p n) ^ (n - k)) atTop
(𝓝 (Real.exp (-r) * r ^ k / k.factorial)) :=
tendsto_choose_mul_pow_of_tendsto_mul_atTop k hrMemorylessness, from Mathlib's formula for the distribution function of expMeasure r, and the solution of the two-state forward equation (with HasDerivAt for the derivative):
/-- **Exponential waiting times are memoryless.** If `T` has the exponential distribution with
rate `r > 0`, then `P(T > s + t) = P(T > s) · P(T > t)` for `s, t ≥ 0`, i.e.
`P(T > s + t | T > s) = P(T > t)`: having waited `s` units tells you nothing. This is why the
holding times of a Poisson process (and of any continuous-time Markov chain) are exponential.
Proof: Mathlib's formula `F(x) = 1 − e^{−rx}` for the distribution function (`cdf_expMeasure_eq`)
and `e^{a+b} = eᵃ eᵇ`. -/
theorem exp_memoryless {r : ℝ} (hr : 0 < r) {s t : ℝ} (hs : 0 ≤ s) (ht : 0 ≤ t) :
1 - cdf (expMeasure r) (s + t) =
(1 - cdf (expMeasure r) s) * (1 - cdf (expMeasure r) t) := by
rw [cdf_expMeasure_eq hr, cdf_expMeasure_eq hr, cdf_expMeasure_eq hr]
simp only [add_nonneg hs ht, hs, ht, ite_true, sub_sub_cancel]
rw [← Real.exp_add]
ring_nf/-- **The two-state chain solves Kolmogorov's forward equation.** A chain on `{0, 1}` jumps
`0 → 1` at rate `a` and `1 → 0` at rate `b` (with `a + b > 0`). Its transition probability
`p(t) = P(X_t = 0 | X_0 = 0) = b/(a+b) + a/(a+b) · e^{−(a+b)t}` satisfies `p(0) = 1` and
`p′(t) = −a p(t) + b (1 − p(t))`: probability flows out of `0` at rate `a` and back in at rate
`b`. As `t → ∞`, `p(t) → b/(a+b)`, the stationary probability of state `0`. -/
theorem two_state_forward {a b : ℝ} (hab : 0 < a + b) (t : ℝ) :
(b / (a + b) + a / (a + b) * Real.exp (-(a + b) * 0) = 1) ∧
HasDerivAt (fun s => b / (a + b) + a / (a + b) * Real.exp (-(a + b) * s))
(-a * (b / (a + b) + a / (a + b) * Real.exp (-(a + b) * t)) +
b * (1 - (b / (a + b) + a / (a + b) * Real.exp (-(a + b) * t)))) t := by
have hne : a + b ≠ 0 := hab.ne'
constructor
· field_simp
simp
ring
· have hexp : HasDerivAt (fun s => Real.exp (-(a + b) * s))
(Real.exp (-(a + b) * t) * (-(a + b))) t := by
have := ((hasDerivAt_id t).const_mul (-(a + b))).exp
simpa using this
convert (hexp.const_mul (a / (a + b))).const_add (b / (a + b)) using 1
field_simp
ringMathlib defines Brownian motion as in the lesson: IsPreBrownianReal B P says that the finite-dimensional laws are those of Brownian motion (centred Gaussian with covariance ), and IsBrownianReal adds almost surely continuous paths. Time is indexed by ℝ≥0. It proves the covariance, the Gaussian increments, their independence, scaling and time inversion — the Gaussian-process theorem and the invariances above. (Mathlib proves these for any process with the right laws; we do not need an existence theorem for them.)
/-- **The covariance of Brownian motion** is `Cov(B_s, B_t) = min(s, t)`. Together with
`E[B_t] = 0` and Gaussian finite-dimensional laws this characterises (pre-)Brownian motion. This
is Mathlib's `IsPreBrownianReal.covariance_eval`. -/
theorem brownian_covariance {Ω : Type*} [MeasurableSpace Ω] {P : Measure Ω}
{B : ℝ≥0 → Ω → ℝ} (hB : IsPreBrownianReal B P) (s t : ℝ≥0) :
cov[B s, B t; P] = ((min s t : ℝ≥0) : ℝ) :=
hB.covariance_eval s t/-- **Brownian increments are Gaussian:** `B_s − B_t` has law `N(0, |s − t|)`. This is Mathlib's
`IsPreBrownianReal.hasLaw_sub`. -/
theorem brownian_increment {Ω : Type*} [MeasurableSpace Ω] {P : Measure Ω}
{B : ℝ≥0 → Ω → ℝ} (hB : IsPreBrownianReal B P) (s t : ℝ≥0) :
HasLaw (B s - B t) (gaussianReal 0 (nndist s.1 t.1)) P :=
hB.hasLaw_sub s t/-- **Brownian increments over disjoint intervals are independent.** This is Mathlib's
`IsPreBrownianReal.hasIndepIncrements`. -/
theorem brownian_indep_increments {Ω : Type*} [MeasurableSpace Ω] {P : Measure Ω}
{B : ℝ≥0 → Ω → ℝ} (hB : IsPreBrownianReal B P) : HasIndepIncrements B P :=
hB.hasIndepIncrements/-- **Brownian scaling.** If `B` is a Brownian motion and `c > 0`, then `t ↦ c^{−1/2} B_{ct}` is
again a Brownian motion: zooming in on a Brownian path by `c` in time and `√c` in space gives a
Brownian path. This is Mathlib's `IsBrownianReal.smul`. -/
theorem brownian_scaling {Ω : Type*} [MeasurableSpace Ω] {P : Measure Ω}
{B : ℝ≥0 → Ω → ℝ} (hB : IsBrownianReal B P) {c : ℝ≥0} (hc : c ≠ 0) :
IsBrownianReal (fun t ω => (√c)⁻¹ * B (c * t) ω) P :=
hB.smul hc/-- **Time inversion.** If `B` is a pre-Brownian motion, so is `t ↦ t B_{1/t}`. It converts
statements about `t → ∞` into statements about `t → 0`. This is Mathlib's
`IsPreBrownianReal.inv`. -/
theorem brownian_time_inversion {Ω : Type*} [MeasurableSpace Ω] {P : Measure Ω}
{B : ℝ≥0 → Ω → ℝ} (hB : IsPreBrownianReal B P) :
IsPreBrownianReal (fun t ω => t * B (1 / t) ω) P :=
hB.invFinally, geometric Brownian motion: we verify the derivatives that Itô's formula needs and the cancellation in the drift.
/-- The candidate solution of `dS = μ S dt + σ S dB`, written as a function of time `t` and of
the value `x = B_t` of the driving Brownian motion: `f(t, x) = S₀ exp((μ − σ²/2) t + σ x)`. -/
noncomputable def gbm (S₀ μ σ t x : ℝ) : ℝ :=
S₀ * Real.exp ((μ - σ ^ 2 / 2) * t + σ * x)/-- **The calculus behind geometric Brownian motion.** For `f = gbm S₀ μ σ`:
`∂ₓf = σ f`, `∂ₓₓf = σ² f`, `∂ₜf = (μ − σ²/2) f`, and hence `∂ₜf + ½ ∂ₓₓf = μ f`.
Itô's formula `df(t, B_t) = (∂ₜf + ½ ∂ₓₓf) dt + ∂ₓf dB_t` then gives
`dS_t = μ S_t dt + σ S_t dB_t` for `S_t = f(t, B_t)`: the `−σ²/2` in the exponent is exactly
cancelled by Itô's correction term `½ ∂ₓₓf`. (Itô's formula itself is not in Mathlib; this
theorem verifies the derivatives it needs.) -/
theorem gbm_ito (S₀ μ σ t x : ℝ) :
HasDerivAt (fun y => gbm S₀ μ σ t y) (σ * gbm S₀ μ σ t x) x ∧
HasDerivAt (fun y => σ * gbm S₀ μ σ t y) (σ ^ 2 * gbm S₀ μ σ t x) x ∧
HasDerivAt (fun s => gbm S₀ μ σ s x) ((μ - σ ^ 2 / 2) * gbm S₀ μ σ t x) t ∧
(μ - σ ^ 2 / 2) * gbm S₀ μ σ t x + σ ^ 2 * gbm S₀ μ σ t x / 2 = μ * gbm S₀ μ σ t x := by
-- derivative in the space variable
have hx : HasDerivAt (fun y => gbm S₀ μ σ t y) (σ * gbm S₀ μ σ t x) x := by
have h := (((hasDerivAt_id x).const_mul σ).const_add ((μ - σ ^ 2 / 2) * t)).exp.const_mul S₀
convert h using 1
· simp only [gbm, id]
· simp only [gbm, id]
ring
refine ⟨hx, ?_, ?_, by ring⟩
· convert hx.const_mul σ using 1
ring
· have h := ((((hasDerivAt_id t).const_mul (μ - σ ^ 2 / 2)).add_const (σ * x)).exp).const_mul S₀
convert h using 1
· simp only [gbm, id]
· simp only [gbm, id]
ringNot formalised here: the Itô integral and Itô's formula themselves, quadratic variation and nowhere differentiability of Brownian paths, the construction of the Poisson process from waiting times, and the matrix-exponential solution of Kolmogorov's equations. What is formalised is the exact algebra and calculus on which those limit arguments rest, together with Mathlib's genuine probabilistic theorems about Brownian motion and Poisson laws.
Experiments: Itô sums, Poisson arrivals, geometric Brownian motion
The first experiment follows one simulated Brownian path on through dyadic partitions with up to intervals. The left-point (Itô) sums of approach , the trapezoidal (Stratonovich) sums equal on every partition, the quadratic variation approaches , and the total variation grows like without bound.
"""Where Ito's extra term comes from: Riemann sums along one Brownian path.
We sample one Brownian path on [0, 1] at 2^16 equally spaced times (seeded
Gaussian increments) and evaluate, for coarser partitions, the left-point
sum (Ito), the average of the endpoint values (Stratonovich), the quadratic
variation and the total variation. The left sums approach (B_1^2 - 1)/2,
the trapezoidal sums equal B_1^2/2 exactly, the quadratic variation tends to
1 = t, and the total variation grows without bound like sqrt(2n/pi).
"""
import math
import random
def brownian_path(levels, rng):
"""B at times k / 2^levels, k = 0..2^levels, from Gaussian increments."""
n = 2 ** levels
sd = math.sqrt(1.0 / n)
path = [0.0]
for _ in range(n):
path.append(path[-1] + rng.gauss(0.0, sd))
return path
def subsample(path, step):
"""Every step-th value of the path (a coarser partition)."""
return path[::step]
def ito_sum(path):
"""Left-point sum of B dB: sum of B_k (B_(k+1) - B_k)."""
return math.fsum(a * (b - a) for a, b in zip(path, path[1:]))
def stratonovich_sum(path):
"""Trapezoidal sum: sum of (B_k + B_(k+1))/2 * (B_(k+1) - B_k)."""
return math.fsum((a + b) / 2 * (b - a) for a, b in zip(path, path[1:]))
def quadratic_variation(path):
"""Sum of squared increments."""
return math.fsum((b - a) ** 2 for a, b in zip(path, path[1:]))
def total_variation(path):
"""Sum of absolute increments."""
return math.fsum(abs(b - a) for a, b in zip(path, path[1:]))
def main():
levels = 16
path = brownian_path(levels, random.Random(1944))
b1 = path[-1]
print(f"One Brownian path on [0, 1]; B_1 = {b1:.5f}")
print(f"Targets: (B_1^2 - 1)/2 = {(b1 * b1 - 1) / 2:.5f},"
f" B_1^2/2 = {b1 * b1 / 2:.5f}")
print(" n Ito sum Stratonovich quad. var. total var.")
for m in [2, 4, 6, 8, 10, 12, 14, 16]:
p = subsample(path, 2 ** (levels - m))
print(f" {2 ** m:>5} {ito_sum(p):>9.5f} {stratonovich_sum(p):>10.5f}"
f" {quadratic_variation(p):>9.5f} {total_variation(p):>9.2f}")
p = path
gap = stratonovich_sum(p) - ito_sum(p) - quadratic_variation(p) / 2
print(f"Stratonovich - Ito - QV/2 on the finest grid: {gap:.1e}")
print(f"sqrt(2n/pi) for n = 2^16: {math.sqrt(2 * 2 ** 16 / math.pi):.2f}")
print("The Stratonovich sum telescopes to B_1^2/2 on every partition; the")
print("Ito sum differs from it by half the quadratic variation, which")
print("tends to t = 1. Unbounded total variation is why no ordinary")
print("(Riemann-Stieltjes) integral against B exists.")
print()
print("Epistemic status: floating-point computation on a single seeded")
print("pseudo-random path and finitely many partitions. The identities")
print("between the sums are exact algebra (formalised in Lean); the limits")
print("are theorems (quadratic variation of Brownian motion), illustrated")
print("here, not proved.")
if __name__ == "__main__":
main()The second builds a Poisson process from exponential waiting times and compares the counts with the Poisson law, the covariance of counts on disjoint intervals with , and the conditional waiting time with the unconditional one.
"""Building a Poisson process from exponential waiting times.
Arrivals of rate lam = 2 are generated by adding independent exponential
waiting times (seeded). We count the arrivals in [0, 3] over many runs and
compare the frequencies with the Poisson(6) probabilities, check that the
counts in [0, 1] and (1, 3] are uncorrelated (independent increments), test
the memoryless property of the waiting time, and verify the convolution
identity Po(s) * Po(t) = Po(s + t) term by term.
"""
import math
import random
def poisson_pmf(r, k):
"""e^(-r) r^k / k!"""
if r < 0 or k < 0:
raise ValueError("need r >= 0 and k >= 0")
return math.exp(-r) * r ** k / math.factorial(k)
def arrival_times(lam, horizon, rng):
"""Arrival times in [0, horizon] from i.i.d. exponential gaps."""
times, t = [], rng.expovariate(lam)
while t <= horizon:
times.append(t)
t += rng.expovariate(lam)
return times
def count_in(times, a, b):
"""Number of arrivals in the interval (a, b]."""
return sum(1 for t in times if a < t <= b)
def convolution_gap(s, t, k):
"""|sum_j p_j(s) p_(k-j)(t) - p_k(s + t)|."""
total = math.fsum(poisson_pmf(s, j) * poisson_pmf(t, k - j)
for j in range(k + 1))
return abs(total - poisson_pmf(s + t, k))
def main():
lam, runs = 2.0, 20000
rng = random.Random(1909)
firsts, seconds, totals, first_gap = [], [], [], []
for _ in range(runs):
times = arrival_times(lam, 3.0, rng)
firsts.append(count_in(times, 0.0, 1.0))
seconds.append(count_in(times, 1.0, 3.0))
totals.append(len(times))
first_gap.append(times[0] if times else math.inf)
print(f"{runs} runs, rate 2, arrivals in [0, 3] versus Poisson(6):")
print(" k simulated Poisson(6)")
for k in [0, 2, 4, 6, 8, 10, 12]:
freq = totals.count(k) / runs
print(f" {k:>2} {freq:.4f} {poisson_pmf(6.0, k):.4f}")
mean = sum(totals) / runs
var = sum((x - mean) ** 2 for x in totals) / runs
print(f"mean {mean:.3f}, variance {var:.3f} (both 6 in theory)")
m1, m2 = sum(firsts) / runs, sum(seconds) / runs
cov = sum((a - m1) * (b - m2) for a, b in zip(firsts, seconds)) / runs
print(f"Cov(N(0,1], N(1,3]) = {cov:.4f} (0 for independent increments)")
t_wait = [x for x in first_gap if x > 0.5]
cond = sum(1 for x in t_wait if x > 1.0) / len(t_wait)
plain = sum(1 for x in first_gap if x > 0.5) / runs
print(f"P(T > 1 | T > 0.5) = {cond:.4f}, P(T > 0.5) = {plain:.4f},"
f" exact e^-1 = {math.exp(-1):.4f}")
worst = max(convolution_gap(1.3, 2.4, k) for k in range(30))
print(f"max |Po(1.3) * Po(2.4) - Po(3.7)| over k < 30: {worst:.1e}")
print()
print("Epistemic status: the frequencies, covariance and conditional")
print("probability come from seeded simulations (statistical evidence,")
print("with errors of order 1/sqrt(runs) = 0.007). The convolution check")
print("is floating point; the identity is proved exactly in the lesson and")
print("in Lean.")
if __name__ == "__main__":
main()The third solves numerically by the Euler–Maruyama scheme and compares it, on the same Brownian increments, with Itô's exact solution: the error shrinks like (strong order ). The "ordinary chain rule" solution has the wrong mean.
"""Geometric Brownian motion: Ito's correction is real.
We simulate dS = mu S dt + sigma S dB with mu = 0.1, sigma = 0.4, S_0 = 1 on
[0, 1] by the Euler-Maruyama scheme and compare it, path by path, with the
exact solution S_1 = exp((mu - sigma^2/2) + sigma B_1) driven by the same
Brownian increments. The strong error shrinks like sqrt(dt). The sample mean
matches e^mu, the sample median matches e^(mu - sigma^2/2), and the "ordinary
chain rule" guess exp(mu + sigma B_1) has the wrong mean e^(mu + sigma^2/2).
"""
import math
import random
import statistics
MU, SIGMA = 0.1, 0.4
def exact_solution(s0, mu, sigma, t, b):
"""Ito's solution S_t = s0 exp((mu - sigma^2/2) t + sigma B_t)."""
return s0 * math.exp((mu - sigma ** 2 / 2) * t + sigma * b)
def euler_maruyama(s0, mu, sigma, increments, dt):
"""Iterate S <- S + mu S dt + sigma S dB over the given increments."""
s = s0
for db in increments:
s += mu * s * dt + sigma * s * db
return s
def coarsen(increments, factor):
"""Sum consecutive blocks of increments (same path, coarser grid)."""
return [math.fsum(increments[i:i + factor])
for i in range(0, len(increments), factor)]
def main():
rng = random.Random(1973)
paths, fine = 1000, 2 ** 8
incs = [[rng.gauss(0.0, math.sqrt(1 / fine)) for _ in range(fine)]
for _ in range(paths)]
finals = [math.fsum(inc) for inc in incs]
exact = [exact_solution(1.0, MU, SIGMA, 1.0, b) for b in finals]
print("Strong error E|S_1(Euler) - S_1(exact)| on the same paths:")
print(" steps dt error error/sqrt(dt)")
for m in [2, 4, 6, 8]:
n = 2 ** m
errs = [abs(euler_maruyama(1.0, MU, SIGMA, coarsen(inc, fine // n),
1 / n) - ex)
for inc, ex in zip(incs, exact)]
err = statistics.fmean(errs)
print(f" {n:>5} {1 / n:.5f} {err:.5f} {err / math.sqrt(1 / n):.4f}")
print()
naive = [math.exp(MU + SIGMA * b) for b in finals]
print(f"Sample mean of exact S_1: {statistics.fmean(exact):.4f}"
f" (theory e^mu = {math.exp(MU):.4f})")
print(f"Sample median of exact S_1: {statistics.median(exact):.4f}"
f" (theory e^(mu - s^2/2) = {math.exp(MU - SIGMA ** 2 / 2):.4f})")
print(f"Mean of naive exp(mu + s B_1): {statistics.fmean(naive):.4f}"
f" (= e^(mu + s^2/2) = {math.exp(MU + SIGMA ** 2 / 2):.4f}, wrong)")
print("The ordinary chain rule would predict the naive formula; Ito's")
print("formula adds -sigma^2/2 to the exponent, and only then is the mean")
print("e^(mu t), as dS = mu S dt + sigma S dB requires.")
print()
print("Epistemic status: seeded simulations with 1000 paths (statistical")
print("evidence; sample means carry errors of a few percent) and floating")
print("point. The rate dt^(1/2) and the formulas are theorems; the run")
print("illustrates them.")
if __name__ == "__main__":
main()These are simulations: statistical and numerical evidence for finitely many paths and partitions. The exact identities between the sums are proved in Lean; the limits are the theorems above.
Random walks, the heat kernel and the log-normal
Many random walks at once: the root-mean-square distance grows like , the diffusive scaling that becomes in the limit.
Diffusive scaling: distance grows like √n
Each walker steps left or right at random. The typical distance from the start grows like √n.
- 8 of the walks
- root-mean-square distance (500 walks)
- ±√n (exact)
Root-mean-square distance after 400 steps
Simulated20.08
Exact√400 ≈ 20
Simulation of 500 walks of 400 steps: root-mean-square distance 20.08. The exact value is √n, about 20.
Evidence, not proofThis is a simulation of 500 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.
The law of has density , the heat kernel: it solves . Move and watch the heat spread; the area under the curve stays .
The heat kernel: the law of Brownian motion at time t
Move the sliders and trace along the curves to read off values.
- density of B_t
- Signed area: above the axis counts as positive, below (hatched) as negative
- density of B_t: y = 0.2076
For geometric Brownian motion with , compare the mean with the median . Choose and slide past : the median turns downward while the mean keeps rising.
Geometric Brownian motion: mean versus median
Move the sliders and trace along the curves to read off values.
- mean E S_t = e^(μt)
- median e^((μ − σ²/2)t)
- mean E S_t = e^(μt): y = 1.0513
- median e^((μ − σ²/2)t): y = 0.9704
Exercises
1. Stochastic processes
Warm-upHumanLet be a standard Brownian motion. Compute .
2. Stochastic processes
Warm-upHumanRequests reach a server in Nairobi as a Poisson process of rate per minute. Given that exactly requests arrived in the first minutes, what is the expected number of requests in the first minutes?
3. Stochastic processes
CoreHumanWhich of these processes are martingales with respect to the natural filtration of a standard Brownian motion ? Select all that apply.
4. Stochastic processes
CoreHumanCompute .
5. Stochastic processes
CoreHumanWhich equation is correct for ?
6. Stochastic processes
CoreHumanA geometric Brownian motion has and , so . Which statement is true as ?
7. Stochastic processes
CoreHumanThe proof that Brownian paths have infinite variation uses along dyadic partitions of . Which property of Brownian motion guarantees for each path?
8. Stochastic processes
CoreFormalFor a real sequence S : ℕ → ℝ, which Lean statement is the discrete Itô formula proved in the lesson?
9. Stochastic processes
StretchHumanA pure birth chain on jumps from to at rate (so the holding time in state is exponential with mean ). For which rate sequences does the chain make infinitely many jumps in finite time (explode) with probability one? Select all that apply.
10. Stochastic processes
CoreComputationalA path is given by its values path = [S_0, S_1, ..., S_n] on a partition. Write ito_sum(path) (left-point sum of ), stratonovich_sum(path) (midpoint sum, with ) and quadratic_variation(path). The tests check them on exact rational paths and verify the discrete Itô and Stratonovich formulas.
Common misconceptions
Misconception
"The chain rule of calculus applies to Itô integrals." It does not: , not , and . The extra term comes from the quadratic variation, , which vanishes for smooth paths but not for Brownian ones. The ordinary chain rule holds for the Stratonovich integral, at the price of losing the martingale property.
Misconception
"Brownian paths are continuous, so they must be differentiable almost everywhere." Continuity does not imply differentiability anywhere (Weierstrass's function is an example), and monotone or bounded-variation functions are the ones that are differentiable almost everywhere (Lebesgue). Brownian paths have infinite variation on every interval and are differentiable at no point, almost surely. Velocity is not defined, which is why physicists' "white noise" makes sense only as a generalised function.
Misconception
"A Poisson process spreads its arrivals out evenly." Arrivals cluster: the gaps are exponential, whose most likely values are near . Given , the arrival times are distributed like independent uniform points on sorted in order — and uniform random points form clumps and gaps. Regular spacing would be a sign that the process is not Poisson.
Misconception
"If grows, the typical path grows." For geometric Brownian motion with , while almost surely. Expectations can be dominated by rare events; almost-sure statements describe the typical path.
Misconception
"Every martingale is a Markov process", or the reverse. is a Markov process but not a martingale. Conversely, a fair-coin walk whose step size ( or ) is fixed once and for all by the direction of its first step is a martingale but not a Markov process: its current position alone does not tell you how far it will move next (position at time can be reached with either step size). The two notions describe different kinds of memory.
Many ways of seeing
Analysis— Generators, the heat equation and harmonic functions
Every Markov process has an infinitesimal generator ; for a finite chain it is the matrix , and for Brownian motion it is . The transition semigroup solves the heat equation with , and Itô's formula shows that is a martingale. Consequences flow both ways. Kakutani (1944): the solution of the Dirichlet problem in a domain with boundary values is , where is the exit time from . The Feynman–Kac formula (Kac, 1949) represents solutions of as . See partial differential equations.
Geometry— Brownian motion on manifolds, and conformal invariance
On a Riemannian manifold, Brownian motion is the diffusion with generator , the Laplace–Beltrami operator; its transition density is the heat kernel of the manifold, and the short-time asymptotics recover the geodesic distance from the random motion (Varadhan, 1967). Curvature appears in how fast Brownian particles spread: on hyperbolic space they escape to infinity at linear speed, on a compact manifold they equidistribute. In the plane there is a hidden symmetry: Lévy's conformal invariance theorem says that if is a non-constant analytic function, then is again a planar Brownian motion, run with the random clock . Planar Brownian motion thus sees only the conformal structure — which is why it connects to complex analysis and, through Schramm–Loewner evolution, to the scaling limits of planar statistical mechanics. See Riemannian geometry.
Topology— A measure on path space, and winding around a point
Wiener measure is a Borel probability measure on the Polish space of continuous paths with the topology of uniform convergence on compacts. It is concentrated on paths that are Hölder continuous of every order and of no order — a topologically meagre subset of path space carrying full measure. Donsker's invariance principle (1951) is a statement of weak convergence in this space: rescaled random walk paths converge in law to Brownian motion, so continuous functionals such as can be computed from simple random walks. Planar Brownian motion started at never hits (points are polar in dimension two), so its winding angle around is well defined, and Spitzer's theorem (1958) says that converges in distribution to a standard Cauchy law: the path winds around the origin endlessly, in both directions. See the fundamental group.
Physics— Diffusion, atoms and friction
Einstein (1905) argued that a suspended particle of radius in a fluid of viscosity at temperature diffuses with in each coordinate, where ; measuring therefore measures Boltzmann's constant , and with it Avogadro's number. Perrin's experiments did exactly this. Langevin (1908) wrote Newton's law with friction and a random force, : the Ornstein–Uhlenbeck process, whose stationary variance must equal — a fluctuation–dissipation relation. Physicists' white noise "" is heuristic: Wong and Zakai (1965) showed that ordinary differential equations driven by smooth approximations of white noise converge to the Stratonovich solution, which is why physicists often prefer Stratonovich calculus and mathematicians Itô's.
Combinatorics— Counting paths: reflection and the ballot problem
Behind Brownian identities stand exact counts of lattice paths. The reflection principle for simple random walk — reflect the path after its first visit to level — gives the number of paths of length from to that touch as the number of all paths from to . It solves the ballot problem (Bertrand, 1887): if candidate A receives votes and B receives , counted in random order, the probability that A is strictly ahead throughout the count is . Passing to the diffusive limit turns these counts into and the arcsine laws for the time spent positive (Lévy). See Markov chains and random structures.
Wonder Trails
History and context
- Siméon Denis Poisson (1837) derived his distribution as a limit of binomials; Ladislaus von Bortkiewicz (1898) famously fitted it to deaths from horse kicks in the Prussian cavalry. Filip Lundberg (1903) and Agner Krarup Erlang (1909) used Poisson arrivals for insurance risk and telephone traffic.
- Thorvald Thiele (1880) and Louis Bachelier (1900) described Brownian motion mathematically; Albert Einstein (1905), Marian Smoluchowski (1906) and Paul Langevin (1908) gave its physics, and Jean Perrin (1908–1909) its experimental confirmation (Nobel Prize 1926).
- Norbert Wiener (1923) constructed Brownian motion as a measure on path space; Raymond Paley, Wiener and Antoni Zygmund (1933) proved nowhere differentiability; Andrey Kolmogorov (1931) founded the analytic theory of Markov processes with his forward and backward equations; Paul Lévy (Processus stochastiques et mouvement brownien, 1948) discovered most of the fine path properties.
- Kiyosi Itô (1944, 1951) defined the stochastic integral and proved his formula, building a theory of stochastic differential equations; in 2006 he received the first Gauss Prize. Wolfgang Doeblin, killed in 1940, had sent a sealed envelope to the Paris Academy containing a version of Itô's formula; it was opened in 2000. Joseph Doob (1953) put continuous-time martingales at the centre; William Feller developed the semigroup theory of diffusions; Ruslan Stratonovich (1966) introduced his integral.
- Fischer Black, Myron Scholes and Robert Merton (1973) priced options with geometric Brownian motion and Itô's formula (Nobel Prize in Economics 1997 for Merton and Scholes). Stochastic analysis now underlies population genetics (Kimura's diffusions), filtering and control, statistical physics and the study of random geometry.
Further reading
- Ioannis Karatzas and Steven E. Shreve, Brownian Motion and Stochastic Calculus (2nd ed., 1991) — the standard rigorous treatment.
- Bernt Øksendal, Stochastic Differential Equations: An Introduction with Applications (6th ed., 2003) — the friendliest route to Itô calculus and SDEs.
- Peter Mörters and Yuval Peres, Brownian Motion (2010) — path properties, with modern proofs.
- Jean-François Le Gall, Brownian Motion, Martingales, and Stochastic Calculus (2016) — concise and complete.
- James R. Norris, Markov Chains (1997) — discrete and continuous time, Poisson processes, with clear proofs.
- J. F. C. Kingman, Poisson Processes (1993) — the geometry and calculus of Poisson point processes.
- J. Michael Steele, Stochastic Calculus and Financial Applications (2001) — Itô calculus motivated by finance.