"""neural_ca -- a Loschmidt echo in a reversible cellular automaton. The Margolus block rule is a bijection, so a gas of ~2,000 particles mixed for 500 steps can be un-mixed by iterating the same rule backward: the initial configuration returns cell-for-cell (particle number conserved throughout). Yet flipping a single cell of the mixed state before reversing corrupts roughly half the reconstructed past -- exact reversibility and sensitive dependence in the same automaton. python demos/neural_ca_loschmidt_echo.py """ import os, sys, time, random, statistics HERE = os.path.dirname(os.path.abspath(__file__)) REPO = os.path.dirname(HERE) sys.path.insert(0, os.path.join(REPO, "src")) import ca def coarse(g, H, W, k=8): out = [] for by in range(0, H, k): for bx in range(0, W, k): out.append(sum(g[y][x] for y in range(by, by + k) for x in range(bx, bx + k))) return out if __name__ == "__main__": H = W = 64 rng = random.Random(2026) grid = [[1 if rng.random() < 0.5 else 0 for _ in range(W)] for _ in range(H)] n0 = sum(map(sum, grid)) STEPS = 500 print("neural_ca: Loschmidt echo (mix, then run time backward)") print("=" * 56) t0 = time.perf_counter() fwd = ca.run(grid, STEPS, 0) n1 = sum(map(sum, fwd)) back = ca.run_back(fwd, STEPS, 0) echo = back == grid dt = time.perf_counter() - t0 print(f"particles: {n0} at t=0, {n1} at t={STEPS} " f"({'conserved' if n0 == n1 else 'NOT CONSERVED'})") print(f"coarse 8x8 occupancy stdev: t=0 {statistics.pstdev(coarse(grid, H, W)):.2f} " f"-> t={STEPS} {statistics.pstdev(coarse(fwd, H, W)):.2f} (mixed)") print(f"{STEPS} steps forward + {STEPS} reversed in {dt:.1f}s: " f"t=0 recovered {'EXACTLY' if echo else 'FAILED'}") flip = [row[:] for row in fwd] flip[0][0] ^= 1 back2 = ca.run_back(flip, STEPS, 0) ham = sum(back2[y][x] != grid[y][x] for y in range(H) for x in range(W)) print(f"butterfly: flip ONE cell at t={STEPS}, reverse again -> reconstructed " f"past wrong in {ham}/{H * W} cells")