Skip to content

Samplers

sample is the one entry point: method picks the algorithm, device picks CPU or GPU, and the rest of the call is the method's.

import jax
from cosmonuts import sample

key = jax.random.PRNGKey(0)
result = sample(model, key, output="chains/w0wa", progress=True)                          # NUTS
result = sample(model, key, method="nested", device="gpu", output="chains/w0wa_ns")       # evidence
Method Function Use it for
"nuts" nuts Default. Posteriors, with adaptive step size and mass matrix
"hmc" hmc Fixed-length trajectories (num_integration_steps)
"metropolis" metropolis Gradient-free random walk, for models that are not differentiable
"nested" nested The evidence \(\ln Z\) and its error; fills a GPU
(best fit) maximize L-BFGS from several starts

Each returns a result with samples, derived, posterior() and summary(); NUTS and HMC add \(\hat R\), ESS and divergences.

Chains in parallel

NUTS, HMC and Metropolis take parallel=:

parallel Chains run Warm-up
"vmap" batched on one device one, shared
"shard" spread over devices (COSMONUTS_CPU_DEVICES=n makes CPU cores) one per chain
"process" one process each one per chain
"mpi" one MPI rank each (mpirun -n <chains> python -m mpi4py script.py) one per chain
"auto" "shard" with several chains and devices, else "vmap"

CPU or GPU

NUTS gains from a GPU mainly when the theory itself is heavy. Nested sampling is the method that parallelises: its batch of slice chains is what fills a GPU.

Stopping on ESS

target_ess= stops once the smallest effective sample size reaches it and \(\hat R < 1.01\), checked every check_every draws.

Resume

With output, progress is saved as it goes; run again with resume=True to continue. See Your first fit.

Best fit

from cosmonuts import maximize

best = maximize(model, num_starts=4, key=jax.random.PRNGKey(0))
best.params, best.chi2

Use best.params as initial= for a sampler. For constraints that do not depend on prior volume, see Profile likelihoods.