definition overview

A belief is what travels along an edge of a factor graph and what sits on a variable: a representation of a probability distribution, or of a likelihood, over that variable’s space. Four concrete types exist, each with its own note: Trivial Belief, Dirac Belief, Gaussian Belief and Sample Belief. Their algebra is one operation, combine, the product of densities.

Sources: original to this vault (design); code: open_model.jl (AbstractBelief, DiracBelief, SampleBelief, TrivialBelief), beliefs.jl (GaussianBelief), messages.jl (combine, belief_distance, belief_logdensity)

Theory (CT-ML wiki): Giry Monad · Markov Category · Bayesian Inversion · Distribution Monad

What a belief is

Categorically, a belief on a variable is an element of , a state in a Markov category (for continuous spaces, the Giry monad). It is the prior of a Bayesian lens and the posterior that inference returns. On an edge it may also be a likelihood: a non-negative function that need not integrate to one, which is why some beliefs are allowed to be improper.

All belief types subtype LenticulumCore.AbstractBelief. The core package defines the three that need no linear algebra. GaussianBelief lives in the top-level Lenticulum package, which no lib/ package may depend on — the reason the equilibrium and diffusion factors cannot yet return Gaussian messages (DEQ as a Relation §5, The Diffusion Factor §5).

The four types

typerepresentswhereisexacttypical source
Trivial Beliefno information (the unit)LenticulumCoretruean unset message, the prior of a prior
Dirac Beliefa point mass, LenticulumCoretruean observation (a hard clamp), a point inference
Gaussian Belief in canonical form , possibly improperLenticulumfalse (the default)Gaussian factors, Laplace approximations
Sample Beliefa weighted particle setLenticulumCorefalsesamplers, the fallback

isexact says whether a computed belief is exact rather than approximate. It defaults to false so that silence never implies exactness; only the Trivial and Dirac beliefs override it. A Gaussian can be exact (on a linear-Gaussian tree it is), but the flag does not claim it.

The algebra: combine

Pooling two beliefs about one variable is the pointwise product of their densities, the sum–product step at a variable node (Messages are Inversions). Mycelium.combine implements exactly the cases it can do honestly:

combineresultwhy
Trivial with anythingthe otherthe unit
Gaussian with Gaussianadd exact, associative, commutative
Dirac with Gaussian, Sample or Trivialthe Diraca hard clamp is the limit and dominates
two equal Diracsthat Diracidempotent
two different Diracserrorcontradictory hard clamps are a modelling error
anything else (e.g. two Sample beliefs)errorneeds densities (belief_logdensity) and importance reweighting

So beliefs form a partial commutative monoid under combine, with the Trivial belief as unit and the Dirac beliefs as absorbing elements. Gaussians are the one family closed under it, which is why Gaussian belief propagation is exact on trees (The Linear Gaussian Chain).

Other operations

  • belief_distance(a, b) — how much a message changed, the convergence test of propagate!. It returns Inf whenever it cannot tell, so that a schedule never declares convergence it cannot verify.
  • belief_logdensity(b, x) — ; implemented for Gaussians only.
  • variable_entropy(b) — the entropy in the Bethe Free Energy; for Gaussians it can be negative.

Everything else one might do with beliefs (addition, mixture, logic, projection, tempering) is catalogued, with what each needs, in Belief Algebra.

Related: Messages are Inversions, Factor Graphs, Channels and Polarity, Inversions and Bayesian Lenses, Probabilistic Types

tab: Julia
**Docs:** [Lenticulum API](https://mathstruct.org/Lenticulum.jl/dev/packages/lenticulum/) · [Mycelium API](https://mathstruct.org/Lenticulum.jl/dev/packages/mycelium/)
```julia
using Lenticulum, LenticulumCore, Mycelium
using LenticulumCore: DiracBelief, TrivialBelief, SampleBelief
a = Gaussian(1.0, 4.0); b = Gaussian(3.0, 4.0)       # N(1, 4) and N(3, 4), stored as (η, Λ)
c = combine(a, b)                                     # pooling = adding canonical parameters
(belief_mean(c), belief_cov(c))                       # ≈ ([2.0], [2.0;;]): precision-weighted mean, halved variance
combine(TrivialBelief(), a) === a                     # true: the unit
u = uninformative(1); combine(u, a).η == a.η          # true: (0, 0) is the same unit in canonical form
combine(DiracBelief([0.5]), a)                        # the Dirac: a hard clamp dominates (Λ → ∞)
lik = GaussianBelief([2.0, 0.0], [1.0 0.0; 0.0 0.0])  # constrains x₁ only: an improper likelihood message
isproper(lik)                                         # false — fine for a message, not for a mean
belief_mean(combine(lik, Gaussian([0.0, 0.0], [1.0 0.0; 0.0 1.0])))   # ≈ [1.0, 0.0]: proper after a prior
```