mixle.inference.torsion module¶
Twisted composition for mixture components with a shared base density.
Mixture components can share one base density modulo a declared group action,
instead of each independently learning a density from scratch on its own slice
of data. Concretely, CyclicGroup
acts on a periodic coordinate by rotation of its (cos, sin) embedding (an exact, Jacobian-1 change of
variables, so a fitted embedding density scores identically whichever group element aligned a point into it);
fit_twisted_mixture() pools every group’s data into ONE shared base density after undoing each group’s
twist, so the shared density is fit on the union – effectively |groups| times the data for the same
parameter count as fitting one group alone.
Use this as an experimental modeling option. If the shared-base model does not beat independently fit per-group models at matched per-component capacity on held-out per-group log likelihood, keep the independent baseline as the default.
- class CyclicGroup(order, period=1.0)[source]
Bases:
objectZ_``order`` acting on a periodic real-valued coordinate of period
periodby rotation.Each group element
kin{0, ..., order - 1}is realized concretely as a rotation of the coordinate’s(cos, sin)embedding by angle2*pi*k/order– an orthogonal (norm- and Jacobian-preserving) transform, so composing group elements is exactly addition modorder(compose()), and a density fit on the embedding is unaffected by which element aligned a point into it (the twist is undone before scoring, not baked into the density).- embed(x)[source]
The periodic coordinate’s
(cos, sin)embedding, shape(..., 2).
- act(embedded, k)[source]
Rotate an
(..., 2)embedding by group elementk(the forward twist).
- inverse_act(embedded, k)[source]
Undo group element
k’s twist –act(inverse_act(v, k), k) == v.
- class TwistedMixtureResult(base_density, group)[source]
Bases:
objectA single shared base density plus the group whose elements twist it into each group’s local factor.
- Parameters:
base_density (Any)
group (CyclicGroup)
- fit_twisted_mixture(group, data_by_group, *, n_components=2, seed=0, max_its=50)[source]
Fit ONE base density on every group’s data pooled together after undoing each group’s twist.
data_by_groupmaps a group elementkto that group’s (small) sample of the periodic coordinate. Every sample is embedded and rotated back by its own group’sinverse_actbefore pooling – so the fittedn_components-component density seessum(len(v) for v in data_by_group.values())points, not just one group’s slice, for the same parameter count asfit_independent_mixtures()spends on a SINGLE group.
- fit_independent_mixtures(group, data_by_group, *, n_components=2, seed=0, max_its=50)[source]
The untwisted baseline: one independently-fit
n_components-component density per group.Same per-group parameter count as the shared base density in
fit_twisted_mixture(), but|groups|times the total parameters overall, and each fit sees only its own group’s (small) sample – the comparisonfit_twisted_mixture()is measured against.