SilverSight/python/spectral_profile.py
SilverSight Agent 3c35fe50c2 Initial SilverSight: deterministic equation search via Fisher geometry
Core components:
- ChentsovFinite.lean (883 lines, 0 sorry): Fisher metric uniqueness on 8-state simplex
- HachimojiCodec.lean: Deterministic E=mc^2 -> Hachimoji state pipeline
- PVGS_DQ_Bridge (8 sections, ~6,150 lines): Photon-Varied Gaussian to Dual Quaternion
- UniversalMathEncoding.lean: 50-token math address space (~10^15 addresses)
- ChiralitySpace.lean: 4D descriptor (phase x chirality x direction x regime) ~2x10^25
- BindingSite (3 files): Amino acid vocabulary, entropy-based bindability
- Python: chaos game, Sidon addressing, Q16.16 canonical, Finsler metric, QUBO/QAOA
- CI: Lean check, Python check, Q16 roundtrip workflows

Papers: Giani-Win-Conti 2025, Chabaud-Mehraban 2022, Pizzimenti 2024, Wassner 2025
2026-06-21 18:02:05 +08:00

209 lines
7.4 KiB
Python

#!/usr/bin/env python3
"""
spectral_profile.py — 8D Spectral Profile from Byte-Level Co-occurrence Statistics
Computes an 8-dimensional spectral profile from the raw byte structure of an
equation string. Uses ONLY byte-level co-occurrence statistics — no semantic
parsing, no tokenization, no NLP.
The 8 dimensions are derived from the byte co-occurrence matrix C where
C[i,j] = count of byte i followed by byte j (with wrap-around).
"""
import math
from typing import List
def compute_spectral_profile(equation: str) -> List[float]:
"""Compute 8D spectral profile from equation structure.
Uses byte-level co-occurrence statistics (not semantic parsing).
Produces a profile that the chaos game converges to.
The 8 dimensions:
0 — normalized_byte_entropy: Shannon entropy of byte distribution
1 — diagonal_strength: Self-transition ratio
2 — spectral_gap: Dominant / subdominant singular value ratio
3 — length_complexity: Length-sensitive complexity score
4 — asymmetry: Non-symmetry of co-occurrence matrix
5 — symbol_diversity: Unique byte ratio
6 — run_structure: Mean run length of repeated bytes
7 — edge_activity: Activity at byte boundaries (256 wrap)
"""
if not equation:
return [0.125] * 8
data = equation.encode('utf-8')
n = len(data)
if n == 0:
return [0.125] * 8
# ── Byte frequency ──────────────────────────────────────────────
freq = [0] * 256
for b in data:
freq[b] += 1
# ── Dimension 0: byte entropy (Shannon, normalized) ────────────
entropy = 0.0
for count in freq:
if count > 0:
p = count / n
entropy -= p * math.log2(p)
max_entropy = math.log2(min(n, 256))
dim0 = entropy / max_entropy if max_entropy > 0 else 0
# ── Co-occurrence matrix ────────────────────────────────────────
C = [[0] * 256 for _ in range(256)]
for i in range(n):
C[data[i]][data[(i + 1) % n]] += 1
total_trans = n
# ── Dimension 1: diagonal strength ─────────────────────────────
diag_sum = sum(C[i][i] for i in range(256))
dim1 = diag_sum / total_trans if total_trans > 0 else 0
# ── Dimension 2: spectral gap via power iteration ──────────────
# Build a small representative matrix: collapse 256→8 by byte class
# Classify bytes into 8 buckets and compute 8x8 transition matrix
buckets = [0] * 256
for i in range(256):
if i < 32: buckets[i] = 0 # control
elif i < 48: buckets[i] = 1 # punctuation/special
elif i < 58: buckets[i] = 2 # digits
elif i < 65: buckets[i] = 3 # more punctuation
elif i < 91: buckets[i] = 4 # uppercase
elif i < 97: buckets[i] = 5 # more punctuation
elif i < 123: buckets[i] = 6 # lowercase
elif i < 128: buckets[i] = 7 # extended ascii
else: buckets[i] = i % 8 # unicode spread
M8 = [[0.0] * 8 for _ in range(8)]
for i in range(256):
for j in range(256):
if C[i][j] > 0:
bi, bj = buckets[i], buckets[j]
M8[bi][bj] += C[i][j]
# Normalize
for i in range(8):
row_sum = sum(M8[i])
if row_sum > 0:
for j in range(8):
M8[i][j] /= row_sum
# Power iteration for top 2 eigenvalues
def power_iter(M, iters=30):
n = len(M)
v = [math.sin(i * 1.324717957) + 0.01 for i in range(n)]
# Normalize
norm = math.sqrt(sum(x*x for x in v))
v = [x/norm for x in v]
for _ in range(iters):
new_v = [0.0] * n
for i in range(n):
s = 0.0
for j in range(n):
s += M[i][j] * v[j]
new_v[i] = s
norm = math.sqrt(sum(x*x for x in new_v))
if norm < 1e-15:
break
v = [x/norm for x in new_v]
# Rayleigh quotient
Av = [sum(M[i][j] * v[j] for j in range(n)) for i in range(n)]
val = sum(v[i] * Av[i] for i in range(n))
return val, v
val1, v1 = power_iter(M8)
# Deflate for second eigenvalue
for i in range(8):
for j in range(8):
M8[i][j] -= val1 * v1[i] * v1[j]
val2, _ = power_iter(M8)
val2 = abs(val2)
if val2 > 1e-10:
gap = val1 / val2
dim2 = min(1.0, (gap - 1.0) / 10.0) # normalize: gap of 11 → 1.0
else:
dim2 = 1.0
# ── Dimension 3: length complexity ──────────────────────────────
# Short equations → low, long equations → high, with diminishing returns
dim3 = min(1.0, n / 50.0)
# ── Dimension 4: asymmetry ──────────────────────────────────────
# Frobenius norm of (C - C^T)
diff_sq = 0.0
total_sq = 0.0
for i in range(256):
for j in range(256):
d = C[i][j] - C[j][i]
s = C[i][j] + C[j][i]
diff_sq += d * d
total_sq += s * s
if total_sq > 0:
dim4 = min(1.0, math.sqrt(diff_sq) / math.sqrt(total_sq))
else:
dim4 = 0.0
# ── Dimension 5: symbol diversity ──────────────────────────────
unique_bytes = sum(1 for f in freq if f > 0)
dim5 = unique_bytes / min(n, 256) if n > 0 else 0
# ── Dimension 6: run structure ─────────────────────────────────
# Mean run length of identical consecutive bytes
if n > 0:
runs = []
current_run = 1
for i in range(1, n):
if data[i] == data[i-1]:
current_run += 1
else:
runs.append(current_run)
current_run = 1
runs.append(current_run)
mean_run = sum(runs) / len(runs)
dim6 = min(1.0, mean_run / (n ** 0.5)) if n > 0 else 0
else:
dim6 = 0.0
# ── Dimension 7: edge_activity ─────────────────────────────────
# Transitions that cross byte-class boundaries
cross_count = 0
for i in range(n):
if buckets[data[i]] != buckets[data[(i+1) % n]]:
cross_count += 1
dim7 = cross_count / n if n > 0 else 0
profile = [dim0, dim1, dim2, dim3, dim4, dim5, dim6, dim7]
# Normalize
s = sum(profile)
if s > 0:
profile = [p / s for p in profile]
return profile
def profile_to_basin_hint(profile: List[float]) -> str:
"""Get a rough basin hint from the spectral profile."""
d0, d1, d2, d3, d4, d5, d6, d7 = profile
void_score = d0 + d6 # entropy + runs (trivial patterns)
orbit_score = d2 + d7 # spectral gap + edge activity
braid_score = d1 + d4 # diagonal + asymmetry
observer_score = d3 + d5 # length + diversity
scores = {
"q_void": void_score,
"q_orbit": orbit_score,
"q_braid": braid_score,
"q_observer": observer_score,
}
return max(scores, key=scores.get)