File size: 1,717 Bytes
f26b7d5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 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])