feat(spectral): f/Cartan integration — exact spiral packing, f(n) layout, Cartan Δ-floor, torus-winding fix

STEP 1 — integer spiral-index packing (EXACT): pack_spiral_index/
unpack_spiral_index with corpus-wide base=2·max|c|+1 and offset-encoded
digits, recorded in the codebook JSON header; round-trip verified over
all 250 matrices. Fixes the sign bug in integration_sprint.py's integer
path (unoffset signed packing collapsed (-1,1) with (1,0) in base 2).

STEP 2 — f(n) layout (DECORATIVE): per-entry radius_sq + angle_frac,
computed in decimal arithmetic (indices reach ~1e44 >> 2^52); verified
against VERIFICATION_LOG V007 f(20121); min angular separation ≈4.64e-6
of a turn reported.

STEP 3 — Cartan Δ-floor (--cartan-floor): Δ=17/1792 exact
(CartanConnection.lean:70) as Fisher-distance resolution floor on Δ₇;
13 sub-Δ pairs merge 196 fingerprints into 187 Δ-resolution codewords
vs 9 gap-rule clusters; emitted alongside, not replacing, the 3×-median
rule. Caveat asserted in tests: the |c|/Σ|c| simplex projection is
lossy (one corpus pair at Fisher distance 0) — similarity, not identity.

STEP 4 — torus-winding saturation fix: TorusWinding gains
a_exact/b_exact (plain ℤ, no Q16.16 clamp); torus_to_spiral_index
prefers them, making the round trip lossless (regression-tested at
n=1e9). BraidEigensolid.lean needs the same widening — noted, Lean
untouched.

Also corrects charpoly_codebook.py's stale docstring counts (192/180 →
196/182, cross-checked against the exact Faddeev–LeVerrier fingerprints:
identical on all 250 matrices).

