SilverSight/python/exhaustive_8x8.py
allaun 7f75e41a39 compute(exhaustive): integer-only 8x8 — 65K configs, 5 distinct spectral states
Zero floats. Pure integer: block eigenvalues = 273 ± w, w = 128 × Σ(num/den).

65,536 configurations (1 partition × 4⁸ chiral masks) → 5 distinct states:
  λ=[-111, 657]  44800 (68.4%)  Rossby-dominant (all biased)
  λ=[ -47, 593]  16640 (25.4%)  Mixed (some scarred, some biased)
  λ=[  17, 529]   4015 ( 6.1%)  Canonical (pure achiral)
  λ=[  81, 465]     80 ( 0.1%)  Mixed scarred
  λ=[ 145, 401]      1 ( 0.0%)  Pure scarred

105 partitions × 4⁸ = 6.9M total. Uniform weights — same 5 states.
All computed in 0.1s with integer arithmetic.
2026-06-30 20:38:06 -05:00

108 lines
4.3 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
"""Exhaustive 8x8 Cartan — ZERO FLOAT, integer arithmetic.
The Cartan matrix is block-diagonal (4 independent 2x2 blocks).
Each block [[273, w], [w, 273]] has integer eigenvalues {273+w, 273-w}.
No eigendecomposition needed — just 4 integer additions/subtractions per config."""
import time, json, math
def block_eigenvalues(m):
"""Eigenvalues of [[273, 256*m], [256*m, 273]] in INTEGER."""
w = (256 * m)
return (273 + w, 273 - w)
def all_partitions():
strands = list(range(8)); result = []
def backtrack(rem, cur):
if not rem: result.append(tuple(sorted(tuple(sorted(p)) for p in cur))); return
first = rem[0]; rest = rem[1:]
for i, second in enumerate(rest): backtrack(rest[:i]+rest[i+1:], cur+[(first,second)])
backtrack(strands, []); return sorted(set(result))
# Chiral modifiers as integer multiples: {1, 1/2, 3/2} × 256
# Use rational pairs (num, den) to keep everything integer
CHIRAL = {
"A": (1, 1), # achiral: m = 1
"S": (1, 2), # scarred: m = 1/2
"L": (3, 2), # left bias: m = 3/2
"R": (3, 2), # right bias: m = 3/2
}
NAMES = ["A", "S", "L", "R"]
def chiral_mask_name(mask):
return "".join(NAMES[m] for m in mask)
def compute_lam(partition, mask):
"""Compute λ_min, λ_max as integers. No floats."""
all_lo = []
all_hi = []
for (a, b) in partition:
num_a, den_a = CHIRAL[NAMES[mask[a]]]
num_b, den_b = CHIRAL[NAMES[mask[b]]]
# m = (a.num/a.den + b.num/b.den) / 2
# w = 256 * m = 128 * (a.num/a.den + b.num/b.den)
# Use common denominator: w = 128 * (num_a*den_b + num_b*den_a) / (den_a * den_b)
num = 128 * (num_a * den_b + num_b * den_a)
den = den_a * den_b
w = num // den # integer division — exact for these cases
if num % den != 0: # shouldn't happen with our values
w = round(num / den)
all_lo.append(273 + w)
all_hi.append(273 - w)
return max(all_lo), min(all_hi)
t0 = time.time()
partitions = all_partitions()
# Since Cartan weights are UNIFORM, all 105 partitions give identical results.
# Just compute on first partition × all 4^8 chiral masks.
partition = partitions[0]
total = 4**8
lam_min_set, lam_max_set = set(), set()
canonical = 0; rossby = 0; counts = {}
print(f"Computing 4^8 = {total:,} chiral configurations (integer only)...")
for mask_int in range(total):
mask = [(mask_int // (4**i)) % 4 for i in range(8)]
lam_max, lam_min = compute_lam(partition, mask)
lam_min_set.add(lam_min)
lam_max_set.add(lam_max)
if lam_min == 17: canonical += 1
if lam_min < 0: rossby += 1
key = (lam_min, lam_max)
counts[key] = counts.get(key, 0) + 1
t1 = time.time()
print(f"\nDone in {t1-t0:.1f}s")
print(f"Integer arithmetic only — zero floats.")
print(f"\nResults for 4^8 = {total:,} configurations:")
print(f" Canonical (λ_min=17): {canonical} ({canonical/total*100:.1f}%)")
print(f" Rossby-active (λ_min<0): {rossby} ({rossby/total*100:.1f}%)")
print(f"\nDistinct spectral states:")
print(f" λ_min values: {sorted(lam_min_set)}")
print(f" λ_max values: {sorted(lam_max_set)}")
print(f" Total distinct states: {len(counts)}")
print(f"\nSpectral state distribution:")
for (lo, hi), n in sorted(counts.items(), key=lambda x: -x[1])[:10]:
print(f" λ=[{lo:>4}, {hi:>4}] -> {n:>5} configs ({n/total*100:5.1f}%)")
# All 105 partitions give the same results (uniform Cartan weights)
full_total = len(partitions) * total
print(f"\nAll 105 partitions × 4^8 = {full_total:,} configs:")
print(f" Same results (uniform weights). 105 × {total:,} = {full_total:,}")
print(f" Partition count is multiplicative — just scales the config count.")
receipt = {
"schema": "exhaustive_8x8_v2", "zero_float": True,
"partitions": len(partitions), "chiral_configs": total,
"total": full_total, "compute_time_s": round(t1-t0, 2),
"canonical": canonical, "rossby": rossby,
"lambda_min_values": sorted(lam_min_set),
"lambda_max_values": sorted(lam_max_set),
"distinct_states": len(counts),
"note": "All integer arithmetic. Block eigenvalues = 273 ± w where w = 256*m, m = chiral average."
}
with open("signatures/exhaustive_8x8_receipt.json", "w") as f:
json.dump(receipt, f, indent=2)
print(f"\nReceipt: signatures/exhaustive_8x8_receipt.json")