Inference¶
Pure kernels, adaptation utilities and compiled runners. See Inference for how they fit together.
Runners¶
probjax.inference.run
¶
run(key, kernel, state, params, num_steps, *, args=None, adaptor=None, collect=None, thin=1, progress=False)
Run num_steps transitions and keep every thin-th.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
RngKey
|
Random key. |
required |
kernel
|
Kernel
|
The kernel to run. |
required |
state
|
Any
|
Initial kernel state. |
required |
params
|
Any
|
Kernel parameters. |
required |
num_steps
|
int
|
Number of transitions; must be a multiple of |
required |
args
|
tuple[Any, ...] | None
|
Per-step extra arguments (e.g. minibatches), a tuple whose
leaves have a leading axis of length |
None
|
adaptor
|
Adaptor | None
|
Adapts |
None
|
collect
|
tuple[str, ...] | None
|
State or info fields to record at every kept step;
|
None
|
thin
|
int
|
Keep every |
1
|
progress
|
bool | tuple[str, ...]
|
Show a progress bar. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
RunResult
|
class: |
RunResult
|
an array with |
Source code in probjax/inference/runner.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | |
probjax.inference.warmup
¶
Fit the kernel parameters over num_steps transitions.
policy is an :class:Adaptor (run with :func:run, then finalized) or
a :class:Warmup procedure. None uses the kernel's
default_adaptation.
Source code in probjax/inference/runner.py
probjax.inference.step
¶
Take one transition, then apply one adaptor update if given.
Returns (state, params, adaptor_state, info). Use it to write your own
outer loop, for example one that alternates sampling with fitting.
Source code in probjax/inference/runner.py
MCMC kernels¶
probjax.inference.hmc
¶
Bases: MarkovKernelAPI
Hamiltonian Monte Carlo with a fixed number of integration steps.
Tunable parameters come from kernel.init_params(state, step_size=0.5,
inverse_mass_matrix=None) (see :class:HMCParams); the step size is
scaled by the initial gradient norm. Default adaptation:
:func:window_warmup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
num_integration_steps
|
Number of integrator steps per proposal. |
required | |
integrator
|
Symplectic integrator from |
required | |
divergence_threshold
|
Energy error above which a transition is flagged as divergent. |
required |
Source code in probjax/inference/mcmc/hmc.py
probjax.inference.nuts
¶
Bases: MarkovKernelAPI
No-U-Turn sampler: HMC with an adaptively chosen trajectory length.
Tunable parameters are the same as for :class:hmc
(step_size, inverse_mass_matrix). Default adaptation:
:func:window_warmup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
max_num_doublings
|
Maximum tree depth; a trajectory has at most
|
required | |
divergence_threshold
|
Energy error above which a transition is flagged as divergent. |
required | |
integrator
|
Symplectic integrator from |
required |
Source code in probjax/inference/mcmc/hmc.py
probjax.inference.dynamic_hmc
¶
Bases: MarkovKernelAPI
HMC whose number of integration steps changes from step to step.
The step count follows a deterministic or random sequence with the given
average, which avoids the periodicity of fixed-length HMC. Tunable
parameters are the same as for :class:hmc. Default adaptation:
:func:window_warmup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
average_integration_steps
|
Mean number of integrator steps. |
required | |
integration_steps_sequence
|
How the step counts are drawn:
|
required | |
divergence_threshold
|
Energy error above which a transition is flagged as divergent. |
required | |
integrator
|
Symplectic integrator from |
required |
Source code in probjax/inference/mcmc/dynamic_hmc.py
probjax.inference.mala
¶
Bases: MarkovKernelAPI
Metropolis-adjusted Langevin algorithm.
Proposes a gradient step plus Gaussian noise and accepts it with a
Metropolis-Hastings correction. Tunable parameters come from
kernel.init_params(state, step_size=1e-2) (see :class:MALAParams);
the step size is scaled by the initial gradient norm. Default adaptation:
:func:step_size_adaptor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required |
Source code in probjax/inference/mcmc/mala.py
probjax.inference.mclmc
¶
Bases: MarkovKernelAPI
Microcanonical Langevin Monte Carlo without Metropolis adjustment.
Isokinetic dynamics with partial momentum refreshment; asymptotically
biased, so tune step_size and L with :func:mclmc_warmup (the
default adaptation). Tunable parameters come from
kernel.init_params(state, step_size=0.1, L=1.0,
inverse_mass_matrix=None) (see :class:MCLMCParams).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
integrator
|
Isokinetic integrator from |
required |
Source code in probjax/inference/mcmc/mclmc.py
probjax.inference.adjusted_mclmc
¶
Bases: MarkovKernelAPI
Metropolis-adjusted MCLMC with a fixed number of integration steps.
Tunable parameters come from kernel.init_params(state, step_size=0.5,
num_integration_steps=10, inverse_mass_matrix=None,
L_proposal_factor=inf) (see :class:AdjustedMCLMCParams). Default
adaptation: step-size dual averaging towards a 0.9 acceptance rate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
integrator
|
Isokinetic integrator from |
required | |
divergence_threshold
|
Energy error above which a transition is flagged as divergent. |
required |
Source code in probjax/inference/mcmc/mclmc.py
probjax.inference.mh
¶
Bases: MarkovKernelAPI
Metropolis-Hastings with a user-supplied proposal.
The kernel params are passed to the proposal as params=; the default
init_params returns the empty :class:RWParams.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
transition_proposal_fn
|
|
required | |
transition_proposal_logpdf
|
|
required |
Source code in probjax/inference/mcmc/mh.py
probjax.inference.gauss_rwmh
¶
Bases: MarkovKernelAPI
Gaussian random-walk Metropolis-Hastings.
Proposes x + step_size * scale @ eps with standard normal eps.
Tunable parameters come from kernel.init_params(state, step_size=0.5,
scale=None) (see :class:RWParamsGauss); scale is a diagonal
(vector) or a dense matrix square root and defaults to the identity.
Default adaptation: a covariance estimate for scale over the first half
of the warmup, then the step size towards a 0.234 acceptance rate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required |
Source code in probjax/inference/mcmc/mh.py
probjax.inference.imh
¶
Bases: MarkovKernelAPI
Independent Metropolis-Hastings with a :class:~probjax.inference.Density proposal.
The kernel's params are the proposal's params, so a learned proposal's
weights live in the compiled scan and can be trained there. Default
adaptation: :func:~probjax.inference.fit_adaptor maximising the
proposal's likelihood on Rao-Blackwellised chain output, one Adam step
per transition. Pass fit_adaptor(..., every=k, num_fit_steps=m) as the
warmup policy to alternate sampling and fitting blocks instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
proposal
|
The independent proposal. Build one from a flow with
:func: |
required |
Source code in probjax/inference/mcmc/imh.py
probjax.inference.slice
¶
Bases: MarkovKernelAPI
Slice sampling along random one-dimensional slices.
Each step brackets the slice by stepping out with step_size and then
shrinks it until a point is accepted. Tunable parameters come from
kernel.init_params(state, step_size=0.5) (see :class:SliceParams).
Default adaptation: :func:slice_step_size_adaptor, balancing bracket
expansions and contractions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
max_evals
|
Maximum number of density evaluations per step. |
required | |
slice_fn
|
Slice geometry: |
required | |
slice_fn_arg
|
|
required | |
**kwargs
|
Options for the |
required |
Source code in probjax/inference/mcmc/slice.py
probjax.inference.latent_slice
¶
Bases: MarkovKernelAPI
Latent slice sampling with an auxiliary, per-coordinate bracket width.
The bracket width is resampled every step from an exponential with rate
step_size, so it adapts to the local scale. Tunable parameters come
from kernel.init_params(state, step_size=0.5) (see
:class:LatentSliceParams). Default adaptation: step size towards a
target number of density evaluations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
max_evals
|
Maximum number of density evaluations per step. |
required |
Source code in probjax/inference/mcmc/latent_slice.py
probjax.inference.elliptical_slice
¶
Bases: MarkovKernelAPI
Elliptical slice sampling for targets with a Gaussian prior.
The target is split as N(mean, cov_matrix) * likelihood. Rejection
free and without tunable parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the full target. |
required | |
cov_matrix
|
Prior covariance, a diagonal (vector) or a dense matrix. |
required | |
mean
|
Prior mean. |
required | |
loglikelihood_fn
|
Log likelihood. Defaults to |
required |
Source code in probjax/inference/mcmc/elliptical_slice.py
probjax.inference.arms
¶
Bases: MarkovKernelAPI
Adaptive rejection Metropolis sampling for scalar targets.
Proposes from a piecewise-exponential envelope of the log density and
corrects with Metropolis-Hastings; rejected proposals refine the
envelope. The envelope is set up by kernel.init(key, position,
init_points=None, lb=-inf, ub=inf, max_points=50). No tunable
parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the scalar target. |
required |
Source code in probjax/inference/mcmc/arms.py
probjax.inference.a2rms
¶
Bases: MarkovKernelAPI
ARMS that also refines the envelope after some accepted proposals.
Like :class:arms, but an accepted proposal still updates the envelope
with a probability that grows with the envelope's gap to the target, so
the envelope keeps improving where ARMS would stop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the scalar target. |
required |
Source code in probjax/inference/mcmc/arms.py
probjax.inference.gaussian_imh
¶
Bases: MarkovKernelAPI
Independent Metropolis-Hastings with a Gaussian proposal.
Tunable parameters come from kernel.init_params(state, mean=None,
cov=None) (see :class:GaussianIMHParams). Default adaptation: running
estimates of the mean and covariance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required |
Source code in probjax/inference/mcmc/imh.py
probjax.inference.adjusted_mclmc_dynamic
¶
Bases: MarkovKernelAPI
Metropolis-adjusted MCLMC with a varying number of integration steps.
Tunable parameters come from kernel.init_params(state, step_size=0.5,
inverse_mass_matrix=None, L_proposal_factor=inf) (see
:class:AdjustedMCLMCDynamicParams). Default adaptation:
step-size dual averaging towards a 0.9 acceptance rate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target. |
required | |
average_integration_steps
|
Mean number of integrator steps. |
required | |
integration_steps_sequence
|
How the step counts are drawn:
|
required | |
divergence_threshold
|
Energy error above which a transition is flagged as divergent. |
required | |
integrator
|
Isokinetic integrator from |
required | |
next_random_arg_fn
|
Advances the random argument; required with
|
required | |
integration_steps_fn
|
Custom step-count function, overriding
|
required |
Source code in probjax/inference/mcmc/mclmc.py
probjax.inference.pseudo_marginal
¶
Wrap a probjax MCMC kernel for pseudo-marginal inference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner_kernel_cls
|
A probjax kernel class (e.g. |
required | |
stochastic_logdensity_fn
|
Callable
|
A callable
|
required |
num_samples
|
int
|
Number of independent keys to evaluate and average for variance reduction (default 1). |
1
|
**inner_kernel_kwargs
|
Options for the inner kernel. They are routed
to whichever of |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Kernel
|
fixes one sub-key for the stochastic log-density, and delegates |
|
Kernel
|
the transition to the inner kernel. |
Source code in probjax/inference/mcmc/pmmcmc.py
Exact samplers¶
Each step returns one independent, exact draw.
probjax.inference.ars
¶
Bases: MarkovKernelAPI
Adaptive rejection sampling for univariate log-concave targets.
Every step returns one exact, independent draw: run collects iid
samples, not a Markov chain. Draws come from a piecewise-exponential
envelope of the log density; a draw that misses the squeeze costs one
log-density evaluation and adds a tangent there, so the envelope tightens
as sampling proceeds and later draws are cheaper. The envelope lives in the
state; there are no parameters to adapt.
The envelope is set up by kernel.init(key, position, init_points=None,
lower=-inf, upper=inf, max_points=50). init_points default to
position + [-1, 0, 1]; on an unbounded side they must straddle the
mode. The target must be log-concave.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the scalar target. |
required | |
max_proposals
|
Envelope draws allowed per step before giving up. |
required |
Source code in probjax/inference/rejection/adaptive.py
probjax.inference.rejection
¶
Bases: MarkovKernelAPI
Rejection sampling with a :class:~probjax.inference.Density proposal.
Every step returns one exact, independent draw from the target, provided
params.log_bound bounds log p - log q from above: proposals
x ~ q are accepted with probability exp(log p(x) - log q(x) - log M)
until one is. log p need not be normalised.
Params come from kernel.init_params(state, proposal_params,
log_bound=-inf). The default adaptation, :func:bound_adaptor, learns
the bound as the largest ratio seen, so warm up before collecting draws. A
learned proposal trains with :func:~probjax.inference.fit_adaptor on
field="proposal"; the accepted draws are exact target samples, so the
default data_fn is the right training data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Log density of the target, up to a constant. |
required | |
proposal
|
The proposal. It needs heavier tails than the target, or no finite bound exists. |
required | |
max_proposals
|
Proposals allowed per step before giving up. |
required |
Source code in probjax/inference/rejection/proposal.py
probjax.inference.bound_adaptor
¶
Raise params.<field> to the largest log p - log q seen.
The bound only grows, so draws taken while it is still growing are
slightly biased towards where it was too low; run this as warmup and keep
the bound fixed for the draws you report. With axis_name the chains
under jax.vmap share the maximum over all of them.
Source code in probjax/inference/rejection/proposal.py
Stochastic-gradient MCMC¶
probjax.inference.sgld
¶
Stochastic Gradient Langevin Dynamics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grad_estimator
|
Callable
|
Function |
required |
temperature
|
float
|
Temperature parameter (default 1.0). |
1.0
|
Source code in probjax/inference/mcmc/sgmcmc.py
probjax.inference.sghmc
¶
Stochastic Gradient Hamiltonian Monte Carlo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grad_estimator
|
Callable
|
Function |
required |
num_integration_steps
|
int
|
Number of leapfrog steps per sample. |
10
|
alpha
|
float
|
Friction coefficient. |
0.01
|
beta
|
float
|
Noise scaling. |
0.0
|
temperature
|
float
|
Temperature parameter. |
1.0
|
Source code in probjax/inference/mcmc/sgmcmc.py
probjax.inference.sgnht
¶
Stochastic Gradient Nosé-Hoover Thermostat.
SGNHT extends SGHMC with a thermostat variable that automatically adjusts the kinetic energy to maintain the target temperature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grad_estimator
|
Callable
|
Function |
required |
alpha
|
float
|
Friction coefficient. |
0.01
|
beta
|
float
|
Noise scaling. |
0.0
|
temperature
|
float
|
Temperature parameter. |
1.0
|
Note
init requires the rng to initialise momentum::
state = sampler.init(key, position)
Source code in probjax/inference/mcmc/sgmcmc.py
Warmup and adaptation¶
probjax.inference.window_warmup
¶
window_warmup(*, diagonal=True, target_acceptance_rate=0.8, initial_buffer_size=75, final_buffer_size=50, first_window_size=25)
Finite Stan-style warmup using BlackJAX's window-adaptation base.
Source code in probjax/inference/mcmc/adaptation.py
probjax.inference.pathfinder_warmup
¶
pathfinder_warmup(algorithm, logdensity_fn, *, initial_step_size=1.0, target_acceptance_rate=0.8, collect=False, **extra_parameters)
Create a BlackJAX Pathfinder warmup procedure.
Source code in probjax/inference/mcmc/warmup.py
probjax.inference.mclmc_warmup
¶
Create BlackJAX's MCLMC warmup for an :class:~probjax.inference.mclmc kernel.
Advances the chain while estimating L, the step size and, optionally,
a diagonal preconditioner. It tunes the kernel it is run with, so a custom
integrator is respected. options go to
blackjax.mclmc_find_L_and_step_size.
Source code in probjax/inference/mcmc/warmup.py
probjax.inference.step_size_adaptor
¶
step_size_adaptor(target=0.8, *, target_from_info_fn=lambda info: acceptance_rate, t0=10, gamma=0.05, kappa=0.75)
Local dual-averaging rule backed by BlackJAX's adaptation primitive.
Source code in probjax/inference/mcmc/adaptation.py
probjax.inference.mass_matrix_adaptor
¶
Local mass-matrix estimator backed by BlackJAX Welford adaptation.
Source code in probjax/inference/mcmc/adaptation.py
probjax.inference.covariance_adaptor
¶
Local proposal-geometry estimator backed by BlackJAX Welford updates.
Source code in probjax/inference/mcmc/adaptation.py
probjax.inference.mean_adaptor
¶
Local proposal-mean estimator backed by BlackJAX Welford updates.
Source code in probjax/inference/mcmc/adaptation.py
probjax.inference.compose_adaptors
¶
Compose adaptors, threading parameter updates in declaration order.
Source code in probjax/inference/adaptation.py
probjax.inference.acceptance_rate_adaptor
¶
Scale params[field] by exp(acceptance_rate - target).
Too many rejections shrink the step, too few grow it. Steps that report no acceptance rate (NaN) leave it unchanged.
Source code in probjax/inference/smc/adaptation.py
probjax.inference.slice_step_size_adaptor
¶
Dual averaging of the slice width on the share of bracket expansions.
A step size that is too small spends its evaluations stepping out, one
that is too large spends them shrinking the bracket. The expanding share
falls monotonically with the step size, so driving it to target
(expansions as many as contractions by default, as in Karamanis & Beutler,
2021) is stable, unlike targeting the total number of evaluations.
Source code in probjax/inference/mcmc/adaptation.py
probjax.inference.particle_adaptor
¶
Set params[field] to the covariance of the particles.
A one-dimensional field gets the variances, a two-dimensional one the full covariance, matching what HMC-style moves expect of an inverse mass matrix.
Source code in probjax/inference/smc/adaptation.py
probjax.inference.pooled
¶
Share one adaptation across chains run under jax.vmap.
Run the chains with jax.vmap(..., axis_name=axis_name). After every
update each chain's floating-point adaptor statistics and parameters are
replaced by their mean over chains, so all chains adapt as one. For dual
averaging this equals adapting on the mean acceptance rate. Welford
estimates measure deviations from the pooled mean, so they include the
spread between chains; they start slightly low (the bias shrinks like
log(n) / n after n updates).
Do not pool a :func:fit_adaptor: averaging would mix the chains'
buffered points. Give it axis_name instead, which averages gradients.
Source code in probjax/inference/adaptation.py
probjax.inference.fit_adaptor
¶
fit_adaptor(loss_fn, optimizer, *, field=None, data_fn=None, buffer_size=4096, batch_size=256, every=1, num_fit_steps=1, axis_name=None, seed=0)
Train learned parameters on the chain's own output, inside the scan.
Each transition appends data_fn(state, info) -> (points, weights) to a
ring buffer of buffer_size points shaped like state.position.
Every every transitions the adaptor takes num_fit_steps optimizer
steps on loss_fn(params, points, weights) over minibatches of
batch_size buffered points (None: the whole buffer). every=1,
num_fit_steps=1 trains a little after every transition;
every=200, num_fit_steps=200 alternates sampling and fitting blocks.
Both run fully compiled.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loss_fn
|
Callable[[Any, Any, Any], Any]
|
the training loss, e.g. :func: |
required |
optimizer
|
GradientTransformation
|
an optax transformation. |
required |
field
|
str | None
|
the parameter field to train; |
None
|
data_fn
|
Callable[[Any, Any], tuple[Any, Any]] | None
|
what to store per transition; defaults to the new position with weight one. |
None
|
axis_name
|
str | None
|
average gradients over this |
None
|
seed
|
int
|
seeds the minibatch draws (adaptors receive no key). |
0
|
Source code in probjax/inference/adaptation.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | |
probjax.inference.maximum_likelihood
¶
Weighted negative log-likelihood of density, for :func:fit_adaptor.
Source code in probjax/inference/adaptation.py
Convergence diagnostics¶
probjax.inference.effective_sample_size
¶
Compute estimate of the effective sample size (ess).
Parameters¶
input_array: An array representing multiple chains of MCMC samples. The array must contains a chain dimension and a sample dimension. chain_axis The axis indicating the multiple chains. Default to 0. sample_axis The axis indicating a single chain of MCMC samples. Default to 1.
Returns¶
NDArray of the resulting statistics (ess), with the chain and sample dimensions squeezed.
Variables whose within-chain variance is numerically zero have an effective
sample size of zero. Variables containing a NaN draw are undefined and
report NaN; the reduction is per variable, so an independent finite
variable is unaffected. Infinities are ordered values and are not treated
as missing.
Notes¶
The basic ess (:math:N_{\mathit{eff}}) diagnostic is computed by:
.. math:: \hat{N}_{\mathit{eff}} = \frac{MN}{\hat{\tau}}
.. math:: \hat{\tau} = -1 + 2 \sum_{t'=0}^K \hat{P}_{t'}
where :math:M is the number of chains, :math:N the number of draws,
:math:\hat{\rho}_t is the estimated _autocorrelation at lag :math:t, and
:math:K is the last integer for which :math:\hat{P}_{K} = \hat{\rho}_{2K} +
\hat{\rho}_{2K+1} is still positive :cite:p:stan_ess,gelman1995bayesian.
The current implementation is similar to Stan, which uses Geyer's initial monotone sequence
criterion :cite:p:geyer1992practical,geyer2011introduction.
Source code in blackjax/diagnostics.py
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | |
probjax.inference.ess_bulk
¶
Bulk effective sample size (rank-normalized split-chain ESS).
Computes the bulk ESS from Vehtari et al. (2021): rank-normalizes draws
after splitting each chain in half, then applies the standard
autocorrelation-based :func:effective_sample_size estimator. This
diagnostic is robust to non-stationarity and multimodality.
Parameters¶
input_array An array representing multiple chains of MCMC samples. The array must contain a chain dimension and a sample dimension. chain_axis The axis indicating the multiple chains. Default 0. sample_axis The axis indicating a single chain of MCMC samples. Default 1.
Returns¶
NDArray of the resulting bulk-ESS, with chain and sample dimensions squeezed.
Notes¶
Algorithm:
- Split each chain in half → 2× chains.
- Pool all draws and rank-normalize with :math:
z_r = \Phi^{-1}((r-3/8)/(n+1/4)). - Apply :func:
effective_sample_sizeto the rank-normalized draws.
References¶
.. cite:p:vehtari2021rank
Source code in blackjax/diagnostics.py
probjax.inference.ess_tail
¶
Tail effective sample size.
Computes the tail ESS from Vehtari et al. (2021) as the minimum of the ESS of the lower- and upper-tail indicator functions applied to split-chain draws.
The tail quantiles are determined by prob: the lower tail uses the
(1 - prob) / 2 quantile and the upper tail uses the
(1 + prob) / 2 quantile. The default prob=0.90 corresponds to
the 5th/95th percentiles, matching ArviZ's default prob=(0.05, 0.95).
.. warning::
The agreement with az.ess(method="tail") holds for continuous
draws only. The upper-tail indicator here is
:math:\mathbf{1}(x \ge q_{\text{high}}), whereas Vehtari et al.
and ArviZ use :math:\mathbf{1}(x \le q) for both tails. On
continuous draws the two are exact complements and the ESS is
identical, but on tied draws they are not: for iid Bernoulli(0.1),
:math:P(x \ge q_{95}) is 0.097 rather than 0.05, and for a 5-level
grid it is 0.21. This is a separate known defect in the tail
estimator's tie handling, tracked independently of the
rank-normalization fix; note that simply switching to <= does not
resolve it, since that indicator is identically 1 on such draws and
would be reported as degenerate.
Parameters¶
input_array
An array representing multiple chains of MCMC samples. The array must
contain a chain dimension and a sample dimension.
chain_axis
The axis indicating the multiple chains. Default 0.
sample_axis
The axis indicating a single chain of MCMC samples. Default 1.
prob
Central-interval probability that determines the tail quantiles.
Lower quantile: (1 - prob) / 2; upper quantile:
(1 + prob) / 2. Default 0.90 gives the 5th/95th-percentile
tail, matching az.ess(method="tail") (ArviZ default).
Returns¶
NDArray of the resulting tail-ESS, with chain and sample dimensions squeezed.
Notes¶
Algorithm:
- Split each chain in half → 2× chains.
- Compute pooled lower/upper quantiles (at
(1-prob)/2and(1+prob)/2) across all split chains and draws. - Form indicator series :math:
\mathbf{1}(x \le q_{\text{low}})and :math:\mathbf{1}(x \ge q_{\text{high}}). - Compute :func:
effective_sample_sizefor each indicator. - Return :math:
\min(\text{ESS}_\text{lower}, \text{ESS}_\text{upper}).
References¶
.. cite:p:vehtari2021rank
Source code in blackjax/diagnostics.py
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | |
probjax.inference.potential_scale_reduction
¶
Gelman and Rubin (1992)'s potential scale reduction for computing multiple MCMC chain convergence.
Parameters¶
input_array: An array representing multiple chains of MCMC samples. The array must contains a chain dimension and a sample dimension. chain_axis The axis indicating the multiple chains. Default to 0. sample_axis The axis indicating a single chain of MCMC samples. Default to 1.
Returns¶
NDArray of the resulting statistics (r-hat), with the chain and sample dimensions squeezed.
Notes¶
The diagnostic is computed by:
.. math:: \hat{R} = \sqrt{\frac{\hat{V}}{W}}
where :math:W is the within-chain variance and :math:\hat{V} is the posterior variance
estimate for the pooled traces. This is the potential scale reduction factor, which
converges to unity when each of the traces is a sample from the target posterior. Values
greater than one indicate that one or more chains have not yet converged :cite:p:stan_rhat,gelman1992inference.
Source code in blackjax/diagnostics.py
probjax.inference.rhat
¶
Rank-normalized split-RÌ‚ (Vehtari et al. 2021).
The modern improved R̂ diagnostic. Combines two split-chain R̂ values — one on rank-normalized draws and one on rank-normalized folded draws — and returns the maximum. The folded component catches scale/variance non-convergence that the bulk component can miss.
This matches the default az.rhat(method="rank") convention in ArviZ.
Parameters¶
input_array An array representing multiple chains of MCMC samples. The array must contain a chain dimension and a sample dimension. At least 2 chains and at least 4 draws per chain are required. chain_axis The axis indicating the multiple chains. Default 0. sample_axis The axis indicating a single chain of MCMC samples. Default 1.
Returns¶
NDArray of the resulting RÌ‚ values, with chain and sample dimensions squeezed. Values close to 1.0 indicate convergence; values above 1.01 suggest chains have not converged.
Notes¶
Algorithm (Vehtari et al. 2021, § 4):
- Split each chain in half → 2× chains.
- Rank-normalize with the Blom plotting position
:math:
z_r = \Phi^{-1}((r - 3/8) / (n + 1/4))over the joint pool. - Compute the standard split-RÌ‚ on the rank-normalized draws (bulk).
- Compute the folded draws :math:
|x - \mathrm{median}(x)|, rank-normalize them, and compute split-RÌ‚ again (tail). - Return :math:
\max(\hat{R}_{\text{bulk}}, \hat{R}_{\text{tail}}).
.. warning::
NaN from this function does not uniquely mean "the draws
contained a missing observation". The folded component subtracts the
pooled median, so when at least half of a component's pooled draws are
+inf (or -inf) the median is infinite and the fold evaluates
inf - inf, which is NaN. Such a component returns NaN from
:func:rhat while containing no NaN at all — and while
:func:ess_bulk and :func:ess_tail still return finite values for it.
Infinity handling is a separate open question from the missing-data
contract; this is documented, not yet decided.
References¶
.. cite:p:vehtari2021rank
Source code in blackjax/diagnostics.py
probjax.inference.pareto_khat
¶
Pareto shape parameter k̂ for tail diagnosis.
Fits a Generalised Pareto Distribution (GPD) to the upper and/or lower tail of a 1-D sample and returns the estimated shape parameter k̂.
Parameters¶
x
1-D array of draws (or any array; it is ravelled before use).
tail
Which tail to fit: "upper", "lower", or "both" (default).
When "both", returns the maximum of the two k̂ estimates.
tail_frac
Fraction of samples used as the tail. Default 0.10 (10 %).
A minimum of 5 tail samples is always enforced.
Returns¶
Scalar Array: the Pareto shape estimate k̂. Values below 0.5 indicate reliable tail estimates; 0.5–0.7 are moderate; above 0.7 may be unreliable.
Notes¶
Uses the Zhang & Stephens (2009) empirical-Bayes estimator implemented
in the internal :func:_gpdfit. The upper tail is modelled directly;
the lower tail is reflected and modelled as an upper tail.
Source code in blackjax/diagnostics.py
probjax.inference.kernelized_stein_discrepancy
¶
Estimate squared kernelized Stein discrepancy with a V- or U-statistic.
Parameters¶
samples
PyTree (an array, or a dict/tuple/NamedTuple of per-field arrays) whose
leaves share a leading num_samples axis. Chain dimensions must be
pooled explicitly before calling this function.
grad_logdensity_fn
Target score function, mapping one sample (one leading-axis slice of
samples, with the same PyTree structure) to the gradient of its log
density. For example, jax.grad(logdensity_fn). The normalizing
constant is not required.
kernel
Scalar-valued, twice differentiable positive semidefinite kernel taking
two flattened sample vectors. Bind kernel parameters such as bandwidth
with functools.partial. The kernel must satisfy the target's Stein
boundary conditions; choosing an appropriate kernel is the caller's
responsibility.
statistic
"v" includes diagonal pairs; "u" excludes them and requires at
least two draws. The U-statistic can be negative, even in exact arithmetic.
Returns¶
Estimate of squared KSD, not a calibrated p-value or convergence certificate.
The V-statistic has a sample-dependent diagonal bias of order 1/n.
Notes¶
Complements rather than replaces R-hat. Approximately independent draws are
assumed; autocorrelation and an unvisited mode can make the result misleading.
A positive semidefinite kernel alone does not identify every distribution:
this requires additional conditions, including integral strict positive
definiteness :cite:p:liu2016kernelized. Gaussian RBF kernels do not in
general detect non-convergence in dimension three or higher. IMQ kernels
have convergence guarantees for suitable targets, but targets with bounded
scores, including some heavy-tailed targets, remain a gap
:cite:p:gorham2017kernels.
Uses the score/kernel derivative expression in :cite:p:liu2016kernelized.
Rows are processed sequentially and columns are vectorized. The computation
has quadratic cost in sample count and mixed Hessians with d² entries;
temporary pairwise storage scales as O(n*d²) rather than O(n²*d²).
The supplied functions must support JAX differentiation and transformations.
No clipping is applied to either statistic.
Vendored from unreleased BlackJAX main; see the module docstring.
Source code in probjax/inference/diagnostics.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | |
probjax.inference.imq_kernel
¶
Inverse multiquadric kernel (c² + ||x-y||²)**beta.
Use c > 0 and -1 < beta < 0. Bind non-default parameters with
functools.partial. Convergence guarantees additionally require target
conditions; see :cite:p:gorham2017kernels.
Vendored from unreleased BlackJAX main; see the module docstring.
Source code in probjax/inference/diagnostics.py
probjax.inference.divergence_concentration
¶
Flag a run where sampling-phase divergences concentrate on a minority of chains.
Parameters¶
is_divergent
Per-draw divergence flags (bool or 0/1) for the sampling
(post-warmup) phase only, shape (n_chains, n_draws).
rate_threshold
Minimum per-chain divergence rate for chain k to count as
flagged. Default 0.02 (2%).
Returns¶
:class:DivergenceConcentrationReport. warn is true iff between
1 and max(1, n_chains // 4) chains are flagged -- a
minority-outlier trigger; an ensemble where most/all chains cross the
threshold returns populated fields but no warning.
Notes¶
- Counting is sampling-phase only; warmup divergences are out of scope.
- Concatenating warmup draws in front of sampling draws dilutes a real signal below threshold rather than raising a false alarm -- slice to sampling draws only before calling this.
multinomial_p_valueis context only; it never decideswarn.
Source code in blackjax/diagnostics.py
probjax.inference.divergence_concentration_from_counts
¶
Same as :func:divergence_concentration, from precomputed per-chain counts.
Use when per-draw flags are not retained but per-chain totals are.
early_rate / late_rate are NaN (no per-draw resolution for
a quarter profile); :func:format_divergence_warning omits that part
of the message rather than printing "nan%".
Parameters¶
chain_divergence_counts
Per-chain divergence counts for the sampling phase, shape
(n_chains,).
n_draws
Number of sampling draws per chain.
rate_threshold
See :func:divergence_concentration.
Returns¶
:class:DivergenceConcentrationReport
Source code in blackjax/diagnostics.py
probjax.inference.format_divergence_warning
¶
Render a :class:DivergenceConcentrationReport as a human-readable message.
Returns "" when report.warn is false. Otherwise returns one
sentence per flagged chain (newline-separated when more than one
chain is flagged). Not JIT-compatible by design — call it on concrete
report values (e.g. after a sampling run has completed), not inside
traced code.
Parameters¶
report
A report produced by :func:divergence_concentration or
:func:divergence_concentration_from_counts.
Returns¶
str, empty when there is nothing to warn about.
Source code in blackjax/diagnostics.py
probjax.inference.DivergenceConcentrationReport
¶
Bases: NamedTuple
Per-run divergence-concentration diagnostic report.
All fields are plain JAX numerics — no strings — so the statistic
itself stays JIT-compilable. Pass the report to
:func:format_divergence_warning to render a human-readable message
from concrete (non-traced) values.
Attributes¶
warn
Bool. Whether a minority of chains (see the module notes on
:func:divergence_concentration) crossed rate_threshold.
flagged
Bool array, shape (n_chains,). Which chains crossed
rate_threshold, independent of whether warn ends up true.
num_flagged
Number of flagged chains, flagged.sum().
rates
Per-chain sampling-phase divergence rate, shape (n_chains,).
early_rate, late_rate
Per-chain divergence rate in the first and last quarter of the
sampling draws, shape (n_chains,). NaN when computed from
:func:divergence_concentration_from_counts (no per-draw
resolution available).
median_other_rate
For each chain, the median rates value across the other
n_chains - 1 chains, shape (n_chains,). NaN when
n_chains <= 1.
total_divergences
Total divergence count D summed over all chains.
num_chains
Number of chains M.
rate_threshold
The threshold that was applied (echoed back for the message /
for callers that only keep the report).
multinomial_p_value
Bonferroni-corrected exchangeable-null tail probability for the
single worst chain, min(1, M * P(Binomial(D, 1/M) >= d_max)).
Context only; never drives warn. NaN when D=0.
Source code in blackjax/diagnostics.py
Sequential Monte Carlo¶
See the SMC guide.
probjax.inference.smc
¶
smc(logprior_fn, loglikelihood_fn, *, move, num_mcmc_steps=10, target_ess=None, waste_free=None, batch_size=0)
Tempered SMC with MCMC moves.
With target_ess=None the schedule is fixed and each step takes the next
temperature as its argument, so run is called with
args=(schedule,). With a target_ess each step picks the largest
temperature that keeps that fraction of effective particles; once the
temperature reaches 1 further steps leave the state unchanged, so
num_steps is a cap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logprior_fn
|
Callable
|
Log prior of one particle. |
required |
loglikelihood_fn
|
Callable
|
Log likelihood of one particle; a scalar, or one term per observation for data tempering. |
required |
move
|
Any
|
MCMC kernel moving the particles, an API class such as |
required |
num_mcmc_steps
|
int
|
MCMC steps per particle and SMC step. |
10
|
target_ess
|
float | None
|
Fraction of effective particles each adaptive step keeps. |
None
|
waste_free
|
int | None
|
Keep every state of the move chains instead of only the
last (Dau and Chopin, 2022): each step resamples
|
None
|
batch_size
|
int
|
Move this many particles at a time to bound memory;
|
0
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Kernel
|
|
|
Kernel
|
that fits the move's geometry to the population. |
Source code in probjax/inference/smc/tempering.py
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | |
probjax.inference.SMCState
¶
Bases: NamedTuple
An equally weighted population at one temperature.
Attributes:
| Name | Type | Description |
|---|---|---|
particles |
PyTree[Array]
|
pytree with a leading particle axis. |
temperature |
Array
|
the current temperature, a scalar or one per observation. |
log_evidence |
Array
|
running estimate of |
Source code in probjax/inference/smc/tempering.py
probjax.inference.SMCInfo
¶
Bases: NamedTuple
Diagnostics of one SMC step.
Attributes:
| Name | Type | Description |
|---|---|---|
ess |
Array
|
effective sample size of the reweighted population, as a fraction of the particles. |
log_evidence_increment |
Array
|
this step's factor of the evidence estimate. |
ancestors |
Array
|
index of each particle's parent. |
unique_fraction |
Array
|
fraction of distinct parents among the resampled
particles; |
acceptance_rate |
Array
|
mean acceptance rate of the MCMC moves (NaN if the move reports none). |
Source code in probjax/inference/smc/tempering.py
probjax.inference.particle_adaptor
¶
Set params[field] to the covariance of the particles.
A one-dimensional field gets the variances, a two-dimensional one the full covariance, matching what HMC-style moves expect of an inverse mass matrix.
Source code in probjax/inference/smc/adaptation.py
probjax.inference.acceptance_rate_adaptor
¶
Scale params[field] by exp(acceptance_rate - target).
Too many rejections shrink the step, too few grow it. Steps that report no acceptance rate (NaN) leave it unchanged.
Source code in probjax/inference/smc/adaptation.py
probjax.inference.population_diagnostics
¶
Weight ESS and exact population/ancestral diversity (O(N log N) sorting).
Diagnostics do not imply independent posterior samples. ancestors may be composed origin labels for measuring collapse over many resampling steps.
Source code in probjax/inference/smc/temporal_utils.py
probjax.inference.summarize_replicates
¶
Mean and Monte Carlo standard error across independent RUN estimates.
Supply posterior expectation estimates (or evidence estimates on the desired scale), not individual correlated particles from one run.
Source code in probjax/inference/smc/temporal_utils.py
Twisted SMC for diffusion models¶
probjax.inference.diffusion_smc
¶
Twisted SMC that follows guide's reverse diffusion through times.
Run it for len(times) - 1 steps; further steps leave the state
unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
guide
|
Guide
|
the reverse SDE and twist, e.g. from
:func: |
required |
times
|
Array
|
the time grid; sorted from the noisy end to the clean one. |
required |
ess_threshold
|
float
|
resample when the ESS fraction falls below this. |
0.5
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Kernel
|
|
Source code in probjax/inference/smc/diffusion.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
probjax.inference.Guide
¶
Bases: NamedTuple
The reverse diffusion and twist :func:diffusion_smc follows.
All functions act on a batch of particles and take explicit params.
Attributes:
| Name | Type | Description |
|---|---|---|
sample_base |
Callable
|
|
evaluate |
Callable
|
|
log_target |
Callable
|
|
log_transition |
Callable | None
|
|
Source code in probjax/inference/smc/diffusion.py
probjax.inference.score_guide
¶
A training-free guide for an unnormalised target (reverse diffusion SMC).
At every particle it estimates the score with num_inner importance
samples of the target, and uses the same samples' marginal estimate as the
twist, relative to the forward noising kernel. That costs num_inner
target evaluations per particle and step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
log_target_fn
|
Callable[[Array], Array]
|
unnormalised log density of one point. |
required |
schedule
|
Any
|
the forward noising, with |
required |
event_shape
|
tuple[int, ...]
|
shape of one point. |
required |
num_inner
|
int
|
importance samples per score estimate. |
64
|
max_score_norm
|
float | None
|
clip the estimated score to this norm; noisy estimates at small times can otherwise throw particles far away. |
50.0
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Guide
|
class: |
Guide
|
time where the noised target is close to one. |
Source code in probjax/inference/smc/diffusion.py
probjax.inference.neural.diffusion_guide
¶
Steer a pretrained diffusion model towards prior(x) * exp(V(x)).
The guide for :func:~probjax.inference.diffusion_smc, after the twisted
diffusion sampler (Wu et al. 2023). The twist is V at the model's
denoised estimate of the clean point, faded in as the noise goes, and its
gradient steers the model's reverse SDE. The twist is a heuristic: it
decides how many particles are needed, never what they converge to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Any
|
a trained diffusion model with a |
required |
log_potential_fn
|
Callable[[Any], Any]
|
|
required |
event_spec
|
Any
|
shape (or pytree of shapes) of one point; defaults to the model's. |
None
|
twist
|
bool
|
|
True
|
inputs
|
dict[str, Any] | None
|
named model inputs such as |
None
|
Returns:
| Type | Description |
|---|---|
tuple[Guide, Any]
|
|
Source code in probjax/inference/neural.py
probjax.inference.DiffusionSMCState
¶
Bases: NamedTuple
A weighted population at one time of the reverse diffusion.
Attributes:
| Name | Type | Description |
|---|---|---|
particles |
PyTree[Array]
|
pytree with a leading particle axis. |
log_weights |
Array
|
normalised log weights. |
log_twist |
Array
|
twist of each particle at the current time. |
drift, |
diffusion
|
the reverse SDE at each particle. |
guidance |
PyTree[Array]
|
the proposal's steer at each particle. |
time_index |
Array
|
index of the current time in |
log_evidence |
Array
|
running estimate of |
Source code in probjax/inference/smc/diffusion.py
probjax.inference.DiffusionSMCInfo
¶
Bases: NamedTuple
Diagnostics of one reverse step.
Attributes:
| Name | Type | Description |
|---|---|---|
ess |
Array
|
effective sample size after reweighting, as a fraction. |
resampled |
Array
|
whether the population was resampled. |
ancestors |
Array
|
index of each particle's parent. |
unique_fraction |
Array
|
fraction of distinct parents; |
log_evidence_increment |
Array
|
this step's factor of the evidence estimate. |
Source code in probjax/inference/smc/diffusion.py
Filtering and smoothing¶
Every filter is a kernel built from a model, with the model parameters
theta as its params. See the filtering guide.
probjax.inference.LinearGaussianModel
¶
Bases: NamedTuple
A linear-Gaussian state-space model, filtered exactly by a Kalman filter.
Attributes:
| Name | Type | Description |
|---|---|---|
initial |
Callable
|
|
transition |
Callable
|
|
observation |
Callable
|
|
Source code in probjax/inference/filtering/state_space.py
probjax.inference.GaussianModel
¶
Bases: NamedTuple
A nonlinear model with additive Gaussian noise, for the EKF and the UKF.
Attributes:
| Name | Type | Description |
|---|---|---|
initial |
Callable
|
|
transition |
Callable
|
|
observation |
Callable
|
|
Source code in probjax/inference/filtering/state_space.py
probjax.inference.StateSpaceModel
¶
Bases: NamedTuple
A state-space model written for a single particle.
All functions act on one latent state x, which may be any pytree; the
particle filter vectorizes them over particles.
Attributes:
| Name | Type | Description |
|---|---|---|
init |
Callable
|
|
step |
Callable
|
|
log_likelihood |
Callable
|
|
transition_logdensity |
Optional[Callable]
|
|
Source code in probjax/inference/filtering/state_space.py
probjax.inference.kalman_filter
¶
Kalman filter for a linear-Gaussian state-space model.
The transition and observation matrices may be
:mod:~probjax.utils.linear_operator operators: large innovation systems
are then solved with CG and their log-determinant estimated by Lanczos.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
LinearGaussianModel
|
The model, as functions of the parameters |
required |
linear_solve
|
Optional[Callable]
|
|
None
|
logdet_fn
|
Optional[Callable]
|
|
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Kernel
|
and |
|
Kernel
|
params. |
|
Kernel
|
observations so far. |
Source code in probjax/inference/filtering/kalman_filter.py
probjax.inference.extended_kalman_filter
¶
Extended Kalman filter for a nonlinear model with Gaussian noise.
Each step linearises f at the filtered mean and h at the predicted
mean, then applies the Kalman update. Its log-likelihood is that of the
linearised model, an approximation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
GaussianModel
|
The model, as functions of the parameters |
required |
matrix_free
|
bool
|
Use the Jacobians as matrix-free operators instead of materialising them; pays off for large states. |
False
|
linear_solve, logdet_fn
|
As for :func: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Source code in probjax/inference/filtering/extended_kalman_filter.py
probjax.inference.unscented_kalman_filter
¶
unscented_kalman_filter(model, *, sigma_points=merwe_sigma_point)
Unscented Kalman filter for a nonlinear model with Gaussian noise.
Propagates sigma points through the transition and the observation instead of linearising them, so it needs no Jacobians.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
GaussianModel
|
The model, as functions of the parameters |
required |
sigma_points
|
Callable
|
|
merwe_sigma_point
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Source code in probjax/inference/filtering/unscented_kalman_filter.py
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | |
probjax.inference.square_root_kalman_filter
¶
Square-root Kalman filter for a linear-Gaussian model.
Takes the same model as :func:kalman_filter, with covariances; it factors
them itself. The state carries std with cov = std @ std.T.
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Source code in probjax/inference/filtering/square_root_kf.py
probjax.inference.rank_reduced_kalman_filter
¶
rank_reduced_kalman_filter(model, rank, *, linear_solve=None, min_eig=1e-09, process_noise_rank=None, energy_threshold=None, min_rank=1)
Kalman filter with the covariance kept at low rank, P ~= U S U^T.
The predict step combines the propagated covariance and the process noise
in factored form and truncates to rank; the update works in the
current subspace. Costs scale with rank instead of the state size.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
LinearGaussianModel
|
As for :func: |
required |
rank
|
int
|
Rank |
required |
linear_solve
|
Optional[Callable]
|
Solver for the innovation covariance. |
None
|
min_eig
|
float
|
Floor for the kept eigenvalues. |
1e-09
|
process_noise_rank
|
Optional[int]
|
Rank kept of |
None
|
energy_threshold
|
Optional[float]
|
Keep only the leading directions holding this
fraction of the variance (at least |
None
|
min_rank
|
int
|
Smallest effective rank under |
1
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Kernel
|
its state carries |
Source code in probjax/inference/filtering/rank_reduced_kalman_filter.py
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | |
probjax.inference.particle_filter
¶
particle_filter(model, num_particles, *, ess_threshold=0.5, proposal=None, unbiased_gradients=False)
Particle filter for a state-space model.
Each step moves the particles through the transition (or proposal),
weights them by the observation likelihood and resamples when the ESS
falls below ess_threshold. state.log_likelihood is an unbiased
estimate of the likelihood (on the log scale), so the filter can drive a
pseudo-marginal sampler over theta.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
StateSpaceModel
|
The model, written for one particle. |
required |
num_particles
|
int
|
Number of particles. |
required |
ess_threshold
|
float
|
Resample when the ESS falls below this fraction. |
0.5
|
proposal
|
Optional[Callable]
|
|
None
|
unbiased_gradients
|
bool
|
Pass gradients of the weights through resampling
(a stop-gradient correction), for fitting |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Kernel
|
and |
Source code in probjax/inference/filtering/particle_filter.py
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
probjax.inference.filtering.GaussianFilterState
¶
Bases: NamedTuple
The filtering distribution N(mean, cov) at time t.
log_likelihood accumulates log p(y_1:t | theta) over the steps.
Source code in probjax/inference/filtering/gaussian.py
probjax.inference.filtering.GaussianFilterInfo
¶
Bases: NamedTuple
The one-step prediction and this step's log-likelihood term.
Source code in probjax/inference/filtering/gaussian.py
probjax.inference.filtering.ParticleFilterState
¶
Bases: NamedTuple
A weighted particle approximation of the filtering distribution.
log_likelihood accumulates an unbiased estimate of p(y_1:t | theta)
on the log scale.
Source code in probjax/inference/filtering/particle_filter.py
probjax.inference.filtering.ParticleFilterInfo
¶
Bases: NamedTuple
Diagnostics of one filter step.
Attributes:
| Name | Type | Description |
|---|---|---|
ancestors |
Array
|
index of each particle's parent (itself without resampling). |
log_likelihood_increment |
Array
|
this step's term of the log-likelihood. |
ess |
Array
|
effective sample size of the weights, as a fraction. |
unique_fraction |
Array
|
fraction of distinct parents; |
Source code in probjax/inference/filtering/particle_filter.py
probjax.inference.filtering.merwe_sigma_point
¶
Generate sigma points for unscented Kalman filter, see [1].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mu0
|
ArrayLike
|
Mean of the state |
required |
cov0
|
ArrayLike
|
Covariance of the state |
required |
alpha
|
ArrayLike
|
Determines the spread around the mean (small values lead to large weight which require high precission (64 bit)). Large values will spread the sigma points further, typically letting to an overestimation of the covariance, small values will lead to an underestimation. Literature suggests 1e-3 but this requires 64 bit precision to work at all... . Defaults to 1.. |
1.0
|
beta
|
ArrayLike
|
Prior on covariance. Defaults to 2.. |
2.0
|
kappa
|
ArrayLike
|
Additional parameter. Defaults to 0.. |
0.0
|
Returns:
| Type | Description |
|---|---|
Tuple[Array, Array, Array]
|
Tuple[NDArray, NDArray, NDArray]: Sigma points, weights_mean, weights_cov |
References
[1] R. Van der Merwe "Sigma-Point Kalman Filters for Probabilitic Inference in Dynamic State-Space Models" (Doctoral dissertation)
Source code in probjax/inference/filtering/unscented_kalman_filter.py
probjax.inference.filtering.julier_uhlmann_sigma_points
¶
Generate Julier-Uhlmann sigma points.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mu0
|
ndarray
|
Mean of the state (D, ) |
required |
cov0
|
ndarray
|
Covariance of the state (D, D) |
required |
kappa
|
float
|
Spread parameter. Often chosen as kappa = 3 - D for state dimension D. |
0.0
|
Returns:
| Type | Description |
|---|---|
Tuple[Array, Array, Array]
|
Tuple[sigma_points, weights_mean, weights_cov]: sigma_points: (2D+1, D) weights_mean: (2D+1,) weights_cov: (2D+1,) |
Source code in probjax/inference/filtering/unscented_kalman_filter.py
probjax.inference.filtering.spherical_simplex_sigma_points
¶
Generate spherical simplex sigma points without explicit Python loops.
This creates a (D+1) x D array of points that form a regular simplex. The steps are: 1. Construct an initial (D+1, D) array corresponding to a simplex. 2. Center the points so they have zero mean. 3. Scale the points to achieve unit covariance. 4. Apply the square root of the covariance (via Cholesky) and then add mu0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mu0
|
ndarray
|
Mean of the state, shape (D,) |
required |
cov0
|
ndarray
|
Covariance of the state, shape (D,D) |
required |
Returns:
| Name | Type | Description |
|---|---|---|
sigma_points |
ndarray
|
(D+1, D) |
weights_mean |
ndarray
|
(D+1,) |
weights_cov |
ndarray
|
(D+1,) |
Source code in probjax/inference/filtering/unscented_kalman_filter.py
Smoothing and trajectories¶
probjax.inference.smooth
¶
Rauch--Tung--Striebel smoothed means and covariances of a Gaussian filter.
Exact for a :class:LinearGaussianModel filtered by a Kalman filter; for
a :class:GaussianModel it linearises the transition at the filtered
means (the extended RTS smoother). Both outputs include the initial time,
so they have len(states.t) + 1 entries.
Source code in probjax/inference/filtering/trajectory.py
probjax.inference.sample_paths
¶
Draw joint latent paths from a filter's output at fixed theta.
Paths have shape (len(states.t) + 1, num_samples, D), including the
initial state. A Gaussian filter's output is sampled backward from the
RTS conditionals: exactly for a :class:LinearGaussianModel, linearised
for a :class:GaussianModel. A particle filter's output uses
method='backward' (FFBSi, cost O(T N M), needs
model.transition_logdensity) or 'ancestry' (the stored parents,
O(T M), prone to path collapse). By default backward sampling is used
whenever the model has a transition density.
Source code in probjax/inference/filtering/trajectory.py
probjax.inference.particle_gibbs
¶
particle_gibbs(rng, reference_path, model, theta, ts, observations, *, t0=0.0, num_particles=32, observed=None, ancestor_sampling=True)
One conditional-SMC update (PGAS by default), returning a new joint path.
reference_path has shape (len(ts) + 1, D), including x(t0), and
model is a :class:StateSpaceModel with array states. Ancestor
sampling needs model.transition_logdensity. Multinomial resampling at
every step is intentional: pinning one index in systematic resampling is
not a valid conditional resampler.
The update preserves the smoothing law at fixed theta. Repeated calls
form an MCMC chain; one call is not an independent posterior draw.
Source code in probjax/inference/filtering/trajectory.py
Temporal SMC¶
probjax.inference.temporal_smc
¶
temporal_smc(filter, logprior_fn, *, max_observations, ess_threshold=0.5, num_moves=1, proposal_fn=None, batch_size=0)
SMC over parameters that assimilates one observation per step.
Each parameter particle carries its own filter, built for one theta:
a :func:~probjax.inference.particle_filter gives SMC² (unbiased
likelihoods), a :func:~probjax.inference.kalman_filter exact parameter
SMC. After every observation the outer weights are multiplied by the
filters' likelihood increments. When the ESS drops below
ess_threshold, parameters are resampled together with their filters
and moved by num_moves pseudo-marginal Metropolis-Hastings steps,
which re-filter the observations seen so far for each proposal.
The kernel steps like a filter, step(key, state, None, t, y,
observed=True), so run(key, kernel, state, None, len(ts), args=(ts,
ys)) assimilates a dataset, and running more steps continues it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filter
|
Kernel
|
Filter kernel for one |
required |
logprior_fn
|
Callable
|
|
required |
max_observations
|
int
|
Capacity of the buffer of assimilated observations;
steps beyond it are rejected ( |
required |
ess_threshold
|
float
|
Resample when the ESS falls below this fraction. |
0.5
|
num_moves
|
int
|
MH moves after each resampling; |
1
|
proposal_fn
|
Callable | None
|
|
None
|
batch_size
|
int
|
Parameters processed at once; |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Kernel
|
observation_like, t0=0.0) |
|
Kernel
|
which sets the buffer's shape. |
Source code in probjax/inference/smc/temporal.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | |
probjax.inference.TemporalSMCState
¶
Bases: NamedTuple
A weighted population of parameters, each with its own filter.
Attributes:
| Name | Type | Description |
|---|---|---|
parameters |
Any
|
pytree with a leading particle axis. |
filter_states |
Any
|
each parameter's filter state; their
|
log_weights |
Any
|
normalised log weights. |
log_evidence |
Any
|
running estimate of |
t0, |
t
|
initial time and time of the last assimilated observation. |
num_observations |
Any
|
observations assimilated so far. |
proposal_scale |
Any
|
scale of the adaptive random-walk move. |
data |
Any
|
|
Source code in probjax/inference/smc/temporal.py
posterior_samples
¶
Draw num_samples parameters from the weighted population.
Source code in probjax/inference/smc/temporal.py
probjax.inference.TemporalSMCInfo
¶
Bases: NamedTuple
Diagnostics of one assimilated observation.
Attributes:
| Name | Type | Description |
|---|---|---|
log_evidence_increment |
Any
|
this observation's term of the evidence. |
ess |
Any
|
effective sample size before resampling, as a fraction. |
resampled |
Any
|
whether the parameters were resampled. |
ancestors |
Any
|
index of each particle's parent. |
unique_fraction |
Any
|
fraction of distinct parents; |
acceptance_rate |
Any
|
mean acceptance of the moves (0 without moves). |
valid |
Any
|
false if the step was rejected and the state left unchanged. |
Source code in probjax/inference/smc/temporal.py
probjax.inference.sample_joint_paths
¶
Draw parameters from a temporal SMC state, then a path for each.
Each drawn theta re-runs filter over the observations the state
has assimilated (it keeps them), then draws one path with
:func:sample_paths. Paths have shape (num_samples,
num_observations + 1, D). Gaussian paths are exact given each
parameter; particle paths carry the filter's finite-particle error. Must
be called outside jit, since the number of observations sets the
shapes.
Source code in probjax/inference/filtering/joint.py
Learned components¶
probjax.inference.Density
¶
Bases: NamedTuple
A parameterised distribution, as inference needs it.
The parameters are an explicit argument, never closure state, so a kernel
can carry them in its params and an adaptor can train them inside a
compiled scan. :mod:probjax.inference.neural builds one from a
:mod:probjax.nn model.
Attributes:
| Name | Type | Description |
|---|---|---|
sample |
Callable[[Any, Any], Any]
|
|
logpdf |
Callable[[Any, Any], Any]
|
|
Source code in probjax/inference/base.py
probjax.inference.neural.density
¶
Split a tractable-density model into a :class:Density and its params.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Any
|
a :mod: |
required |
Returns:
| Type | Description |
|---|---|
Density
|
|
Any
|
|
Source code in probjax/inference/neural.py
probjax.inference.neural.bijection
¶
Split a normalizing flow into its map z -> (x, log|det J|) and params.
This is what :func:~probjax.inference.neutra needs.
Source code in probjax/inference/neural.py
probjax.inference.mcmc.imh.imh_data
¶
Rao-Blackwellised training data for :func:fit_adaptor.
The next position is the proposal with probability acceptance_rate and
the previous position otherwise, so both are stored with those weights.
Proposals the chain rejects still teach the proposal where the target is
not.
Source code in probjax/inference/mcmc/imh.py
Variational inference¶
probjax.inference.flow_vi
¶
Variational inference with a learned density as the variational family.
The objective is the reparameterised reverse KL, mean(log q(x) - log p(x))
over draws x from q. Each kernel step is one optimizer step, so the
fit runs through :func:~probjax.inference.run like any sampler:
family, params = density(maf(dim, 4, rngs=nnx.Rngs(0))) kernel = flow_vi(logdensity_fn, family, optax.adam(1e-3)) result = run(key, kernel, kernel.init(params), None, 2000, collect=("loss",)) fitted = result.state.params
Reverse KL is mode-seeking. A flow fitted this way tends to under-cover: on
Neal's funnel it concentrates in the neck and reports a smaller variance than the
truth. That is a property of the objective, not of this implementation, and it is
the reason :func:probjax.inference.neutra exists -- running MCMC in the flow's
latent space stays asymptotically exact however imperfect the flow is, so the
flow only has to be helpful, not correct.
FlowVIState
¶
FlowVIInfo
¶
Bases: NamedTuple
Per-step diagnostics.
Attributes:
| Name | Type | Description |
|---|---|---|
loss |
Array
|
|
Source code in probjax/inference/vi/flow_vi.py
flow_vi
¶
Fit family to logdensity_fn by reverse KL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Callable
|
the unnormalized target log-density, taking one position. |
required |
family
|
Density
|
the variational family; its |
required |
optimizer
|
GradientTransformation
|
an optax |
required |
num_samples
|
int
|
draws used to estimate the objective at each step. |
100
|
stl_estimator
|
bool
|
use the sticking-the-landing gradient estimator, which lowers gradient variance at no cost in bias. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Kernel
|
class: |
Kernel
|
from the family's params; the step takes no kernel params, so pass |
|
Kernel
|
|
Source code in probjax/inference/vi/flow_vi.py
probjax.inference.neutra
¶
Reparameterise logdensity_fn through a bijection T.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logdensity_fn
|
Callable
|
the unnormalized target log-density, taking one position. |
required |
bijection
|
Callable[[Any, Any], tuple[Any, Any]]
|
|
required |
params
|
Any
|
the bijection's parameters. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
NeuTraTransform
|
class: |
Source code in probjax/inference/vi/neutra.py
probjax.inference.FlowVIState
¶
probjax.inference.FlowVIInfo
¶
Bases: NamedTuple
Per-step diagnostics.
Attributes:
| Name | Type | Description |
|---|---|---|
loss |
Array
|
|
Source code in probjax/inference/vi/flow_vi.py
probjax.inference.NeuTraTransform
¶
Bases: NamedTuple
A target rewritten in a flow's latent coordinates.
Attributes:
| Name | Type | Description |
|---|---|---|
logdensity |
Callable
|
the pulled-back log-density, to hand to any kernel. |
forward |
Callable
|
maps latent draws back to the target's space. Accepts a single position or a leading batch of them. |
Source code in probjax/inference/vi/neutra.py
States and results¶
The types returned by the runners and kernels. Kernel State and Params are
blackjax's own types, re-exported for convenience and documented there.
probjax.inference.RunResult
¶
Bases: NamedTuple
The outcome of :func:~probjax.inference.run or a warmup.
trace maps each collected name to its values stacked over the kept
steps. A warmup policy stores its own diagnostics there instead.
Source code in probjax/inference/base.py
probjax.inference.Kernel
¶
Bases: NamedTuple
A pure transition and the functions needed to initialize it.
default_adaptation is an optional factory returning the kernel's
recommended adaptation policy (an Adaptor or a Warmup).
Runners use it when no explicit policy is passed; an explicitly
passed policy always wins.
Source code in probjax/inference/base.py
probjax.inference.Warmup
¶
Bases: NamedTuple
A finite initialization policy for a kernel and its parameters.
run(key, kernel, state, params, num_steps) returns a
:class:RunResult whose trace holds the policy's diagnostics.
Source code in probjax/inference/base.py
probjax.inference.Adaptor
¶
Bases: NamedTuple
A local parameter-adaptation state machine.
init receives (state, params). update consumes one completed
transition and can therefore be used during warmup or regular sampling.