mixle.reason.core module

The reasoning front door: fuse modality evidence into a belief, query it with native UQ.

reason(prior, evidence) folds a sequence of linear-Gaussian observations into a belief state by exact Kalman assimilation, tracking how many nats of uncertainty each modality removed. The returned ReasonedAnswer is the posterior belief plus the tools a scientific answer needs: credible intervals, per-modality attribution, and an epistemic/aleatoric split of any prediction.

class Latent[source]

Bases: object

Factories for the shared latent’s prior belief (the starting point of assimilation).

static gaussian(mean, cov)[source]

A Gaussian prior N(mean, cov) over the latent.

Parameters:
Return type:

GaussianBelief

static vector(dim, *, mean=0.0, var=1.0)[source]

An isotropic Gaussian prior over a dim-vector latent: N(mean*1, var*I).

Parameters:
Return type:

GaussianBelief

static mechanistic(A, steps, *, x0_mean=None, x0_cov=None, process_cov=None)[source]

A physics-constrained prior over a latent trajectory z_0 .. z_{steps-1}.

The trajectory follows a linear dynamical law z_{t+1} = A z_t + w_t, w_t ~ N(0, Q) – a discretized linear ODE/PDE (A is the state-transition operator; take it from a mixle_pde DynamicsOperator for real physics). The returned belief is the exact joint Gaussian over the stacked trajectory (steps * d,) (block t is z_t); its block-tridiagonal precision is the mechanistic prior. Because the states are coupled, evidence at any one time informs all times through the dynamics – fusing observations via reason() is then exact Kalman smoothing, so a sparsely-observed field is filled in by the physics, not by a generic smoothness assumption.

Parameters:
  • A (Any) – (d, d) linear state-transition operator (one discrete step).

  • steps (int) – number of time steps T in the trajectory.

  • x0_mean (Any) – mean of z_0 (default zeros).

  • x0_cov (Any) – covariance of z_0 (default identity).

  • process_cov (Any) – process-noise covariance Q (default zeros – deterministic dynamics).

Return type:

GaussianBelief

class LinearGaussianEvidence(H, y, R, name='')[source]

Bases: object

One modality’s evidence about the latent z: y = H z + noise, noise ~ N(0, R).

H is the (possibly linearized) forward operator mapping the latent to this modality’s measurement space, y the observed data, R its noise covariance (matrix, diagonal, or scalar). Application forward models (e.g. mixle_pde geophysics operators) produce these.

Parameters:
H: Any
y: Any
R: Any
name: str = ''
Evidence

Short alias – Evidence(H, y, R, name).

class NonlinearEvidence(h, y, R, jacobian=None, iterations=2, name='')[source]

Bases: object

One modality’s evidence through a NONLINEAR forward model: y = h(z) + noise.

Assimilated by (iterated) extended-Kalman linearization: at the current belief mean m the forward is replaced by its tangent h(z) ~ h(m) + J(m)(z - m) and the exact linear update runs on that tangent; with iterations > 1 the linearization point is refined at the updated mean and the update repeats FROM THE PRE-UPDATE BELIEF (the iterated EKF), which matters when the prior mean is far from the truth. jacobian is analytic when you have it; otherwise a central finite difference is used. Honest caveat: this is a Gaussian approximation around the linearization point – for strongly multimodal posteriors it reports one mode’s belief, not the mixture.

Parameters:
h: Any
y: Any
R: Any
jacobian: Any = None
iterations: int = 2
name: str = ''
block_selector(step, n_blocks, block_dim, within=None)[source]

An observation matrix that reads time-block step of a stacked trajectory latent.

For a latent built by Latent.mechanistic() (shape (n_blocks * block_dim,)), returns the H selecting block step – use it to build LinearGaussianEvidence for an observation at that time. within optionally reads only part of the block (a (k, block_dim) local readout); by default the whole block is read (identity).

Parameters:
Return type:

ndarray

class ReasonedAnswer(belief, prior_entropy, contributions)[source]

Bases: object

A posterior belief about a query, with the UQ a scientific answer needs.

Beyond mean / interval / entropy (delegated to the belief), it exposes attribution() – the nats of uncertainty each modality removed – and predict(), which splits a prediction’s uncertainty into epistemic (from latent uncertainty) and aleatoric (observation noise) via the law of total variance.

Parameters:
property mean: ndarray
cov()[source]
Return type:

ndarray

sd()[source]
Return type:

ndarray

entropy()[source]
Return type:

float

interval(level=0.9)[source]

Per-coordinate central credible interval at level (an (d, 2) array of [lo, hi]).

Parameters:

level (float)

Return type:

ndarray

information_gain()[source]

Total nats of uncertainty the evidence removed from the prior (H[prior] - H[posterior]).

Return type:

float

attribution(*, normalize=False)[source]

Per-modality information gain in nats – which modality sharpened the belief, and by how much.

With normalize=True, values are the fraction of the total gain (they then sum to ~1).

Parameters:

normalize (bool)

Return type:

dict[str, float]

predict(H, R=0.0)[source]

Split the uncertainty of a new prediction y* = H z + noise(R) (law of total variance).

epistemic = diag(H P Hᵀ) (from the latent’s remaining uncertainty, reducible by more data) and aleatoric = diag(R) (irreducible observation noise). Exact for the Gaussian belief.

Parameters:
Return type:

UncertaintyDecomposition

marginal(indices)[source]

Restrict the answer to a subset of latent coordinates (query a specific variable).

Parameters:

indices (Any)

Return type:

ReasonedAnswer

reason(prior, evidence, *, query=None)[source]

Fuse evidence into prior by exact Kalman assimilation; return the queried posterior.

Parameters:
  • prior (Any) – the latent’s prior belief (GaussianBelief; build one with Latent).

  • evidence (Any) – a sequence of LinearGaussianEvidence and/or NonlinearEvidence – one per modality / observation. Nonlinear items assimilate by iterated-EKF linearization (a Gaussian approximation; see NonlinearEvidence). They are folded in one at a time (order does not affect the result), and the nats each removes are recorded for ReasonedAnswer.attribution().

  • query (Any) – optional latent coordinate indices to restrict the answer to.

Returns:

A ReasonedAnswer – the posterior belief plus attribution and prediction UQ.

Return type:

ReasonedAnswer