Tests: 43 passed (19 new).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
allaun 2026-07-01 20:53:47 -05:00
parent e81caa4a6a
commit 359effdfc6
7 changed files with 2126 additions and 239 deletions

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,7 @@
**Date:** 2026-07-01
**Module:** `python/spectral_codebook.py`
**Output:** `data/spectral_codebook.json`
**Tests:** `tests/test_spectral_codebook.py` (15 tests)
**Tests:** `tests/test_spectral_codebook.py` (43 tests)
Implements the "Next Steps" of `docs/SPECTRAL_CODEBOOK_ANALYSIS.md`: a
gap-aware spectral codebook over the 250 8×8 integer braid adjacency
@ -16,6 +16,7 @@ encode/decode round trip and an exact, float-free fingerprint per matrix.
python3 python/spectral_codebook.py # build + report + write JSON
python3 python/spectral_codebook.py --check-manifold # also run the 278-row corpus
python3 python/spectral_codebook.py --gap-factor 3 --min-support 10 --no-write
python3 python/spectral_codebook.py --cartan-floor # + Fisher/Δ=17/1792 floor report
python3 tests/test_spectral_codebook.py # or python3 -m pytest tests/test_spectral_codebook.py
```
@ -122,6 +123,73 @@ matrices, no id lacks a matrix). Rerunning gap quantization on the 278-row
corpus reproduces the 250-matrix boundaries exactly: **no new gaps, no new
clusters, all extra rows fall inside existing clusters.**
## Φ-corkscrew and Cartan layers (f/Cartan integration batch)
Four layers added on top of the fingerprints, each labelled **exact**
(integer arithmetic, Lean-provable) or **decorative** (placement/reporting
only, carries no information):
### 1. Integer spiral-index packing — EXACT
`pack_spiral_index` / `unpack_spiral_index` with corpus-wide parameters
recorded in the JSON header (`phi_corkscrew.packing`): offset = max|c| over
all fingerprint coefficients (164 234 on this corpus), base = 2·offset + 1
(328 469). Digits are offset-encoded (`c + offset ∈ [0, base)`), so
`spiral_index = Σ (cᵢ + offset)·baseⁱ` is the base-B positional numeral of
the fingerprint — injective on fingerprints by uniqueness of positional
representation, inverted exactly by `unpack_spiral_index`, and verified by
round trip over all 250 matrices in the test suite. It inherits charpoly's
non-injectivity on *matrices* (cospectral classes share one index), so
identity still requires the within-cluster index.
This **supersedes** the float phinary packing that `integration_sprint.py`
used historically (`phinary += c·φ⁻ⁱ` then truncation — not injective).
The integer path in `integration_sprint.phi_corkscrew_index` is fixed the
same way (offset-encoded digits; its unoffset signed packing collapsed
e.g. `(-1, 1)` with `(1, 0)` in base 2), but its base is per-call — for
corpus-comparable indices use the codebook's recorded (base, offset).
### 2. f(n) layout — DECORATIVE
`f(n) = (√n·cos(nψ), √n·sin(nψ))`, ψ = 2π/φ². Injective because 1/φ² is
irrational; low-discrepancy by the three-distance theorem;
information-neutral (everything decodes from `spiral_index` alone). Each
entry stores `layout.radius_sq` (= the spiral index, exact int) and
`layout.angle_frac` (fraction of a full turn). Angles are computed in
`decimal` arithmetic at full precision because spiral indices reach
~10⁴⁴ ≫ 2⁵², where float64 retains no fractional bits of n/φ². Verified
against `VERIFICATION_LOG.md` V007: f(20121) = (137.80079576,
33.64432624). Measured minimum pairwise angular separation across the
corpus: ≈ 4.64 × 10⁻⁶ of a turn (positive, as irrationality requires).
### 3. Cartan ∆-floor quantization (`--cartan-floor`) — EXACT ∆, reported floor
∆ = **17/1792** exactly (λ_min of the Cartan crossing blocks,
`CartanConnection.lean:70`, `docs/cartan_fingerprint.md`), adopted as the
resolution floor on the Fisher metric of Δ₇:
`d_F(p, q) = 2·arccos(Σ√(pᵢqᵢ))` with `pᵢ = |cᵢ|/Σ|cⱼ|` (all-zero
fingerprint → uniform, by convention). Measured on this corpus: **13
fingerprint pairs fall below ∆**, merging 196 fingerprints into **187
∆-resolution codewords**, vs **9 clusters** from the 3×-median-gap λ rule.
Both rules are emitted side by side; neither replaces the other.
Caveat, asserted in the tests: the simplex projection destroys sign and
scale, so distinct fingerprints can collide on Δ₇ (this corpus has a pair
at Fisher distance exactly 0). The Fisher/∆ layer is a **similarity**
metric, not an identity key.
### 4. Torus-winding saturation fix — EXACT
`pist_braid_bridge.TorusWinding` now carries `a_exact`/`b_exact` (plain ,
no clamp) alongside the legacy Q16.16 raws, which silently saturate above
32767 (i.e. for spiral_index > 65535 — and codebook indices reach ~10⁴⁴).
`torus_to_spiral_index` prefers the exact fields, making the round trip
lossless for every index (regression-tested at n = 10⁹); legacy windings
without exact fields keep the old Q16 behaviour. The matching Lean type in
`BraidEigensolid.lean` needs the same widening (Int fields alongside
Q16_16) before this layer can be mirrored formally — noted in the
dataclass docstring, Lean file intentionally untouched.
## Notes for the Lean side
- **Identity layer vs. similarity layer.** `ClassifyN.hashMatrix` is a
@ -222,11 +290,16 @@ equation provenance; this sync does not (and cannot) connect to it.
## Output schema (`data/spectral_codebook.json`)
- header: `schema` (`spectral_codebook_v2`), `quantization` (factor,
min support, median gap, kept/candidate/suppressed boundaries,
sparse-tail cutoff), `clusters` (table above), `collisions` (all counts
and explicit collision classes), `manifold_278` (when `--check-manifold`).
- header: `schema` (`spectral_codebook_v2`), `phi_corkscrew` (packing
base/offset + layout semantics and measured min angular separation),
`quantization` (factor, min support, median gap,
kept/candidate/suppressed boundaries, sparse-tail cutoff), `clusters`
(table above), `collisions` (all counts and explicit collision classes),
`manifold_278` (when `--check-manifold`), `cartan_floor` (when
`--cartan-floor`: sub-Δ Fisher pairs, Δ-resolution codeword count,
rule comparison).
- `entries[]`: `equation_id`, `codeword`, `index`, `spectral_radius`
(exact), `lambda_power_iteration` (legacy), `charpoly` (8 exact ints),
`density`, `frobenius`, `trace`, optional `sparse_tail`,
`density`, `frobenius`, `trace`, `spiral_index` (exact int packing of
charpoly), `layout` (`radius_sq`, `angle_frac`), optional `sparse_tail`,
optional `identical_matrix_ids`.

View file

@ -6,7 +6,9 @@ polynomial coefficients as the codebook key.
Key advantages over power-iteration spectral radius:
- Exact (integer coefficients, no float precision issues)
- 192 unique fingerprints vs 180 from spectral radius
- 196 unique fingerprints vs 182 from spectral radius (measured on the
250-matrix corpus; identical coefficients to the exact FaddeevLeVerrier
fingerprints in spectral_codebook.py on all 250 matrices)
- Cayley-Hamilton verifiable in (fits integer-only doctrine)
- Guaranteed L minimum distance of 1 between distinct codewords

View file

@ -282,13 +282,17 @@ def phi_corkscrew_index(spectral_coeffs: np.ndarray) -> int:
# If coefficients are integers (charpoly), use them directly
if np.all(coeffs == np.round(coeffs)):
# Integer packing: shift each coefficient into a unique digit position
# Base = max(|coeff|) + 1 to guarantee injectivity
# Offset-encoded positional packing: digit = c + abs_max ∈ [0, base)
# with base = 2·abs_max + 1. Packing signed coefficients without
# the offset is NOT injective: (-1, 1) and (1, 0) both give 1 in
# base 2. base/offset are per-call here; for corpus-comparable
# indices use spectral_codebook.pack_spiral_index with the
# corpus-wide (base, offset) recorded in the codebook JSON.
abs_max = int(np.max(np.abs(coeffs))) if len(coeffs) > 0 else 0
base = max(abs_max + 1, 2)
base = max(2 * abs_max + 1, 2)
result = 0
for i, c in enumerate(coeffs):
result += int(c) * (base ** i)
result += (int(c) + abs_max) * (base ** i)
return result
# Float coefficients: normalize to [0, 1], quantize to 16-bit integers

View file

@ -334,9 +334,17 @@ class TorusWinding:
Matches: SilverSight.BraidEigensolid.TorusWinding
a = spatial winding (latitude cycle)
b = phase/torsion winding (longitude cycle)
The Q16_16 raws are LOSSY above value 32767 (Q16_MAX_RAW clamp);
a_exact/b_exact carry the plain- winding with no clamp and are the
authoritative values when present. BraidEigensolid.lean's
TorusWinding needs the same widening (Int fields alongside the
Q16_16 raws) before this exact layer can be mirrored formally.
"""
a: int # Q16_16 raw
b: int # Q16_16 raw
a: int # Q16_16 raw — saturates for values > 32767
b: int # Q16_16 raw — saturates for values > 32767
a_exact: Optional[int] = None # plain winding, no clamp
b_exact: Optional[int] = None # plain winding, no clamp
def to_float(self) -> Tuple[float, float]:
return q16_to_float(self.a), q16_to_float(self.b)
@ -356,8 +364,9 @@ def spiral_to_torus_winding(spiral_index: int) -> TorusWinding:
SATURATION WARNING: b_raw uses Q16.16 encoding, which clamps at
Q16_MAX_RAW / 65536 32767.99. For spiral_index > 65535, the
phase winding b silently saturates. Use torus_winding_safe() for
indices that may exceed this range.
phase winding b silently saturates. The a_exact/b_exact fields carry
the unclamped integers; torus_to_spiral_index prefers them, so the
round trip is exact for every spiral_index.
This mirrors: TorusWinding in BraidEigensolid.lean
"""
@ -366,7 +375,7 @@ def spiral_to_torus_winding(spiral_index: int) -> TorusWinding:
b_val = spiral_index // phi_step
a_raw = float_to_q16(float(a_val))
b_raw = float_to_q16(float(b_val))
return TorusWinding(a=a_raw, b=b_raw)
return TorusWinding(a=a_raw, b=b_raw, a_exact=a_val, b_exact=b_val)
def spiral_to_torus_winding_safe(spiral_index: int) -> Tuple[TorusWinding, bool]:
@ -385,18 +394,22 @@ def spiral_to_torus_winding_safe(spiral_index: int) -> Tuple[TorusWinding, bool]
saturated = b_val > max_q16_val
a_raw = float_to_q16(float(a_val))
b_raw = float_to_q16(float(b_val))
return TorusWinding(a=a_raw, b=b_raw), saturated
return TorusWinding(a=a_raw, b=b_raw, a_exact=a_val, b_exact=b_val), saturated
def torus_to_spiral_index(w: TorusWinding) -> int:
"""Inverse: recover spiral index from torus winding.
n = φ_step · b + a (in integer approximation)
n = φ_step · b + a
For spiral_index > 65535, this will return a saturated value.
Use spiral_to_torus_winding_safe() to detect this case.
Prefers the exact fields when present (lossless for all n);
falls back to the Q16.16 raws, which saturate for
spiral_index > 65535 use spiral_to_torus_winding_safe() to
detect that case on legacy windings without exact fields.
"""
phi_step = int(round(PHI))
if w.a_exact is not None and w.b_exact is not None:
return phi_step * w.b_exact + w.a_exact
b_int = int(round(q16_to_float(w.b)))
a_int = int(round(q16_to_float(w.a)))
return phi_step * b_int + a_int

View file

@ -257,6 +257,186 @@ def spectral_profile(mat: Sequence[Sequence[int]]) -> dict:
}
# ──────────────────────────────────────────────────────────────────────
# Φ-corkscrew: integer spiral-index packing (exact) + f(n) layout
# ──────────────────────────────────────────────────────────────────────
#
# The packing layer is EXACT and provable: with a corpus-wide base
# B = 2·max|c| + 1 and offset o = max|c|,
# every offset digit c_i + o lies in [0, B), so
# n = Σ (c_i + o)·B^i
# is the base-B positional numeral of the digit tuple — injective on
# char-poly fingerprints by uniqueness of positional representation, and
# unpack_spiral_index inverts it exactly. It inherits charpoly's
# NON-injectivity on matrices (cospectral classes share one index).
#
# The layout layer f(n) = (√n·cos(nψ), √n·sin(nψ)), ψ = 2π/φ², is
# DECORATIVE placement only: injective because 1/φ² is irrational
# (distinct n give distinct angles), information-neutral (everything is
# recoverable from n alone), low-discrepancy by the three-distance
# theorem. It carries no information beyond spiral_index.
def packing_params(fingerprints: Sequence[Sequence[int]]) -> Tuple[int, int]:
"""Corpus-wide (base, offset) for spiral-index packing.
offset = max|c| over every coefficient of every fingerprint;
base = 2·offset + 1, so offset-encoded digits fill [0, base).
"""
offset = max((abs(c) for fp in fingerprints for c in fp), default=0)
return 2 * offset + 1, offset
def pack_spiral_index(coeffs: Sequence[int], base: int, offset: int) -> int:
"""Little-endian base-B packing of offset-encoded coefficients.
Exact integer arithmetic; injective for digits in range (raises
otherwise). Replaces the float phinary packing of
integration_sprint.phi_corkscrew_index, which was not injective.
"""
n = 0
for i, c in enumerate(coeffs):
d = c + offset
if not 0 <= d < base:
raise ValueError(
f"coefficient {c} out of packing range for "
f"base={base}, offset={offset}")
n += d * base ** i
return n
def unpack_spiral_index(n: int, base: int, offset: int,
length: int = 8) -> Tuple[int, ...]:
"""Exact inverse of pack_spiral_index."""
if n < 0:
raise ValueError("spiral index must be non-negative")
out: List[int] = []
for _ in range(length):
n, d = divmod(n, base)
out.append(d - offset)
if n:
raise ValueError("spiral index exceeds length digits in this base")
return tuple(out)
# 1/φ² = (3 √5)/2: the fractional rotation per step of the corkscrew.
def angle_frac(n: int) -> float:
"""frac(n/φ²) — the corkscrew angle of index n as a fraction of 2π.
Computed in decimal arithmetic at a precision that covers the integer
part of n·(35)/2, because float64 loses the fractional part
entirely once n exceeds 2^52 (spiral indices here reach base^8).
"""
from decimal import Decimal, getcontext
getcontext().prec = len(str(abs(n))) + 25
alpha = (Decimal(3) - Decimal(5).sqrt()) / 2
return float((Decimal(n) * alpha) % 1)
def corkscrew_xy(n: int) -> Tuple[float, float]:
"""f(n) = (√n·cos(nψ), √n·sin(nψ)), ψ = 2π/φ². Placement only."""
theta = 2.0 * math.pi * angle_frac(n)
r = math.sqrt(n)
return r * math.cos(theta), r * math.sin(theta)
def min_angular_separation(indices: Sequence[int]) -> Optional[float]:
"""Minimum circular distance (as a fraction of a full turn) between
the corkscrew angles of distinct spiral indices."""
uniq = sorted({angle_frac(n) for n in set(indices)})
if len(uniq) < 2:
return None
gaps = [uniq[i + 1] - uniq[i] for i in range(len(uniq) - 1)]
gaps.append(1.0 - uniq[-1] + uniq[0]) # wrap-around
return min(gaps)
# ──────────────────────────────────────────────────────────────────────
# Cartan ∆-floor quantization (Fisher metric on Δ₇)
# ──────────────────────────────────────────────────────────────────────
#
# ∆ = 17/1792 is the minimum eigenvalue of the Cartan crossing blocks,
# proven exact in formal/.../CartanConnection.lean:70 (see
# docs/cartan_fingerprint.md). It is adopted here as the resolution
# floor on the Fisher metric: two codewords closer than ∆ are treated
# as indistinguishable at operator resolution. This gives a PRINCIPLED
# alternative to the 3×-median-gap heuristic; both are emitted so the
# rules can be compared, neither replaces the other.
CARTAN_DELTA = Fraction(17, 1792) # exact; CartanConnection.lean:70
def simplex_project(coeffs: Sequence[int]) -> Tuple[float, ...]:
"""Project a fingerprint onto Δ₇: p_i = |c_i| / Σ|c_j|.
Convention: the all-zero fingerprint (nilpotent x⁸ class) maps to
the uniform distribution flagged in the report, since that choice
is a convention, not a theorem.
"""
total = sum(abs(c) for c in coeffs)
k = len(coeffs)
if total == 0:
return tuple(1.0 / k for _ in range(k))
return tuple(abs(c) / total for c in coeffs)
def fisher_distance(p: Sequence[float], q: Sequence[float]) -> float:
"""d_F(p, q) = 2·arccos(Σ√(p_i·q_i)) — Fisher geodesic distance on
the probability simplex (Bhattacharyya angle × 2)."""
bc = sum(math.sqrt(a * b) for a, b in zip(p, q))
return 2.0 * math.acos(min(1.0, bc))
def cartan_floor_report(profiles: Dict[str, dict]) -> dict:
"""All-pairs Fisher distances between distinct fingerprints; pairs
below = 17/1792 are merged into -resolution components (union-
find), giving the codeword count the Cartan floor supports."""
fp_rep: Dict[Tuple[int, ...], str] = {}
for eid in sorted(profiles):
fp_rep.setdefault(tuple(profiles[eid]["charpoly"]), eid)
fps = list(fp_rep)
pts = [simplex_project(fp) for fp in fps]
delta = float(CARTAN_DELTA)
parent = list(range(len(fps)))
def find(i: int) -> int:
while parent[i] != i:
parent[i] = parent[parent[i]]
i = parent[i]
return i
sub_delta: List[dict] = []
min_d, min_pair = None, None
for i in range(len(fps)):
for j in range(i + 1, len(fps)):
d = fisher_distance(pts[i], pts[j])
if min_d is None or d < min_d:
min_d, min_pair = d, (fp_rep[fps[i]], fp_rep[fps[j]])
if d < delta:
sub_delta.append({
"representatives": [fp_rep[fps[i]], fp_rep[fps[j]]],
"fisher_distance": round(d, 8),
})
ri, rj = find(i), find(j)
if ri != rj:
parent[rj] = ri
components = len({find(i) for i in range(len(fps))})
return {
"delta_exact": "17/1792",
"delta_source": "CartanConnection.lean:70 (docs/cartan_fingerprint.md)",
"delta_float": delta,
"metric": "Fisher on Δ₇: d_F = 2·arccos(Σ√(p_i·q_i)); "
"p_i = |c_i|/Σ|c_j| (all-zero fingerprint → uniform, "
"by convention)",
"distinct_fingerprints": len(fps),
"pairs_below_delta": len(sub_delta),
"sub_delta_pairs": sub_delta[:50],
"delta_resolution_codewords": components,
"min_fisher_distance": round(min_d, 8) if min_d is not None else None,
"min_fisher_pair": list(min_pair) if min_pair else None,
}
# ──────────────────────────────────────────────────────────────────────
# Gap-aware quantization (deduped, sample-size guarded)
# ──────────────────────────────────────────────────────────────────────
@ -350,6 +530,14 @@ class Codebook:
eid: spectral_profile(mat) for eid, mat in matrices.items()
}
# Φ-corkscrew integer packing (corpus-wide base/offset, exact)
self.pack_base, self.pack_offset = packing_params(
[p["charpoly"] for p in self.profiles.values()])
self.spiral_indices: Dict[str, int] = {
eid: pack_spiral_index(p["charpoly"], self.pack_base, self.pack_offset)
for eid, p in self.profiles.items()
}
# dedupe byte-identical matrices BEFORE gap analysis
self.matrix_groups: Dict[Matrix, List[str]] = {}
for eid in sorted(self.profiles):
@ -480,6 +668,7 @@ class Codebook:
for eid in sorted(self.profiles):
cw, idx = self._assign[eid]
p = self.profiles[eid]
n = self.spiral_indices[eid]
entry = {
"equation_id": eid,
"codeword": cw,
@ -490,6 +679,11 @@ class Codebook:
"density": p["density"],
"frobenius": p["frobenius"],
"trace": p["trace"],
"spiral_index": n,
"layout": {
"radius_sq": n,
"angle_frac": round(angle_frac(n), 12),
},
}
if self.is_sparse_tail(p["spectral_radius"]):
entry["sparse_tail"] = True
@ -507,6 +701,33 @@ class Codebook:
"characteristic polynomial (charpoly); lambda_power_iteration is "
"the legacy estimate and is unreliable on peripheral spectra"
),
"phi_corkscrew": {
"packing": {
"base": self.pack_base,
"offset": self.pack_offset,
"digits": 8,
"order": "little-endian: charpoly c1 is digit 0",
"semantics": (
"spiral_index = Σ (c_i + offset)·base^i — exact "
"integer, injective on charpoly fingerprints "
"(unpack_spiral_index inverts it exactly); inherits "
"charpoly's non-injectivity on matrices, so identity "
"still needs the within-cluster index"
),
},
"layout": {
"psi": "2π/φ² (golden angle)",
"angle_frac": "frac(n·(3√5)/2), decimal-exact precision",
"min_angular_separation_frac": (
min_angular_separation(list(self.spiral_indices.values()))
),
"semantics": (
"decorative placement only: f(n) is injective because "
"1/φ² is irrational, and carries no information beyond "
"spiral_index"
),
},
},
"quantization": {
"method": "gap_aware_deduped_min_support",
"gap_factor": self.gap_factor,
@ -584,6 +805,9 @@ def main(argv: Optional[List[str]] = None) -> int:
help="Minimum distinct matrices per cluster (default 10)")
ap.add_argument("--check-manifold", action="store_true",
help="Also run over the 278-row RRC/Q16_16Manifold corpus")
ap.add_argument("--cartan-floor", action="store_true",
help="Also emit the Cartan ∆=17/1792 Fisher-floor report "
"(alongside, not replacing, the gap rule)")
ap.add_argument("--no-write", action="store_true",
help="Report only; do not write the JSON")
ap.add_argument("--sync-db", action="store_true",
@ -638,6 +862,21 @@ def main(argv: Optional[List[str]] = None) -> int:
print(f" boundaries match 250-matrix codebook: {mc['boundaries_match_250']} "
f"({mc['clusters']} clusters)")
if args.cartan_floor:
cf = cartan_floor_report(cb.profiles)
doc["cartan_floor"] = cf
gap_clusters = len(q["boundaries"]) + 1
print(f"\n Cartan ∆-floor (∆ = {cf['delta_exact']}"
f"{cf['delta_float']:.6f}, {cf['delta_source']}):")
print(f" distinct fingerprints on Δ₇ : {cf['distinct_fingerprints']}")
print(f" pairs below ∆ (Fisher) : {cf['pairs_below_delta']}")
print(f" min Fisher distance : {cf['min_fisher_distance']} "
f"{cf['min_fisher_pair']}")
print(f" rule comparison — codewords : "
f"∆-floor {cf['delta_resolution_codewords']} vs "
f"3×-median-gap {gap_clusters} (λ clusters); both emitted, "
f"neither replaces the other")
if args.sync_db:
import spectral_codebook_db
print("\n DB sync (dry run):")

View file

@ -320,5 +320,189 @@ class TestSpectralCodebookDbSync(unittest.TestCase):
os.environ["NEON_PG"] = old
class TestPhiCorkscrewPacking(unittest.TestCase):
"""STEP 1: integer spiral-index packing — exact, injective, reversible."""
@classmethod
def setUpClass(cls):
cls.matrices = sc.parse_matrices_lean()
cls.codebook = sc.Codebook(cls.matrices)
def test_base_is_odd_and_covers_corpus(self):
base, offset = self.codebook.pack_base, self.codebook.pack_offset
self.assertEqual(base, 2 * offset + 1)
for p in self.codebook.profiles.values():
for c in p["charpoly"]:
self.assertLessEqual(abs(c), offset)
def test_round_trip_all_250(self):
base, offset = self.codebook.pack_base, self.codebook.pack_offset
for eid, p in self.codebook.profiles.items():
fp = tuple(p["charpoly"])
n = self.codebook.spiral_indices[eid]
self.assertEqual(sc.unpack_spiral_index(n, base, offset, 8), fp, eid)
def test_injective_on_fingerprints(self):
by_fp = {}
for eid, p in self.codebook.profiles.items():
by_fp.setdefault(tuple(p["charpoly"]), set()).add(
self.codebook.spiral_indices[eid])
# one index per fingerprint …
for fp, idxs in by_fp.items():
self.assertEqual(len(idxs), 1, fp)
# … and distinct fingerprints get distinct indices
all_idx = [next(iter(v)) for v in by_fp.values()]
self.assertEqual(len(set(all_idx)), len(by_fp))
def test_signed_collision_regression(self):
# The unoffset packing collapsed (-1, 1) and (1, 0); ours must not.
base, offset = sc.packing_params([(-1, 1), (1, 0)])
a = sc.pack_spiral_index((-1, 1), base, offset)
b = sc.pack_spiral_index((1, 0), base, offset)
self.assertNotEqual(a, b)
def test_out_of_range_raises(self):
with self.assertRaises(ValueError):
sc.pack_spiral_index((5,), base=3, offset=1)
def test_integration_sprint_integer_path_fixed(self):
import numpy as np
import integration_sprint as isp
# same shape, same abs_max (=1) → same per-call base/offset, so the
# historical base-2 collision pair must now pack to distinct indices
a = isp.phi_corkscrew_index(np.array([-1.0, 1.0, 0.0]))
b = isp.phi_corkscrew_index(np.array([1.0, 0.0, -1.0]))
self.assertNotEqual(a, b)
class TestCorkscrewLayout(unittest.TestCase):
"""STEP 2: f(n) layout — decorative placement, verified against V007."""
@classmethod
def setUpClass(cls):
cls.matrices = sc.parse_matrices_lean()
cls.codebook = sc.Codebook(cls.matrices)
def test_v007_reference_point(self):
# VERIFICATION_LOG.md V007: f(20121) = (-137.80079576, -33.64432624)
x, y = sc.corkscrew_xy(20121)
self.assertAlmostEqual(x, -137.80079576, places=5)
self.assertAlmostEqual(y, -33.64432624, places=5)
def test_angle_frac_in_unit_interval(self):
for eid, n in self.codebook.spiral_indices.items():
f = sc.angle_frac(n)
self.assertGreaterEqual(f, 0.0, eid)
self.assertLess(f, 1.0, eid)
def test_angle_frac_exceeds_float64_naive(self):
# for n >> 2^52 the float product n·α has no fractional bits left;
# the decimal path must still give a nontrivial fraction
n = 10 ** 40 + 7
f = sc.angle_frac(n)
self.assertGreaterEqual(f, 0.0)
self.assertLess(f, 1.0)
# consecutive indices step by frac(α): distinguishable at any scale
g = sc.angle_frac(n + 1)
alpha_frac = 0.3819660112501051 # frac((3√5)/2)
diff = (g - f) % 1.0
self.assertAlmostEqual(diff, alpha_frac, places=9)
def test_layout_in_json_and_information_neutral(self):
doc = self.codebook.to_json()
pc = doc["phi_corkscrew"]
self.assertEqual(pc["packing"]["base"], self.codebook.pack_base)
sep = pc["layout"]["min_angular_separation_frac"]
self.assertIsNotNone(sep)
self.assertGreater(sep, 0.0)
for entry in doc["entries"]:
# radius² IS the spiral index — layout adds no information
self.assertEqual(entry["layout"]["radius_sq"], entry["spiral_index"])
class TestCartanFloor(unittest.TestCase):
"""STEP 3: Cartan ∆ = 17/1792 as Fisher-distance resolution floor."""
@classmethod
def setUpClass(cls):
cls.matrices = sc.parse_matrices_lean()
cls.codebook = sc.Codebook(cls.matrices)
cls.report = sc.cartan_floor_report(cls.codebook.profiles)
def test_delta_exact_value(self):
from fractions import Fraction
self.assertEqual(sc.CARTAN_DELTA, Fraction(17, 1792))
def test_fisher_metric_axioms(self):
p = sc.simplex_project((1, -2, 3, 0, 0, 0, 0, 4))
q = sc.simplex_project((0, 5, 0, 1, 0, 0, 0, 0))
self.assertAlmostEqual(sc.fisher_distance(p, p), 0.0, places=12)
self.assertAlmostEqual(sc.fisher_distance(p, q),
sc.fisher_distance(q, p), places=12)
# disjoint support → maximal distance π
u = sc.simplex_project((1, 0, 0, 0, 0, 0, 0, 0))
v = sc.simplex_project((0, 1, 0, 0, 0, 0, 0, 0))
import math
self.assertAlmostEqual(sc.fisher_distance(u, v), math.pi, places=12)
def test_simplex_projection_sums_to_one(self):
for p in self.codebook.profiles.values():
pt = sc.simplex_project(p["charpoly"])
self.assertAlmostEqual(sum(pt), 1.0, places=12)
def test_zero_fingerprint_convention(self):
pt = sc.simplex_project((0,) * 8)
self.assertEqual(pt, tuple(1.0 / 8 for _ in range(8)))
def test_report_consistency(self):
r = self.report
self.assertEqual(r["distinct_fingerprints"], 196)
# merging k sub-∆ pairs can remove at most k components
self.assertGreaterEqual(
r["delta_resolution_codewords"],
r["distinct_fingerprints"] - r["pairs_below_delta"])
self.assertLessEqual(r["delta_resolution_codewords"],
r["distinct_fingerprints"])
def test_simplex_projection_is_lossy(self):
# |c|/Σ|c| destroys sign+scale: distinct fingerprints can collide on
# Δ₇ (min Fisher distance 0.0 in this corpus) — similarity layer,
# NOT an identity key. This is asserted so the doc claim stays true.
self.assertEqual(self.report["min_fisher_distance"], 0.0)
class TestTorusWindingExact(unittest.TestCase):
"""STEP 4: torus-winding round trip must not saturate at n ≥ 65536."""
@classmethod
def setUpClass(cls):
import pist_braid_bridge as pbb
cls.pbb = pbb
def test_round_trip_regression_1e9(self):
pbb = self.pbb
for n in (0, 1, 65535, 65536, 10 ** 9):
w = pbb.spiral_to_torus_winding(n)
self.assertEqual(pbb.torus_to_spiral_index(w), n, n)
def test_exact_fields_populated(self):
pbb = self.pbb
w = pbb.spiral_to_torus_winding(10 ** 9)
self.assertEqual(w.a_exact, 10 ** 9 % 2)
self.assertEqual(w.b_exact, 10 ** 9 // 2)
def test_q16_raws_still_saturate_and_are_flagged(self):
pbb = self.pbb
w, saturated = pbb.spiral_to_torus_winding_safe(10 ** 9)
self.assertTrue(saturated)
self.assertEqual(w.b, pbb.Q16_MAX_RAW) # legacy raw clamps…
self.assertEqual(pbb.torus_to_spiral_index(w), 10 ** 9) # …exact wins
def test_legacy_winding_without_exact_fields(self):
pbb = self.pbb
w = pbb.TorusWinding(a=pbb.float_to_q16(1.0), b=pbb.float_to_q16(21.0))
self.assertEqual(pbb.torus_to_spiral_index(w), 43)
if __name__ == "__main__":
unittest.main()