tbnpy.adaptiveMH¶
Overview¶
This module implements an adaptive, tensorised Metropolis–Hastings (MH) sampler for hybrid Bayesian networks containing both discrete and continuous variables.
Key design features:
Supports many evidence rows and many parallel chains simultaneously.
Uses tensorised log-probability evaluation for efficiency.
Handles hybrid variables: - discrete variables via symmetric adaptive categorical proposals, - continuous variables via Gaussian random-walk proposals.
Adapts proposal parameters during burn-in using Robbins–Monro updates.
The sampler is factor-based: each probability object (typically
Cpt) is treated as a factor contributing to the joint log-probability.
Glossary¶
n_evi: number of evidence rows.
n_chain: number of parallel MCMC chains.
state: dictionary mapping
var_name -> tensor (n_evi, n_chain).evidence_1d: dictionary mapping
var_name -> tensor (n_evi,).factor: a probability object defining a local conditional distribution.
Utility functions¶
Variable type helpers¶
- is_discrete(var) bool¶
Return
Trueifvarrepresents a discrete variable (i.e.var.valuesis a list).
- is_continuous(var) bool¶
Return
Trueifvarrepresents a continuous variable (i.e.var.valuesis a tuple).
- num_categories(var) int¶
Return the number of discrete categories of
var. Raises an assertion error ifvaris not discrete.
Factor construction utilities¶
- build_Cs_3d(prob, state: dict, evidence_1d: dict) torch.Tensor¶
Build a 3D tensor of composite states for a probability object.
Parameters¶
- prob
Probability object with attributes
childsandparents.- state
Dictionary mapping latent variable names to tensors of shape
(n_evi, n_chain).- evidence_1d
Dictionary mapping observed variable names to tensors of shape
(n_evi,).
Returns¶
- torch.Tensor
Tensor of shape
(n_evi, n_chain, n_childs + n_parents)in column order:[child_0, ..., child_{n_childs-1}, parent_0, ..., parent_{n_parents-1}]
Notes¶
Evidence variables are broadcast across chains. Latent variables are taken from
state.
Proposal kernels¶
Discrete proposals¶
- propose_discrete_adaptive(x: torch.Tensor, logits: torch.Tensor, alpha: float) torch.Tensor¶
Symmetric adaptive proposal for a discrete variable.
Parameters¶
- x
Current state, shape
(n_evi, n_chain), integer in[0, K-1].- logits
Global adaptive logits of shape
(K,).- alpha
Mixing weight between local and global proposals (
0 < alpha < 1).
Returns¶
- torch.Tensor
Proposed state, same shape as
x.
Notes¶
The proposal is a mixture of:
local move: uniform jump to any other category,
global move: draw from a learned categorical distribution.
The mixture remains symmetric, preserving MH correctness.
Continuous proposals¶
Adaptation configuration¶
- class AdaptConfig¶
Configuration parameters for adaptive MH.
Attributes¶
- burninint
Number of iterations during which adaptation is active.
- gammafloat
Robbins–Monro exponent (typically in
(0.5, 1]).- target_acceptfloat
Target acceptance rate for continuous proposals.
- min_log_sigma, max_log_sigmafloat
Bounds for continuous proposal scales.
- alphafloat
Mixing weight for discrete proposals.
HybridAdaptiveMH¶
- class HybridAdaptiveMH¶
Adaptive Metropolis–Hastings sampler for hybrid Bayesian networks.
The sampler maintains a latent state:
state[var_name]has shape(n_evi, n_chain)evidence variables are fixed and broadcast across chains
Each MH step updates one variable (or block) at a time.
Initialisation¶
- HybridAdaptiveMH.init_state_from_forward_samples(probs_copy: dict)¶
Initialise latent state from forward-sampling output (e.g. produced by
tbnpy.inference).Parameters¶
- probs_copy
Dictionary of probability objects where each object has:
prob.Csof shape(n_evi, n_chain, dim)prob.psof shape(n_evi, n_chain)
- HybridAdaptiveMH.init_state_random(seed: int | None = None)¶
Initialise latent state randomly.
Discrete variables are drawn uniformly; continuous variables are drawn from a standard normal distribution.
Core MCMC update¶
- HybridAdaptiveMH.mh_update_block(vars: list, iteration: int) torch.Tensor¶
Perform one MH update for a block of variables.
Parameters¶
- vars
List of variables to update jointly.
- iteration
Current iteration index (used for adaptation).
Returns¶
- torch.Tensor
Boolean tensor of shape
(n_chain,)indicating accepted chains.
Running the sampler¶
- HybridAdaptiveMH.run(n_iter: int, update_blocks: list[list[str]] | None = None, store_every: int = 0, progress_every: int = 100) dict¶
Run the adaptive MH sampler.
Parameters¶
- n_iter
Number of MCMC iterations.
- update_blocks
Optional variable blocks (by name) to update jointly.
- store_every
Thinning interval for storing full latent states (can be memory intensive).
- progress_every
Print progress every given number of iterations.
Returns¶
- dict
Dictionary containing:
accept_rate: per-block acceptance rateslogp_chain: final log-probability per chainlogp_evi_chain: final log-probability per evidence×chainlog_sigma: learned proposal scales for continuous variablesstates_thinned(optional) : stored latent states