SilverSight/python/chiral_spectral_lut.py
allaun 9711af2427 feat(lut): Chiral Spectral LUT — 65K entries, 5 regimes, 0.1s, zero floats
python/chiral_spectral_lut.py:
- Maps 65,536 chiral configurations → 5 spectral fingerprints
- Integer arithmetic only: block eigenvalues = 273 ± w, w rational
- Regime classification: CANONICAL (6.1%), ROSSBY (93.8%), SCARRED (0.1%)
- Example: AAAAAAAA→λ=[17,529] CANONICAL, LLLLLLLL→λ=[-111,657] ROSSBY

Receipt: signatures/chiral_spectral_lut.json
2026-06-30 20:39:02 -05:00

88 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Chiral Spectral LUT — mapping 8-strand chiral configuration → spectral state.
8 strands × 4 chiral labels = 4⁸ = 65,536 states
Collapses to exactly 5 distinct spectral fingerprints.
The LUT maps any configuration to its eigenvalue pair {λ_min, λ_max}
using pure integer arithmetic (zero floats).
"""
import json, time
# Chiral weights as rational pairs (num, den) — integer arithmetic, zero floats
CHIRAL = {"A": (1, 1), "S": (1, 2), "L": (3, 2), "R": (3, 2)}
NAMES = ["A", "S", "L", "R"] # achiral, scarred, left_bias, right_bias
def compute_spectral(chi8):
"""
Compute {λ_min, λ_max} for an 8-char chiral string like 'AASSSLLR'.
Integer arithmetic only — zero floats.
The Cartan matrix is 4×2×2 block-diagonal: pairs (0,1), (2,3), (4,5), (6,7).
Each block [[273, w], [w, 273]] has eigenvalues {273+w, 273-w}
where w = 128 × (chiral[num]/chiral[den] average of the pair).
"""
pairs = [(0,1), (2,3), (4,5), (6,7)]
all_lo, all_hi = [], []
for a, b in pairs:
an, ad = CHIRAL[chi8[a]]
bn, bd = CHIRAL[chi8[b]]
# w = 128 × (an/ad + bn/bd) = 128 × (an×bd + bn×ad) / (ad×bd)
num = 128 * (an * bd + bn * ad)
den = ad * bd
w = num // den
all_lo.append(273 + w)
all_hi.append(273 - w)
return max(all_lo), min(all_hi)
def build_lut(save=True):
"""Build the full 65,536-entry LUT."""
t0 = time.time()
lut = {}
for mask_int in range(4**8):
chi = "".join(NAMES[(mask_int >> (i*2)) & 3] for i in range(8))
lam_max, lam_min = compute_spectral(chi)
lut[chi] = {"lambda_max": lam_max, "lambda_min": lam_min}
t1 = time.time()
# Classify into regimes
regimes = {}
for chi, spec in lut.items():
key = (spec["lambda_min"], spec["lambda_max"])
regimes.setdefault(key, [])
regimes[key].append(chi)
print(f"LUT built in {t1-t0:.1f}s — {len(lut):,} entries, zero floats")
print(f"\nSpectral regime distribution ({len(regimes)} regimes):")
for (lo, hi), configs in sorted(regimes.items(), key=lambda x: -len(x[1])):
regime = "CANONICAL" if lo == 17 else "ROSSBY" if lo < 0 else "SCARRED" if lo > 17 else "OTHER"
name = {"CANONICAL": "achiral ground state",
"ROSSBY": "nonabelian (Rossby-active)",
"SCARRED": "sub-critical (scarred)"}.get(regime, regime)
print(f" λ=[{lo:>4}, {hi:>4}] {len(configs):>5} configs ({len(configs)/len(lut)*100:5.1f}%) {name}")
if save:
receipt = {
"schema": "chiral_spectral_lut_v1", "zero_float": True,
"entries": len(lut), "regimes": len(regimes),
"regime_labels": ["CANONICAL", "ROSSBY", "SCARRED"],
"compute_time_s": round(t1-t0, 2),
"note": "Integer arithmetic only. Block eigenvalues = 273 ± w, w = 128 × avg(chi)"
}
with open("signatures/chiral_spectral_lut.json", "w") as f:
json.dump(receipt, f, indent=2)
print(f"\nReceipt: signatures/chiral_spectral_lut.json")
return lut, regimes
if __name__ == "__main__":
lut, regimes = build_lut()
# Example lookups
print("\nExample lookups:")
for chi in ["AAAAAAAA", "SSSSSSSS", "LLLLLLLL", "AASSLRRL", "AASSAASS"]:
spec = lut.get(chi, {})
regime = "CANONICAL" if spec.get("lambda_min") == 17 else "ROSSBY" if spec.get("lambda_min", 0) < 0 else "SCARRED"
print(f" {chi} → λ=[{spec.get('lambda_min')}, {spec.get('lambda_max')}] {regime}")