ml-intern
swayam1111 commited on
Commit
168d8f1
·
verified ·
1 Parent(s): c4cca0e

Upload problem_solvers/lehmer_phenomena.py

Browse files
Files changed (1) hide show
  1. problem_solvers/lehmer_phenomena.py +66 -0
problem_solvers/lehmer_phenomena.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ PROBLEM 8: Zero Spacing Records — Lehmer Phenomena
3
+ ====================================================
4
+ Unusually close zeros are called "Lehmer phenomena".
5
+ OPEN: characterize the distribution of closest pairs among large zeros.
6
+ """
7
+
8
+ import numpy as np
9
+ from typing import Dict
10
+
11
+
12
+ class LehmerPhenomenaAnalyzer:
13
+ def __init__(self, zeros: list):
14
+ self.zeros = np.array(zeros)
15
+ self.results = {}
16
+
17
+ def analyze(self) -> Dict:
18
+ spacings = np.diff(self.zeros)
19
+ # Normalize by local mean spacing
20
+ window = 50
21
+ normalized = np.zeros(len(spacings))
22
+ for i in range(len(spacings)):
23
+ start = max(0, i - window // 2)
24
+ end = min(len(spacings), i + window // 2)
25
+ local_mean = np.mean(spacings[start:end])
26
+ normalized[i] = spacings[i] / local_mean if local_mean > 0 else 1.0
27
+
28
+ # Find minimum spacings
29
+ min_spacing = float(np.min(normalized))
30
+ min_idx = int(np.argmin(normalized))
31
+
32
+ # Small spacing distribution
33
+ small_threshold = 0.3
34
+ n_small = int(np.sum(normalized < small_threshold))
35
+
36
+ # GUE prediction for small spacings: P(s) ~ (πs)²/2 for small s
37
+ # Wigner surmise: p(s) = (π/2)s exp(-πs²/4)
38
+ s_bins = np.linspace(0, 3, 60)
39
+ hist, _ = np.histogram(normalized, bins=s_bins, density=True)
40
+ wigner = (np.pi / 2) * s_bins[:-1] * np.exp(-np.pi * s_bins[:-1] ** 2 / 4)
41
+
42
+ self.results = {
43
+ 'n_zeros': len(self.zeros),
44
+ 'min_normalized_spacing': min_spacing,
45
+ 'min_spacing_index': min_idx,
46
+ 'min_spacing_gamma': float(self.zeros[min_idx]),
47
+ 'mean_spacing': float(np.mean(spacings)),
48
+ 'std_spacing': float(np.std(spacings)),
49
+ 'n_small_spacings': n_small,
50
+ 'fraction_small': float(n_small / len(normalized)),
51
+ 'spacing_histogram': hist.tolist(),
52
+ 'wigner_prediction': wigner.tolist(),
53
+ 'bin_centers': ((s_bins[:-1] + s_bins[1:]) / 2).tolist(),
54
+ 'top_10_smallest': [float(v) for v in np.sort(normalized)[:10]],
55
+ }
56
+ return self.results
57
+
58
+ def summary(self) -> str:
59
+ r = self.results
60
+ s = f"Lehmer Phenomena Analysis\n{'='*50}\n"
61
+ s += f"Zeros: {r['n_zeros']:,}\n"
62
+ s += f"Min normalized spacing: {r['min_normalized_spacing']:.6f}\n"
63
+ s += f"At γ ≈ {r['min_spacing_gamma']:.2f} (index {r['min_spacing_index']})\n"
64
+ s += f"Spacings < 0.3: {r['n_small_spacings']} ({r['fraction_small']:.4%})\n"
65
+ s += f"Top 10 smallest: {r['top_10_smallest'][:5]}\n"
66
+ return s