Brownian Bridge

Brownian Bridge

Recipes for simulating the Brownian bridge process in both continuous and discrete time.

Simulating the Brownian Bridge

Continuous-time Recipe for Brownian Bridge

Intuition

The Brownian bridge is a Brownian motion conditioned to return to zero at time 1. Its covariance kernel is $$ K(s, t) = \min(s, t) - s t $$ The Karhunen–Loève expansion gives $$ B_t = \sqrt{2} \sum_{k=1}^\infty Z_k \frac{\sin(k \pi t)}{k \pi} $$ where \( Z_k \sim \mathcal{N}(0, 1) \) are independent.

General Recipe

  1. Define the process and covariance kernel \( K(s, t) = \min(s, t) - s t \).
  2. Set up and solve the integral eigenvalue problem: $$ \int_0^1 K(s, t) e_k(s) ds = \lambda_k e_k(t) $$
  3. Obtain eigenfunctions and eigenvalues: $$ e_k(t) = \sqrt{2} \sin(k \pi t), \quad \lambda_k = \frac{1}{(k \pi)^2} $$
  4. Construct the Karhunen–Loève expansion for simulation.
  5. Discretize the expansion for practical computation.

Python Implementation

import numpy as np

def brownian_bridge_ctr(steps=100, n_terms=500, paths=1):
    t = np.linspace(0, 1, steps)
    Bt = np.zeros((paths, steps))
    for p in range(paths):
        Z = np.random.normal(0, 1, n_terms)
        k = np.arange(1, n_terms + 1)
        for i, ti in enumerate(t):
            sin_terms = np.sin(k * np.pi * ti) / (k * np.pi)
            Bt[p, i] = np.sqrt(2) * np.dot(Z, sin_terms)
    return Bt

Summary: This approach yields sample paths of the Brownian bridge with the correct covariance structure, as guaranteed by the Karhunen–Loève theorem.

Discrete-time Recipe for Brownian Bridge

Intuition

In discrete time, we want to construct a vector \( X \) such that $$ \mathbb{E}[X] = 0, \quad \text{Cov}(X) = \Gamma $$ where \( \Gamma_{ij} = \min(t_i, t_j) - t_i t_j \) is the covariance matrix for the Brownian bridge.

General Recipe

  1. Generate the desired covariance matrix \( \Gamma \).
  2. Decompose \( \Gamma = Q \Lambda Q^T \) (eigendecomposition).
  3. Generate a Gaussian vector \( Z \sim N(0, I_n) \).
  4. Set \( X = Q \Lambda^{1/2} Z \).

Python Implementation

import numpy as np

def brownian_bridge_dtr(steps=100, paths=1, T=1):
    t = np.linspace(0, T, steps)
    Gamma = np.zeros((steps, steps))
    for i in range(steps):
        for j in range(steps):
            Gamma[i, j] = min(t[i], t[j]) - t[i]*t[j]
    eigenvals, eigenvecs = np.linalg.eigh(Gamma)
    Z = np.random.normal(0, 1, (steps, paths))
    Bt = eigenvecs @ np.diag(np.sqrt(eigenvals)) @ Z
    return Bt.T

Summary: This approach produces Brownian bridge sample paths with the correct covariance structure by diagonalizing the covariance matrix and scaling standard normal draws.

Simulation

Sample Paths

Covariance

Covariance Error

Theoretical Covariance

Discretized Equation

$$ B_t = \\sqrt{2} \\sum_{k=1}^N Z_k \\frac{\\sin(k \\pi t)}{k \\pi} $$

Relevant Articles

Recipes for simulating stochastic processes

This note discusses the necessary steps to simulate a stochastic process with a desired covariance structure. In this context, I outline the Karhunen–Loéve theorem and provide intuition and general recipes to decompose a stochastic process by establishing the integral eigenvalue problem (continuous-time) or, equivalently, the covariance matrix diagonalization problem (discrete-time). I then apply these general recipes to a Brownian motion and Brownian bridge to numerically simulate paths.

View on SSRN
Suggested Citation:
Paolucci, Roman, Recipes for simulating stochastic processes (Brownian bridge) (June 30, 2025). Available at SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5332011