threshold-computers / demos /neural_ca_loschmidt_echo.py
CharlesCNorton
demos: standalone per-machine programs that put each machine to work
8f34e5f
Raw
History Blame Contribute Delete
2.12 kB
"""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")