Skip to content

Fit and sample

TL;DR

from menobis.models import Constraint, Ensemble, ModelFamily, fit_model, sample_model

fit = fit_model(
    family=ModelFamily.ME,
    constraint=Constraint.STRENGTH,
    strength_out=strength_out,
    strength_in=strength_in,
)
if not fit.converged:
    raise RuntimeError(fit.status)

sample = sample_model(
    ensemble=Ensemble.GRAND_CANONICAL,
    family=ModelFamily.ME,
    constraint=Constraint.STRENGTH,
    fit=fit,
    seed=0,
)

Fit

fit_model selects the route by family, constraint, and optional ensemble (default grand canonical) and returns a typed fit result (e.g. StrengthFit, StrengthCostFit, StrengthEdgesFit, StrengthDegreeFit, DegreeEventsFit, EdgesEventsFit). Fit results expose at least:

  • fit.converged — solver convergence flag;
  • fit.status — human-readable solver status;
  • fit.self_loops — the self-loop policy used;
  • family-specific Lagrange multipliers (x, y; lam; z, w; gamma; q; occupation) — rarely needed by users.

Always check fit.converged before sampling. An unconverged fit must not be silently sampled; the exact failure text is in fit.status.

Constraints must be feasible for the chosen model. Derive them from a valid witness network when possible (see Getting started); hand-picked sequences are easy to make infeasible.

Sample

sample_model returns an EdgeTable — the sparse occupied-pair table with columns source target occ_num.

For metadata about the draw, use sample_model_detailed:

from menobis.routing import sample_model_detailed

result = sample_model_detailed(
    ensemble=Ensemble.GRAND_CANONICAL,
    family=ModelFamily.ME,
    constraint=Constraint.STRENGTH,
    fit=fit,
    seed=0,
)
edges = result.edges          # EdgeTable
diagnostics = result.diagnostics
print(diagnostics.exactness)  # generation category (see below)

result.diagnostics.exactness states how exact the draw is:

  • exact_independent — grand-canonical: per-pair draws from the fitted law;
  • exact_direct — direct sampler from the target distribution (canonical and microcanonical (E,T) routes);
  • exact_stationary_mcmc — validated MCMC kernel; finite-run burn-in and mixing still matter (see MCMC diagnostics).

Seeds and reproducibility

Sampling is deterministic given the seed argument: the same call with the same seed and the same fit yields the same EdgeTable. Use different seeds to generate an ensemble of independent draws.

Canonical

For canonical sampling (ME + STRENGTH), pass the fitted model plus the total occupation to fix:

sample = sample_model(
    ensemble=Ensemble.CANONICAL,
    family=ModelFamily.ME,
    constraint=Constraint.STRENGTH,
    fit=fit,
    total_events=total_events,
)

Canonical fixes total occupation \(T\) exactly; strengths stay soft fitted quantities.

Microcanonical

Microcanonical routes sample directly from constraints and need no fit:

sample = sample_model(
    ensemble=Ensemble.MICROCANONICAL,
    family=ModelFamily.ME,
    constraint=Constraint.STRENGTH,
    strength_out=strength_out,
    strength_in=strength_in,
)

See Microcanonical sampling for the per-route arguments and exactness.

Shared entry point

All three verbs route through route_model(verb, ensemble=..., family=..., constraint=..., **kwargs). The dedicated functions fit_model, sample_model, sample_model_detailed, and filter_model are the documented public endpoints.

Filtering

Filtering compares observed edges against the fitted null: see Filter node pairs.