Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Appendix C: Algorithm Pseudocode

Clean, language-agnostic pseudocode for all major algorithms in this course.


C.1 Metropolis–Hastings

INPUT: target p(x), proposal Q(x→x'), initial x, N_steps, β
OUTPUT: trajectory {x^(t)}

x ← x_0
for t = 1 to N_steps:
    propose x' ~ Q(x → x')
    α ← p(x') Q(x'→x) / [p(x) Q(x→x')]
    u ~ Uniform(0, 1)
    if u < min(1, α):
        x ← x'            # accept
    record x^(t) ← x

For symmetric proposals (\(Q\) symmetric): \(\alpha = p(x’)/p(x) = e^{-\beta \Delta H}\).


C.2 Gibbs Sampler

INPUT: conditional distributions p(x_i | x_{-i}), initial x, N_steps
OUTPUT: trajectory {x^(t)}

for t = 1 to N_steps:
    for i = 1 to d:
        x_i ← sample from p(x_i | x_1,...,x_{i-1}, x_{i+1},...,x_d)
    record x^(t) ← x

C.3 Ising Metropolis (Single-Spin Flip)

INPUT: L × L spin lattice, β, J, N_sweeps
OUTPUT: time series of E, M

initialise spins randomly ±1
precompute: acc[ΔE] = min(1, exp(-β ΔE)) for ΔE in {-8J,-4J,0,4J,8J}

for sweep = 1 to N_sweeps:
    for k = 1 to L²:
        pick spin (i,j) at random
        ΔE ← 2J · s[i,j] · (s[i+1,j] + s[i-1,j] + s[i,j+1] + s[i,j-1])
        u ~ Uniform(0,1)
        if u < acc[ΔE]:
            s[i,j] ← -s[i,j]
    record E ← Σ_<ij> (-J s_i s_j), M ← Σ_i s_i / L²

C.4 Wolff Cluster Algorithm

INPUT: L × L spin lattice, β, J
OUTPUT: updated spins, cluster size

pick random seed (i₀, j₀)
cluster_spin ← s[i₀, j₀]
p_add ← 1 - exp(-2βJ)
cluster ← {(i₀, j₀)}
queue ← {(i₀, j₀)}

while queue not empty:
    (i, j) ← pop from queue
    for each neighbour (i', j') of (i, j):
        if s[i',j'] == cluster_spin and (i',j') not in cluster:
            u ~ Uniform(0,1)
            if u < p_add:
                add (i',j') to cluster and queue

for each (i,j) in cluster:
    s[i,j] ← -s[i,j]

return |cluster|

C.5 Wang-Landau Algorithm

INPUT: system, energy range [E_min, E_max], bin width ΔE
OUTPUT: density of states g(E)

initialise: g(E) ← 1 for all E bins
            H(E) ← 0 (histogram)
            f ← exp(1) ≈ 2.718
            flatness_criterion ← 0.8

x ← random initial configuration
E ← energy(x)

while f > exp(1e-8):
    propose x' (random spin flip or move)
    E' ← energy(x')
    u ~ Uniform(0,1)
    if u < g(E) / g(E'):
        x ← x'
        E ← E'
    g(E) ← g(E) · f
    H(E) ← H(E) + 1

    if histogram is flat (min(H) > flatness_criterion · mean(H)):
        f ← sqrt(f)
        H(E) ← 0 for all E

return g(E)

Flatness check: \(\min_E H(E) > 0.8 \times \langle H \rangle\).


C.6 BKL / Gillespie KMC

INPUT: initial state α, rate catalog {k_j(α)}, T_max
OUTPUT: trajectory of states and times

t ← 0
state ← α

while t < T_max:
    # 1. Compute all rates from current state
    rates ← [k_1(state), k_2(state), ..., k_M(state)]
    K_tot ← sum(rates)

    # 2. Draw time increment
    u1 ~ Uniform(0,1)
    dt ← -ln(u1) / K_tot
    t ← t + dt

    # 3. Select event
    u2 ~ Uniform(0,1)
    cumulative ← 0
    for j = 1 to M:
        cumulative ← cumulative + rates[j]
        if u2 · K_tot ≤ cumulative:
            execute event j
            break

    # 4. Update state and rate catalog
    state ← new_state_after_event_j
    record (t, state)

Event selection can be done in \(\mathcal{O}(\log M)\) using binary search on the cumulative rate array.


C.7 Parallel Tempering

INPUT: M replicas at temperatures T_1 < T_2 < ... < T_M
       N_swap steps between swap attempts
OUTPUT: sampled configurations at each temperature

initialise: x_k ~ random, for k = 1...M

for step = 1 to N_total:
    # Standard MC/MD at each temperature (in parallel)
    for k = 1 to M (parallel):
        perform N_swap sweeps of x_k at β_k

    # Attempt swaps between adjacent replicas
    for k = 1 to M-1 (sequential or checkerboard):
        Δ ← (β_{k+1} - β_k) · (H(x_k) - H(x_{k+1}))
        u ~ Uniform(0,1)
        if u < min(1, exp(Δ)):
            swap x_k ↔ x_{k+1}

    record x_k for all k

C.8 Umbrella Sampling + WHAM

INPUT: M windows with centres {ξ₀^(m)}, spring constants {K^(m)}
       N_steps per window
OUTPUT: free energy profile F(ξ)

# Step 1: Run biased simulations
for m = 1 to M:
    H_biased(x) ← H(x) + ½ K^(m) (ξ(x) - ξ₀^(m))²
    run N_steps Metropolis with H_biased
    record histogram n_m(ξ)

# Step 2: WHAM self-consistent equations
initialise F_m ← 0 for m = 1...M

repeat until convergence:
    # Unbiased density
    ρ(ξ) ← Σ_m n_m(ξ) / Σ_m N_m exp(β F_m - β V_m(ξ))

    # Update free energy offsets
    F_m ← -k_BT ln Σ_ξ ρ(ξ) exp(-β V_m(ξ))

F(ξ) ← -k_BT ln ρ(ξ)

C.9 Blocking Analysis

INPUT: time series {A_t}, t = 1...N
OUTPUT: standard error as function of block size b

for b = 1, 2, 4, 8, ..., N/4:
    n_blocks ← floor(N / b)
    block_means ← [mean(A[k*b : (k+1)*b]) for k in 0..n_blocks-1]
    SE(b) ← std(block_means) / sqrt(n_blocks)

True error ← plateau value of SE(b) for large b
τ_int ← SE(b_plateau)² · N / (2 · SE(b=1)²)