mixle.inference.condition module

condition() / do() – generic conditioning and causal intervention over any fitted mixle model, regardless of how it is composed (composite / mixture / HMM / dependency-tree / Bayesian network / conditional / sequence / optional).

See notes/designs/M0.md for the full design: the recursive rule per combinator, the self-normalized-importance-sampling (SIR) fallback and its ESS receipt, and do()’s graph-surgery semantics. In one line: condition composes each family’s own closed-form conditioning surface where one already exists (MultivariateGaussianDistribution.condition, MixtureDistribution.conditional, HiddenMarkovModelDistribution’s forward-backward) and falls back to likelihood-weighted ancestral sampling – reusing each combinator’s own log_density/sampler – everywhere else; do severs the incoming edges of the assigned fields (graph surgery) rather than reweighting via Bayes.

Neither this module nor its callers modify any family’s internals – only their existing public surfaces are composed.

class ConditionReceipt(method, evidence_status='possible', log_evidence=None, sample_contract='full_record', ess=None, ess_ratio=None, n_particles=None, warnings=<factory>)[source]

Bases: object

What condition() actually did: the method used and (for SIR) the importance-sampling health.

Parameters:
  • method (str)

  • evidence_status (str)

  • log_evidence (float | None)

  • sample_contract (str)

  • ess (float | None)

  • ess_ratio (float | None)

  • n_particles (int | None)

  • warnings (list[str])

exception ImpossibleEvidenceError[source]

Bases: ValueError

Raised when log evidence has zero mass and no posterior exists.

class Posterior(*, sample_fn, log_density_fn, mean_fn, receipt, model=None, identity=None)[source]

Bases: object

A condition() result with one sampling contract across exact and approximate paths.

Distinct from mixle.stats.compute.posterior.Posterior (that hierarchy is for parameter/latent/predictive posteriors keyed by sample(rng)); this one is evidence conditioning within a fitted joint model, with the signature the M0 card specifies: sample(n) / log_density(partial_row) / mean(field) / .receipt.

sample(n) always returns complete records in the base model’s native record type, with evidence fields present and clamped. log_density scores assignments to unobserved fields only when the selected conditioning implementation has a valid density with respect to their base measure. Generic SIR intentionally does not invent one for mixed or categorical records.

Parameters:
  • sample_fn (Callable[[int, int | None], Any])

  • log_density_fn (Callable[[Any], float] | None)

  • mean_fn (Callable[[FieldPath], Any])

  • receipt (ConditionReceipt)

  • model (Any)

  • identity (tuple | None)

property possible: bool

Whether the evidence has nonzero probability under the conditioning model.

sample(n=1, *, seed=None)[source]

Draw n complete native records, including the clamped evidence fields.

Parameters:
Return type:

Any

log_density(partial_row)[source]

Log-density of an assignment to the unobserved fields under the posterior.

Parameters:

partial_row (Any)

Return type:

float

mean(field)[source]

Posterior mean of one unobserved field (same FieldPath/int used in evidence).

Parameters:

field (tuple[int, ...] | int)

Return type:

Any

condition(model, evidence, *, method='auto', n_particles=4096, seed=None)[source]

The posterior over model’s unobserved fields given evidence (see notes/designs/M0.md).

Parameters:
Return type:

Posterior

do(model, assignments)[source]

Sever the incoming edges of the assigned fields, then clamp them (Pearl’s do).

Returns a model of the same combinator family wherever possible (DependencyTreeDistribution, CompositeDistribution, MixtureDistribution) so it can be passed back through condition()/do(); for a HeterogeneousBayesianNetwork it returns the existing InterventionalNetwork (sample/expectation/distribution).

Parameters:
Return type:

Any