18338RMTProject / beta_backend_python.py
rosenyu's picture
Create beta_backend_python.py
f26b7d5 verified
# beta_backend_python.py
import numpy as np
from scipy.special import gamma
from scipy.optimize import minimize_scalar
def loglike_beta(beta, s):
"""
Log-likelihood of Wigner surmise for Dyson index beta:
P(s;β) = aβ * s^β * exp(-bβ * s^2)
"""
if beta <= 0:
return -np.inf
bβ = (gamma((beta + 2) / 2) / gamma((beta + 1) / 2)) ** 2
aβ = 2 * (bβ ** ((beta + 1) / 2)) / gamma((beta + 1) / 2)
return np.sum(np.log(aβ) + beta * np.log(s) - bβ * s * s)
def beta_mle(spacings):
"""
Python version of Julia's beta_mle(spacings)
"""
s = spacings / np.mean(spacings) # normalize to ⟨s⟩ = 1
# maximize log-likelihood → minimize negative log-likelihood
def objective(beta):
return -loglike_beta(beta, s)
result = minimize_scalar(
objective,
bounds=(0.1, 5.0),
method="bounded",
options={"xatol": 1e-5},
)
if not result.success:
raise RuntimeError("β optimization failed: " + result.message)
return float(result.x)
def compute_beta_file(path):
"""
Reads a text file of spacings and prints β̂.
"""
with open(path, "r") as f:
raw = f.read()
# replace commas → spaces
for c in [",", "\n", "\t"]:
raw = raw.replace(c, " ")
toks = raw.split()
if len(toks) == 0:
raise ValueError("No valid numbers found.")
spacings = np.array([float(t) for t in toks], dtype=float)
beta_hat = beta_mle(spacings)
print(beta_hat)
if __name__ == "__main__":
import sys
if len(sys.argv) != 1 + 1:
raise SystemExit("Usage: python beta_backend_python.py <data_file>")
compute_beta_file(sys.argv[1])