mixle.reason.cross_modal module

Cross-modal reasoning as conditional inference in a shared-latent joint (workstream L2).

The loop this module runs – discrepancy -> propose -> verify -> adopt -> remember – is generic across altitudes; L2’s edge is that “cross-modal” needs no bespoke machinery here. A composite over heterogeneous fields (one Gaussian field standing in for an “image embedding,” one Categorical field standing in for a “text label,” etc.) already ties every field to a single shared latent regime the moment those fields are wrapped as one CompositeDistribution and mixed over a component index via MixtureDistribution – the component index is the shared latent regime spanning modalities, and per-component parameter keys= ties (see MixtureEstimator) are the same mechanism used to pool statistics across otherwise-independent per-modality estimators when fitting such a joint.

MixtureDistribution.conditional already implements “condition on any subset, infer any other subset” for exactly this shape of joint: it returns the full posterior mixture over the unobserved coordinates, itself scoreable and sampleable. CrossModalJoint is a thin, name-addressed wrapper around that machinery so callers condition on modality NAMES (“image”, “text”, …) instead of bare composite field indices, and so a further subset of the remaining fields can be requested (not just “everything unobserved”).

class CrossModalJoint(names, joint)[source]

Bases: object

A joint over named modalities sharing one latent regime (a mixture component index).

names fixes the modality-name -> composite-field-index mapping; joint is a MixtureDistribution whose components are CompositeDistribution instances over len(names) heterogeneous fields, in names order. The mixture weights are the shared latent’s prior p(regime); each component is p(modality_0, modality_1, ... | regime=k).

Parameters:
  • names (tuple[str, ...])

  • joint (MixtureDistribution)

classmethod from_components(names, component_fields, weights)[source]

Build a shared-latent joint from per-regime per-modality distributions.

component_fields[k] is the sequence of len(names) per-modality distributions for latent regime k (in names order); weights[k] is p(regime=k). Each regime is wrapped as one CompositeDistribution over the (heterogeneous) modality fields and the regimes are mixed, so the resulting joint’s own component index is exactly the shared latent tying every modality together.

Parameters:
Return type:

CrossModalJoint

infer(observed, target=None)[source]

Posterior over target modalities given observed values for any OTHER subset.

observed maps modality name -> its observed value, for any subset (including the empty set, which returns the marginal/prior). target names the modalities to infer the joint posterior over; defaults to every modality not in observed. Every target name must be absent from observed (you cannot condition on and infer the same modality).

Returns a MixtureDistribution over a len(target)-tuple, in target order (a 1-modality target is a mixture over a 1-tuple, matching CompositeDistribution’s own convention for a single field).

Parameters:
Return type:

MixtureDistribution