Sample from posterior distributions using the No U-turn Sampler (NUTS). For details see the original NUTS paper and the more recent introduction.
This crate was developed as a faster replacement of the sampler in PyMC, to be used with the new numba backend of aesara. The work-in-progress python wrapper for this sampler is nuts-py.
Usage
use ;
use Error;
// Define a function that computes the unnormalized posterior density
// and its gradient.
// The density might fail in a recoverable or non-recoverable manner...
// We get the default sampler arguments
let mut sampler_args = default;
// and modify as we like
sampler_args.step_size_adapt.target = 0.8;
sampler_args.num_tune = 1000;
sampler_args.maxdepth = 3; // small value just for testing...
sampler_args.mass_matrix_adapt.store_mass_matrix = true;
// We instanciate our posterior density function
let logp_func = PosteriorDensity ;
let chain = 0;
let seed = 42;
let mut sampler = new_sampler;
// Set to some initial position and start drawing samples.
sampler.set_position.expect;
let mut trace = vec!; // Collection of all draws
let mut stats = vec!; // Collection of statistics like the acceptance rate for each draw
for _ in 0..2000
Sampling several chains in parallel so that samples are accessable as they are generated
is implemented in [sample_parallel
].
Implementation details
This crate mostly follows the implementation of NUTS in Stan and
PyMC, only tuning of mass matrix and step size differs:
In a first window we sample using the identity as mass matrix and adapt the
step size using the normal dual averaging algorithm.
After discard_window
draws we start computing a diagonal mass matrix using
an exponentially decaying estimate for sqrt(sample_var / grad_var)
.
After 2 * discard_window
draws we switch to the entimated mass mass_matrix
and keep adapting it live until stop_tune_at
.