Skip to main content

tensorlogic_quantrs_hooks/vmp/
mod.rs

1//! Variational Message Passing (VMP) for conjugate exponential families.
2//!
3//! This module implements the algorithm of Winn & Bishop (2005) for the three
4//! families shipped in the v0.2.0 research preview — Gaussian (mean-unknown,
5//! precision-known), Categorical, and Dirichlet — along with their conjugate
6//! factor relationships (Gaussian observation, Gaussian step, Dirichlet-Categorical,
7//! Categorical observation).
8//!
9//! All updates happen in natural-parameter space. The engine drives a
10//! coordinate-ascent loop that monotonically increases the evidence lower bound
11//! (ELBO) until either |ΔELBO| or the L∞ residual of the natural-parameter
12//! vectors falls below the configured tolerance. Divergence (an ELBO decrease
13//! beyond `divergence_tolerance`) surfaces as a [`crate::PgmError::ConvergenceFailure`]
14//! so a numerically broken run never silently returns a garbage posterior.
15//!
16//! # Module map
17//!
18//! | Submodule             | Purpose                                                    |
19//! |-----------------------|------------------------------------------------------------|
20//! | [`exponential_family`]| Trait contract every VMP-compatible distribution satisfies |
21//! | [`distributions`]     | `GaussianNP`, `CategoricalNP`, `DirichletNP` + KL helpers  |
22//! | [`messages`]          | `VmpMessage` / `MessageDirection` primitives               |
23//! | [`engine`]            | `VmpConfig` + `VariationalMessagePassing` coordinate engine|
24//! | [`special`]           | Local `ln_gamma` / `digamma` (scirs2-core free)            |
25//!
26//! # Minimal example
27//!
28//! ```
29//! use tensorlogic_quantrs_hooks::vmp::{
30//!     VariationalMessagePassing, VmpConfig, VmpFactor,
31//! };
32//!
33//! // y ~ N(μ, 1) with one observation y = 3, prior μ ~ N(0, 1).
34//! let config = VmpConfig::new()
35//!     .with_gaussian("mu", 0.0, 1.0).expect("register mu")
36//!     .with_factor(VmpFactor::GaussianObservation {
37//!         target: "mu".to_string(),
38//!         observation: 3.0,
39//!         precision: 1.0,
40//!     })
41//!     .with_limits(50, 1e-8);
42//!
43//! let mut engine = VariationalMessagePassing::new(config).expect("engine");
44//! let result = engine.run().expect("run");
45//! assert!(result.converged);
46//! ```
47//!
48//! # References
49//!
50//! - Winn, J. M. & Bishop, C. M. (2005). *Variational Message Passing*.
51//!   Journal of Machine Learning Research 6, 661-694.
52
53pub mod beta;
54pub mod distributions;
55pub mod engine;
56pub mod exponential_family;
57pub mod gamma;
58pub mod messages;
59pub mod special;
60
61#[cfg(test)]
62mod tests;
63
64pub use beta::{BetaBernoulliObservation, BetaNP};
65pub use distributions::{
66    categorical_kl, dirichlet_kl, gaussian_kl, gaussian_kl_fixed_precision, CategoricalNP,
67    DirichletNP, GaussianNP,
68};
69pub use engine::{
70    Family, VariationalMessagePassing, VariationalState, VmpConfig, VmpFactor, VmpResult,
71};
72pub use exponential_family::ExponentialFamily;
73pub use gamma::{GammaNP, GammaPoissonObservation};
74pub use messages::{MessageDirection, VmpMessage};