bayesmith.graph.graph
Source-derived signatures and contracts. See the reference index for coverage and conventions.
Module contract
The graph container, and the structural rules it refuses to violate. Declaration order **is** topological order. A node may only name parents already declared, which is automatic when the graph comes from ``trace`` -- you cannot pass a ``NodeRef`` you have not created -- and is checked here so that a hand-built graph obeys the same rule.
Plate
Defined in bayesmith.graph.graph, line 21.
class Plate(eqx.Module)
name: str = eqx.field(static=True)
size: int = eqx.field(static=True)A named repetition axis. ``size`` is fixed at construction.
Graph
Defined in bayesmith.graph.graph, line 28.
class Graph(eqx.Module)
nodes: tuple[Node, ...]
plates: tuple[Plate, ...]
joint_prior: Any = None
evidence_terms: tuple[Any, ...] = ()A static DAG of nodes in topological order, plus its plates.
Attributes:
nodes: every node, in topological order.
plates: the repetition axes the nodes may live inside.
joint_prior: a density over SEVERAL latents at once, or ``None``. A
latent's own ``dist_fn`` says what one quantity is a priori and is
the only per-latent prior the rest of the package needs; a Jeffreys
prior is not of that shape -- it is one density over a named block,
a function of the forward model and the noise rather than of the
latents alone. Declaring it HERE is what lets
:func:`~bayesmith.graph.evaluate.log_joint` and
:func:`~bayesmith.bridge.numpyro_bridge.to_numpyro` both find it,
so the two scans of one graph cannot target different posteriors.
Structural only at this layer: this module is the core and imports
nothing from ``diagnose``, so what is checked here is that the
object answers ``over`` and ``log_density`` and that its block
names latents this graph declares. Everything else --
identifiability, the double-prior refusal -- belongs to
:class:`~bayesmith.diagnose.priors.JeffreysPrior` and fires where
it is evaluated.
evidence_terms: likelihood factors produced by graph reduction. Each
answers ``over`` and ``log_density(graph, values)``. Unlike a
``joint_prior``, these terms require the retained latents to keep
their own priors, so the two blocks must be disjoint.Graph.names
names(self) -> tuple[str, ...]Every node name, in topological order.
Graph.latents
latents(self) -> tuple[str, ...]Names of the probabilistic nodes that are inferred.
Graph.observed
observed(self) -> tuple[str, ...]Names of the probabilistic nodes that are conditioned on.
Graph.node
node(self, name: str) -> NodeThe node called ``name``.
Raises:
GraphError: if no node has that name.Graph.plate_size
plate_size(self, name: str) -> intThe declared size of plate ``name``.
Raises:
GraphError: if no plate has that name.