core/algebra
Shay 26270ed846
Some checks failed
smoke / smoke (-m "not quarantine") (pull_request) Failing after 59s
lane-shas / verify pinned lane SHAs (pull_request) Failing after 32s
feat(algebra): null-point recovery primitives + frozen CGA null constants
Shared CGA substrate for the #17 conformal-Procrustes/Kabsch and #16
Cartan-Iwasawa decompositions. Adds algebra/null_point.py and hoists the two
conformal null directions to frozen module constants.

algebra/cga.py
  - Add frozen read-only f64 N_O / N_INF constants: the same vectors
    embed_point builds inline (origin embeds to N_O; N_INF is fixed by every
    Euclidean isometry), so the null-point primitives share one exact sign
    definition instead of re-deriving it per call site.
  - Fix header-docstring sign typo: n_o = 0.5*(e5 - e4), not 0.5*(e4 - e5).
    embed_point was already correct; only the module header disagreed.

algebra/null_point.py (new)
  - dilator(scale), translator(a): CGA similarity constructors; both
    round-trip through the recoverers.
  - recover_dilation(V) -> (scale, D): reads V n_inf rev(V), weight-normalised
    so recovery is invariant to a non-unit versor weight (verified vs V -> kV).
  - recover_translation(V) -> (a, T): reads V n_o rev(V), projective
    dehomogenisation.
  - NullPointRecoveryError carries machine-readable reason codes.
  - Fail-closed symmetric similarity gate (_require_similarity): BOTH recoverers
    now reject non-versors (not_a_versor) and non-similarities (not_similarity,
    e.g. transversions). Closes an asymmetry where recover_translation silently
    accepted a transversion / non-versor and returned a plausible translation,
    violating the module's own wrong=0 contract.
  - Orientation-reversing (reflection / det=-1) versors are refused by
    recover_dilation with a distinct reason improper_versor, kept separate from
    degenerate_scale; recover_translation still accepts them (the origin image is
    well defined). conformal_procrustes strips reflections upstream, so this is a
    documented boundary, not a silent one.
  - Default tol=1e-9 documented: matches f64-exact recovery of a cleanly
    assembled versor (~1e-14 round-trip); noisy/SVD callers must pass a wider tol.

tests/test_null_point_primitives.py (new): 33 tests - null-cone/pairing
invariants, constant immutability, constructor round-trips, composed T.D.R peel,
versor-weight invariance, and the full fail-closed matrix (transversion,
non-versor, inversion, reflection asymmetry, non-positive scale, bad vector).

Invariant protected: wrong=0 - no recovery returns a silently wrong value on a
degenerate / non-versor / non-similarity input. Validation: 33/33 new pass;
88 passed / 1 xfailed across the CGA substrate + physics Procrustes consumers
(dynamic_manifold, surprise, versor closure, rotor, holonomy).

Hardened via a 3-lens adversarial verification (soundness / sign-convention /
consumer-contract, each executing counterexample versors, every finding
skeptic-verified): 2 CONFIRMED findings fixed (asymmetric validation gap;
reflection reason conflation); tol-tightness resolved by documentation rather
than a guard-weakening default change.
2026-07-12 16:28:19 -07:00
..
__init__.py feat(algebra): incidence algebra — graded_wedge, dual, meet + honest outer_product 2026-06-04 21:43:35 -07:00
backend.py perf(rust): zero-copy FFI for diffusion_step + parity-aligned bench gate 2026-05-21 08:51:15 -07:00
cga.py feat(algebra): null-point recovery primitives + frozen CGA null constants 2026-07-12 16:28:19 -07:00
cl41.py
holonomy.py
null_point.py feat(algebra): null-point recovery primitives + frozen CGA null constants 2026-07-12 16:28:19 -07:00
rotor.py feat(algebra): exact fractional powers of non-simple rotors (invariant split) 2026-07-12 09:52:07 -07:00
versor.py fix(ingest): close issue #300 — normalize_to_versor margin at the gate (#312) 2026-05-26 16:39:49 -07:00