#!/usr/bin/env python3 """ 16D Chaos Game via QR Braid Crossings. The 16D manifold V₁₆ = (q_void, q_orbit, q_braid, q_observer) is encoded as an 8×8 matrix where each row is a 2×4 block (8 strands × 2 quadrants). Householder reflections (braid crossings) are randomly applied — the accumulated trajectory is the shock front of the 16D chaos game. The attractor structure reveals the "folded prime" geometry of the 16D search manifold. Reference: - VCN QR pipeline (vcn_dsp_pipeline.py) — Householder = braid crossing - BraidShock 16D (braid_shock_16d.py) — 16D shock propagation - 16D Manifold Adjustment doc — V₁₆ decomposition """ import hashlib import json import math import random from collections import Counter from datetime import datetime, timezone Q16 = 65536 EPSILON = 1e-14 def sidon(k): return 1 << k def random_householder(n): """Generate a random Householder reflector H = I - τ·v·vᵀ.""" v = [random.uniform(-1, 1) for _ in range(n)] norm = math.sqrt(sum(xi * xi for xi in v)) if norm < EPSILON: return [float(i == j) for i in range(n)], 0.0 v = [xi / norm for xi in v] tau = 2.0 # full reflection for normalized v return v, tau def apply_reflector(A, k, v, tau): """Apply Householder reflector at column k of matrix A.""" m = len(A) n = len(A[0]) for j in range(k, n): dot = sum(v[i] * A[i][j] for i in range(m)) for i in range(m): A[i][j] -= tau * v[i] * dot class ChaosGame16D: """16D chaos game driven by random Householder braid crossings.""" def __init__(self, size=8): self.size = size # 8×8 matrix encodes 16D state self.history = [] self.quadrant_map = { "q_void": (0, 3), # rows 0-3, cols 0-1 (4D) "q_orbit": (0, 3), # rows 0-3, cols 2-3 (4D) "q_braid": (4, 7), # rows 4-7, cols 0-1 (4D) "q_observer": (4, 7), # rows 4-7, cols 2-3 (4D) } def init_state(self, mode="random"): """Initialize the 8×8 state matrix for the chaos game.""" A = [[0.0] * self.size for _ in range(self.size)] if mode == "identity": for i in range(self.size): A[i][i] = 1.0 elif mode == "sidon": # Sidon-labeled diagonal: powers of 2 for i in range(self.size): A[i][i] = sidon(i) elif mode == "random": for i in range(self.size): for j in range(self.size): A[i][j] = random.uniform(-1, 1) elif mode == "unit": # All-ones matrix (uniform energy) for i in range(self.size): for j in range(self.size): A[i][j] = 1.0 return A def step(self, A, target_strand=None): """One chaos game step: apply a random Householder reflector. If target_strand is None, picks a random strand (0..7). Returns the reflector info and the new matrix.""" k = target_strand if target_strand is not None else random.randint(0, self.size - 1) v, tau = random_householder(self.size - k) # Pad v to full size v_full = [0.0] * k + v apply_reflector(A, k, v_full, tau) return { "strand": k, "sidon": sidon(k), "tau": round(tau, 4), "nz": sum(1 for vi in v if abs(vi) > EPSILON), } def run(self, steps=1000, record_every=10): """Run the chaos game for `steps` iterations.""" A = self.init_state("random") self.history = [] trace = [] for s in range(steps): ref = self.step(A) if s % record_every == 0: # Compute quadrant energies energy = self.quadrant_energy(A) trace.append({ "step": s, "last_strand": ref["strand"], "sidon": ref["sidon"], "energy": energy, }) self.history = trace return A def quadrant_energy(self, A): """Compute energy in each 4D quadrant of the 16D manifold.""" qe = {} for name, (r_start, r_end) in self.quadrant_map.items(): e = 0.0 for i in range(r_start, r_end + 1): for j in range(self.size): e += A[i][j] * A[i][j] qe[name] = round(math.sqrt(e), 6) qe["total"] = round(sum(qe.values()), 6) return qe def energy_ratio(self, A): """Compute q_braid / q_void energy ratio = braid tension.""" qe = self.quadrant_energy(A) v = qe["q_void"] return qe["q_braid"] / v if v > 0 else float("inf") def sidon_sumset(self): """Compute the Sidon sumset of all visited strand pairs.""" pairs = set() for t in self.history: s = t["sidon"] for other_s in [sidon(i) for i in range(self.size)]: if other_s != s: pairs.add(s + other_s) return sorted(pairs) def main(): random.seed(42) print("=" * 60) print("16D Chaos Game — QR Braid Crossing Model") print("=" * 60) game = ChaosGame16D() # ─── Run multiple trajectories ─────────────────────────────────────── trajectories = [] for trial in range(5): A = game.run(steps=500, record_every=25) final_energy = game.quadrant_energy(A) braid_tension = game.energy_ratio(A) sumset = game.sidon_sumset() print(f"\nTrial {trial + 1}:") print(f" Final energy: {final_energy['total']:.4f}") print(f" Braid tension: {braid_tension:.4f} (q_braid/q_void)") print(f" Sidon sumset: {len(sumset)} unique sums") print(f" Strand usage: {Counter(t['last_strand'] for t in game.history).most_common(3)}") trajectories.append({ "trial": trial + 1, "final_energy": final_energy, "braid_tension": round(braid_tension, 4), "sidon_sumset_size": len(sumset), "sidon_sumset": sumset[:20], # first 20 "energy_evolution": game.history[::4], }) # ─── Run with fixed Sidon sequence ─────────────────────────────────── print(f"\n{'─' * 60}") print("Sidon-ordered chaos: cycling strands 0..7 repeatedly") A = game.init_state("sidon") sidon_trace = [] for cycle in range(10): for strand in range(8): ref = game.step(A, target_strand=strand) if cycle % 2 == 0: sidon_trace.append({ "cycle": cycle, "strand": strand, "sidon": ref["sidon"], "energy": game.quadrant_energy(A), }) final = game.quadrant_energy(A) print(f" Final energy: {final['total']:.4f}") print(f" Quadrants: { {k: round(v, 4) for k, v in final.items()} }") # ─── Receipt ───────────────────────────────────────────────────────── receipt = { "schema": "rrc_chaos_game_16d_v1", "claim_boundary": "random_householder_braid_crossings_on_8x8;sidon_mapped_quadrants", "description": ( "The 16D chaos game applies random Householder reflections " "(braid crossings) to an 8×8 state matrix. The 16D manifold " "quadrants (q_void, q_orbit, q_braid, q_observer) are 4×8 " "blocks of the matrix. Sidon addresses {1..128} label the " "8 strands. The attractor is the shock front ensemble." ), "v16_structure": { "encoding": "8×8 matrix split into 4 quadrant blocks", "q_void": "rows 0-3, cols 0-1", "q_orbit": "rows 0-3, cols 2-3", "q_braid": "rows 4-7, cols 0-1", "q_observer": "rows 4-7, cols 2-3", }, "sidon_addresses": [sidon(k) for k in range(8)], "trajectories": trajectories, "sidon_ordered": sidon_trace, "summary": { "total_trials": len(trajectories), "avg_braid_tension": round(sum(t["braid_tension"] for t in trajectories) / len(trajectories), 4), "avg_energy": round(sum(t["final_energy"]["total"] for t in trajectories) / len(trajectories), 4), }, "computed_at": datetime.now(timezone.utc).isoformat(), } canonical = json.dumps(receipt, sort_keys=True, separators=(",", ":")) receipt["receipt_sha256"] = hashlib.sha256(canonical.encode()).hexdigest() path = "chaos_game_16d_receipt.json" with open(path, "w") as f: json.dump(receipt, f, indent=2) print(f"\n{'=' * 60}") print(f"Receipt: {path}") print(f"SHA256: {receipt['receipt_sha256']}") if __name__ == "__main__": main()