easy primitives

Log Acceptance Ratio

Why this matters

The general Metropolis-Hastings acceptance ratio is

α = min(1, p(x') q(x|x') / (p(x) q(x'|x)))

For asymmetric proposals — random-walk step sizes that are position-dependent, Langevin proposals, or proposals from a learned model — the proposal density ratio q(x|x’)/q(x’|x) does not cancel. Working entirely in log-space avoids numerical underflow when probabilities are tiny and keeps the formula simple: subtract instead of divide.

This formula is the core of every MCMC sampler: vanilla MH, Metropolis- adjusted Langevin algorithm (MALA), Hamiltonian Monte Carlo (HMC), and Sequential Monte Carlo (SMC) importance weights all reduce to this or a close relative.

Worked mini-example

import jax.numpy as jnp

log_p_current  = -2.0
log_p_proposal = -1.0
log_q_forward  = -0.5   # log q(x' | x)
log_q_backward = -0.5   # log q(x  | x')

log_accept = log_p_proposal + log_q_backward - log_p_current - log_q_forward
# = -1.0 + (-0.5) - (-2.0) - (-0.5)
# = -1.0 - 0.5 + 2.0 + 0.5 = 1.0

For symmetric proposals log_q_forward == log_q_backward, so the q terms cancel and log_accept = log_p_proposal - log_p_current.

Common pitfalls

  • Swap forward/backward: q_forward is the probability of proposing x’ from x (numerator of q ratio → denominator of accept ratio); q_backward is the probability of proposing x from x’. Swapping them inverts detailed balance and produces a biased chain.
  • Sign errors: proposal target log_p_proposal goes in the numerator (add), current target log_p_current in the denominator (subtract).
  • No clamp here: this function returns the raw log ratio (possibly > 0). The min(0, ...) clamp happens when using the ratio in an accept step.

Problem

Implement log_acceptance(log_p_current, log_p_proposal, log_q_forward, log_q_backward) that returns the log Metropolis-Hastings acceptance ratio as a scalar.

All four inputs are scalar floats. Return a scalar float.

Hints

jax mcmc log-prob

Sign in to attempt this problem and view the solution.