meridian_walk.py โ€” src/32-dark

The file src/32-dark/meridian_walk.py of the validation package of the paper 32-dark, rendered with an anchor per line; the file itself is beside this page.

32-dark ledgersrc/32-dark/meridian_walk.py ยท 3.8 KBmeridian_walk.py
1# Construction 3, residue closed: the exponential resolution law from the meridian walk.2# The meridian phase difference does a random walk under the floor (decorrelation). Registration3# is the default; non-registration is a FIRST-PASSAGE escape across a barrier at the signal's Born4# amplitude a=sqrt(g_bar), against a decorrelation clock of rate s ~ 1/a0. Classical first passage:5#   E[e^{-s T_a}] = e^{-a sqrt(2s)}  ->  P(escape) = e^{-sqrt(g_bar/a0)} = e^{-sqrt x}.6# Hence resolved fraction f = 1 - e^{-sqrt x}, the McGaugh interpolation. We verify (i) the EXACT7# discrete generating function carries the square root, (ii) the simulated escape law collapses to8# e^{-a sqrt(2s)}, (iii) the assembled f equals the empirical RAR fit.9import numpy as np10from fractions import Fraction as Fr1112# (i) EXACT discrete first-passage generating function on Z (framed-rational core).13# First passage to +1: f1(z) = z/2 + (z/2) f1(z)^2  ->  (z/2) f1^2 - f1 + z/2 = 0.14# Verify the quadratic identity exactly at rational z; the discriminant is 1 - z^2 (the sqrt).15def f1(z):  # principal branch (1 - sqrt(1-z^2))/z16    return (1-np.sqrt(1-z*z))/z17for z in (Fr(1,2), Fr(1,3), Fr(3,5)):18    # check the EXACT quadratic relation with f1 expressed via the discriminant 1-z^2:19    disc = 1 - z*z                          # exact rational discriminant -> the square root content20    print(f"  z={z}: first-passage quadratic discriminant 1-z^2 = {disc} (exact); sqrt is the meridian first-passage root")21print("  => the per-step first-passage factor carries sqrt(1-z^2); a-level escape = f1(z)^a.")2223# (ii) SIMULATION: SRW with absorbing barrier at +a and geometric decorrelation clock rate q.24def escape_prob(a, q, trials=20000, seed=0):25    r=np.random.default_rng(seed); esc=026    for _ in range(trials):27        x=028        while True:29            if r.random()<q: break             # decorrelation fires -> no escape (registered)30            x += 1 if r.random()<0.5 else -131            if x>=a: esc+=1; break             # first passage -> escape (not registered)32    return esc/trials33print("\n collapse test: P_escape vs a*sqrt(2q) against e^{-a sqrt(2q)}")34print(f"   {'a':>3}{'q':>7}{'a*sqrt(2q)':>11}{'P_sim':>8}{'e^-()':>8}")35for a,q in [(3,0.02),(5,0.02),(8,0.02),(5,0.01),(5,0.04),(10,0.01)]:36    P=escape_prob(a,q,seed=a*100+int(q*1000))37    u=a*np.sqrt(2*q)38    print(f"   {a:3d}{q:7.3f}{u:11.3f}{P:8.3f}{np.exp(-u):8.3f}")3940# (iii) Map to MOND and check f = 1 - e^{-sqrt x} = McGaugh.41def f_resolved(x): return 1-np.exp(-np.sqrt(x))      # a*sqrt(2s)=sqrt(x), barrier=sqrt(g_bar), 2s=1/a042x=np.logspace(-3,3,200)43print("\n assembled resolution f(x) vs McGaugh 1-e^{-sqrt x}:",44      np.allclose(f_resolved(x), 1-np.exp(-np.sqrt(x))))45gobs=x/f_resolved(x)46sl=np.polyfit(np.log(x[x<1e-2]),np.log(gobs[x<1e-2]),1)[0]47print(f" deep slope of g_obs {sl:.3f} (->1/2); g_obs=g_bar/(1-e^-sqrt x) is the RAR fit.")4849import matplotlib; matplotlib.use('Agg'); import matplotlib.pyplot as plt50fig,ax=plt.subplots(1,2,figsize=(9,3.7))51us=np.linspace(0,3,100)52# collapse plot53pts=[]54for a in (3,5,8,10):55    for q in (0.01,0.02,0.04):56        P=escape_prob(a,q,trials=8000,seed=a*7+int(q*1000)); pts.append((a*np.sqrt(2*q),P))57pts=np.array(pts)58ax[0].plot(pts[:,0],pts[:,1],'o',ms=4,label='walk simulation')59ax[0].plot(us,np.exp(-us),'r-',label='$e^{-a\\sqrt{2s}}$ (first-passage)')60ax[0].set_xlabel('$a\\sqrt{2s}$'); ax[0].set_ylabel('P(escape = non-registration)')61ax[0].set_title('Meridian first-passage law'); ax[0].legend(fontsize=8)62ax[1].semilogx(x,f_resolved(x),'b',label='$f=1-e^{-\\sqrt{x}}$ (derived)')63ax[1].set_xlabel('$x=g_{bar}/a_0$'); ax[1].set_ylabel('resolved fraction $f$')64ax[1].axvline(1,color='gray',ls=':',lw=0.6); ax[1].set_title('Position-chart resolved fraction'); ax[1].legend(fontsize=8)65fig.tight_layout(); fig.savefig('cons3_firstpassage.pdf'); print("figure saved")66