tidal.inference package#
Bayesian inference for TIDAL parameter estimation.
Wraps the existing simulation + measurement pipeline as a likelihood function for Monte Carlo and nested sampling. Nested sampling uses PolyChord (Handley et al. 2015) with anesthetic (Handley 2019) for analysis and visualization.
Setup:
pip install tidal[inference] # anesthetic only
bash scripts/install_polychord.sh # PolyChord (requires gfortran)
References
Skilling, J. (2004) “Nested Sampling”, AIP Conference Proceedings 735. Handley, W. et al. (2015) “PolyChord: next-generation nested sampling”, MNRAS 453. Handley, W. (2019) “anesthetic: nested sampling visualization”, JOSS 4.
- class tidal.inference.ConstraintSet(constraints=<factory>, expressions=<factory>)[source]#
Bases:
objectA collection of parameter constraints combined with logical AND.
- Parameters:
- class tidal.inference.InferenceResult(samples, log_likelihood, log_prior, param_names, method, metrics=None, log_evidence=None, log_evidence_err=None, weights=None, metadata=<factory>)[source]#
Bases:
objectContainer for inference samples and diagnostics.
- Parameters:
samples (NDArray) – Parameter samples, shape
(n_samples, n_params).log_likelihood (NDArray) – Log-likelihood for each sample, shape
(n_samples,).log_prior (NDArray) – Log-prior for each sample, shape
(n_samples,).method (str) – Sampling method:
"mc"or"nested".metrics (dict[str, NDArray] | None) – Additional simulation metrics per sample (P_max, etc.).
log_evidence (float | None) – Log-evidence (nested sampling only).
log_evidence_err (float | None) – Uncertainty on log-evidence (nested sampling only).
weights (NDArray | None) – Importance weights for nested sampling, shape
(n_samples,).metadata (dict) – Additional metadata (sampler settings, wall time, etc.).
- effective_sample_size()[source]#
Kish effective sample size from weights.
For unweighted MC samples, returns
n_samples. For nested sampling, uses importance weights.Reference: Kish, L. (1965) Survey Sampling, Wiley.
- Return type:
- classmethod from_directory(path)[source]#
Load inference results from a saved directory.
Expects
inference.jsonandresults.csvas written bysave().- Parameters:
path (Path) – Directory containing saved inference results.
- Return type:
- property log_posterior: NDArray[np.float64]#
Log-posterior = log-prior + log-likelihood.
- parameter_importance(n_bootstrap=100)[source]#
Compute parameter importance via KL divergence.
Uses anesthetic to compute total and per-parameter information gain from prior to posterior, plus Bayesian model dimensionality.
- Parameters:
n_bootstrap (int) – Number of bootstrap samples for uncertainty estimation.
- Return type:
- posterior_mean()[source]#
Return the posterior mean parameter values.
For nested sampling, uses importance-weighted mean.
- save(output_dir)[source]#
Save inference results to disk.
Writes: -
results.csvandresults.jsonvia SweepResults -inference.jsonwith evidence, ESS, and summary statistics- Parameters:
output_dir (Path)
- Return type:
None
- to_anesthetic()[source]#
Convert to anesthetic
NestedSamplesfor custom analysis.Returns the native anesthetic object with
.D_KL(),.d_G(),.logZ(),.plot_2d()etc.- Return type:
- to_sweep_results()[source]#
Convert to a
SweepResults.This allows reusing the existing CSV/JSON serialization infrastructure.
- Return type:
SweepResults
- samples: NDArray[np.float64]#
- log_likelihood: NDArray[np.float64]#
- log_prior: NDArray[np.float64]#
- class tidal.inference.ParameterImportanceResult(param_names, d_kl, d_kl_err, d_g, d_g_err, marginal_d_kl, log_evidence, log_evidence_err, consistency=<factory>)[source]#
Bases:
objectResults from parameter importance analysis.
- Parameters:
d_kl (float) – Total KL divergence (nats) — information gained from prior to posterior.
d_kl_err (float) – Bootstrap uncertainty on D_KL.
d_g (float) – Bayesian model dimensionality — effective number of constrained parameters.
d_g_err (float) – Bootstrap uncertainty on d_G.
marginal_d_kl (dict[str, float]) – Per-parameter marginal KL divergence (nats). High D_KL means the data strongly constrains that parameter.
log_evidence (float) – Log Bayesian evidence (log Z).
log_evidence_err (float) – Bootstrap uncertainty on log Z.
consistency (dict[str, Any]) – Self-check diagnostics for the marginal estimates (#420/#433):
sum_marginals,superadditivity_ok(for a product prior the chain rule givesD_KL(joint) >= sum of marginalsexactly, so a violating sum means the estimator is broken),superadditivity_applicable(Falsewhen the low-n_effbias allowance dwarfs the signal and “ok” would be vacuous),bias_allowance/tolerance(the check’s actual power),product_prior(whether the bound is exact for this run),saturated_params(marginals within 90% of the histogram ceilinglog(n_bins)— resolution-limited values),n_eff(Kish effective sample size of the posterior weights),noise_floor(per-parameter estimator bias(n_bins - 1)/(2 n_eff)— a marginal at or below its floor is noise, not constraint),floor_dominated_params(the names that fail that test),fallback_params(names scored against an empirical sample-range reference instead of their prior — unreliable),range_clipped(names with posterior mass outside the recorded prior range, mapped to the clipped weight fraction — the prior record does not describe the samples), andnote. Empty dict when marginals could not be computed.
- class tidal.inference.Prior(name, distribution, low, high)[source]#
Bases:
objectA 1-D marginal prior distribution.
- Parameters:
name (str) – Parameter name (must match the JSON spec’s parameter key).
distribution (str) – One of
"uniform","log_uniform","normal","arctan_uniform".low (float) – Lower bound (for uniform/log_uniform) or mean (for normal). Ignored for arctan_uniform — see below.
high (float) – Upper bound (for uniform/log_uniform) or std (for normal). Ignored for arctan_uniform — see below.
Notes
arctan_uniformdoes NOT uselow/high(GH #425): the angle is uniform on the fixed eps-truncated range(-pi/2 + _ARCTAN_EPS, +pi/2 - _ARCTAN_EPS), so the support is always|x| <= tan(pi/2 - _ARCTAN_EPS) ~= 19.98regardless of the recorded bounds. AUserWarningfires at construction when the given bounds differ from that implied support; pass0:0(the sanctioned sentinel used in the docs) to declare the bounds deliberately unused without warning. Honoring the bounds would silently redefine the prior for every archived chain whose metadata records these unused numbers, so any change must be versioned — deliberately deferred, see the options in GH #425.- property effective_support: tuple[float, float]#
The range
sample()actually draws from — not what was typed.Thin accessor for
effective_support(); see it for the per-distribution contract and the defects that motivated it.
- sample(rng, n)[source]#
Draw n samples from this prior.
- Parameters:
rng (np.random.Generator)
n (int)
- Return type:
NDArray[np.float64]
- tidal.inference.parse_constraint(expr)[source]#
Parse a constraint expression string into a callable.
- Parameters:
expr (str) – A comparison expression, e.g.
"xi > 0"or"deltam**2 < 2*alpha*xi".- Returns:
A function
(params: dict[str, float]) -> boolthat returns True if the constraint is satisfied.- Return type:
callable
- Raises:
ConstraintError – If the expression cannot be parsed safely.