| """ |
| PROBLEM 1: Cramér's Conjecture — Prime Gap Distribution |
| ======================================================== |
| BACKGROUND: |
| Cramér (1936): lim sup g(p)/(ln p)² = 1 |
| Granville (1995): true constant is 2e^{-γ} ≈ 1.1229 |
| NOBODY HAS DISCRIMINATED BETWEEN THEM EMPIRICALLY. |
| |
| HOW TO SOLVE: |
| 1. Compute prime gaps for primes up to 10^7 |
| 2. Compute Cramér ratio g(p)/(ln p)² for ALL prime gaps |
| 3. Build histogram of ratio distribution |
| 4. Compare tail behavior to: |
| - Cramér: P(ratio > λ) ~ e^{-λ} |
| - Granville: P(ratio > λ) ~ e^{-2e^γ · λ} where 2e^γ ≈ 3.562 |
| 5. Statistical test: which model fits the tail better? |
| """ |
|
|
| import numpy as np |
| from typing import Dict, List |
| from scipy import stats |
|
|
|
|
| class CramerGapAnalyzer: |
| def __init__(self): |
| self.results = {} |
| self.primes = [] |
| self.gaps = [] |
| self.ratios = [] |
|
|
| def sieve_primes(self, limit: int) -> np.ndarray: |
| sieve = np.ones(limit + 1, dtype=bool) |
| sieve[:2] = False |
| for i in range(2, int(limit ** 0.5) + 1): |
| if sieve[i]: |
| sieve[i * i::i] = False |
| return np.where(sieve)[0] |
|
|
| def analyze(self, limit: int = 5_000_000) -> Dict: |
| print(f" [Cramér] Sieving primes up to {limit:,}...") |
| self.primes = self.sieve_primes(limit) |
| self.gaps = np.diff(self.primes) |
| log_primes = np.log(self.primes[1:]) |
| self.ratios = self.gaps / (log_primes ** 2) |
|
|
| |
| thresholds = np.linspace(0.1, 2.0, 50) |
| empirical_survival = [] |
| cramer_survival = [] |
| granville_survival = [] |
|
|
| two_e_gamma = 2.0 * np.exp(0.5772156649015329) |
|
|
| for lam in thresholds: |
| emp_surv = np.mean(self.ratios > lam) |
| empirical_survival.append(emp_surv) |
| cramer_survival.append(np.exp(-lam)) |
| granville_survival.append(np.exp(-two_e_gamma * lam)) |
|
|
| |
| tail_mask = thresholds > 0.5 |
| if np.sum(tail_mask) > 5: |
| emp_tail = np.array(empirical_survival)[tail_mask] |
| cra_tail = np.array(cramer_survival)[tail_mask] |
| gra_tail = np.array(granville_survival)[tail_mask] |
| |
| cra_error = np.sum((emp_tail - cra_tail) ** 2) |
| gra_error = np.sum((emp_tail - gra_tail) ** 2) |
| else: |
| cra_error = gra_error = 0 |
|
|
| |
| valid = np.array(empirical_survival) > 0.001 |
| if np.sum(valid) > 5: |
| log_emp = -np.log(np.array(empirical_survival)[valid]) |
| log_thresholds = thresholds[valid] |
| cramer_fit = np.polyfit(log_thresholds, log_emp, 1) |
| granville_fit = np.polyfit(log_thresholds, log_emp / two_e_gamma, 1) if two_e_gamma > 0 else [0, 0] |
| else: |
| cramer_fit = [1.0, 0.0] |
| granville_fit = [1.0, 0.0] |
|
|
| self.results = { |
| 'limit': limit, |
| 'n_primes': len(self.primes), |
| 'n_gaps': len(self.gaps), |
| 'max_ratio': float(np.max(self.ratios)), |
| 'mean_ratio': float(np.mean(self.ratios)), |
| 'std_ratio': float(np.std(self.ratios)), |
| 'max_gap': int(np.max(self.gaps)), |
| 'mean_gap': float(np.mean(self.gaps)), |
| 'thresholds': thresholds.tolist(), |
| 'empirical_survival': empirical_survival, |
| 'cramer_survival': cramer_survival, |
| 'granville_survival': granville_survival, |
| 'tail_error_cramer': float(cra_error), |
| 'tail_error_granville': float(gra_error), |
| 'better_model': 'Cramér' if cra_error < gra_error else 'Granville', |
| 'cramer_fit_slope': float(cramer_fit[0]), |
| 'granville_adjusted_slope': float(granville_fit[0]) if len(granville_fit) > 0 else 0, |
| } |
| return self.results |
|
|
| def summary(self) -> str: |
| r = self.results |
| s = f"Cramér Gap Analysis (up to {r['limit']:,})\n{'='*50}\n" |
| s += f"Primes: {r['n_primes']:,}, Gaps: {r['n_gaps']:,}\n" |
| s += f"Max gap: {r['max_gap']}, Max ratio: {r['max_ratio']:.4f}\n" |
| s += f"Mean gap: {r['mean_gap']:.2f}, Mean ratio: {r['mean_ratio']:.4f}\n" |
| s += f"Tail fit: {r['better_model']} model is BETTER (lower L² error)\n" |
| s += f" Cramér tail L² error: {r['tail_error_cramer']:.6f}\n" |
| s += f" Granville tail L² error: {r['tail_error_granville']:.6f}\n" |
| s += f"Note: Max observed ratio {r['max_ratio']:.4f} < 0.921 (record), insufficient to discriminate.\n" |
| return s |
|
|