mixle.inference.planning module

Estimation planning and certificates.

Mixle chooses estimation methods from model structure: exponential-family leaves use closed-form MLE when available, conditional-linear-Gaussian factors use least squares, GLM factors use IRLS, categorical tables use count updates, and non-convex pieces such as mixtures or neural leaves use EM or gradient optimization.

This module makes those choices inspectable. It walks a fitted model or distribution prototype and returns an EstimationCertificate containing per-block methods, guarantees, and placement hints. The aggregate guarantee is the minimum over all blocks, so a fully observed exponential-family graph can certify as GLOBAL_UNIQUE while a mixture certifies as STATIONARY even when each M-step is closed form.

The guarantee ladder, in ascending strength, is HEURISTIC, STATIONARY, STATIONARY_ESCAPE_TESTED, GLOBAL, and GLOBAL_UNIQUE.

class Guarantee(*values)[source]

Bases: IntEnum

How strong the solution to an estimation block is, as an ordered ladder (higher = stronger).

HEURISTIC = 1
STATIONARY = 2
STATIONARY_ESCAPE_TESTED = 3
GLOBAL = 4
GLOBAL_UNIQUE = 5
property label: str
class BlockPlan(name, kind, method, guarantee, gradient, placement, reason)[source]

Bases: object

The estimation plan for one block of a model: which method ran and how strong its guarantee is.

Parameters:
  • name (str)

  • kind (str)

  • method (str)

  • guarantee (Guarantee)

  • gradient (bool)

  • placement (str)

  • reason (str)

name: str
kind: str
method: str
guarantee: Guarantee
gradient: bool
placement: str
reason: str
class EstimationCertificate(guarantee, blocks=<factory>, escape_tested=False)[source]

Bases: object

The auditable proof of how a model was (or would be) estimated: per-block plans + the aggregate.

guarantee is the minimum over blocks. why_not_adam summarizes where gradient optimization was used and why those blocks could not use a stronger closed-form or convex route.

Parameters:
  • guarantee (Guarantee)

  • blocks (list[BlockPlan])

  • escape_tested (bool)

guarantee: Guarantee
blocks: list[BlockPlan]
escape_tested: bool = False
property gradient_blocks: list[BlockPlan]
property closed_form_blocks: list[BlockPlan]
as_dict()[source]
Return type:

dict[str, Any]

why_not_adam()[source]

The audit: which blocks needed gradient descent and why – everything else got a stronger method.

Return type:

str

table()[source]
Return type:

str

class EstimationSchedule(passes=<factory>, latent=False)[source]

Bases: object

The block-coordinate schedule planner v2 produces (A3): ordered passes + the loop structure.

A fully-factorized model schedules one independent pass per block (no loop). A latent model schedules the EM loop explicitly: an E-step over the latent, then one M-step pass PER BLOCK per round – each M-step named with its own method, so the schedule shows exactly where the closed forms live inside the iteration (and which pass, if any, is the gradient block a pool would take).

Parameters:
  • passes (list[SchedulePass])

  • latent (bool)

passes: list[SchedulePass]
latent: bool = False
property per_round: list[SchedulePass]
property gradient_passes: list[SchedulePass]
describe()[source]
Return type:

str

class SchedulePass(order, kind, block, method, placement, repeat)[source]

Bases: object

One pass of the estimation schedule: what runs, on which block, how, where, and how often.

Parameters:
order: int
kind: str
block: str
method: str
placement: str
repeat: str
certify(model, *, escape_tested=False, penalized=False)[source]

Return the EstimationCertificate for a fitted model (or distribution prototype).

Walks the model’s block structure and classifies each block’s estimation method + guarantee from its capability signals – no fitting is done here, only inspection. Pass escape_tested=True when the fit ran saddle-escape restarts (mixle.Model.fit() sets this automatically), which upgrades EM blocks from STATIONARY to STATIONARY_ESCAPE_TESTED.

Pass penalized (a reason string, or True) when the fit optimized a PENALIZED objective – soft constraints, conservation/PINN residual factors, potentials (E2). The optimum is then of the penalized surrogate, NOT the likelihood, so no block may claim more than STATIONARY however clean its own solver is: every stronger block is downgraded with the penalty named in its reason.

Parameters:
Return type:

EstimationCertificate

plan_estimation(model, *, escape_tested=False)[source]

Alias for certify() – the pre-fit planning view over a distribution prototype.

Parameters:
Return type:

EstimationCertificate

schedule(model, *, escape_tested=False)[source]

Plan the block-coordinate estimation schedule for model (planner v2, A3).

Built from the same block classification as certify(): EM blocks make the schedule a loop (E-step + per-block M-steps, repeated until convergence); without a latent block every block is one independent pass. Gradient blocks appear as explicit gradient passes with their pool placement, so the schedule is also the offload plan for the hybrid case.

Parameters:
Return type:

EstimationSchedule