ml-intern
swayam1111 commited on
Commit
8ddca8d
·
verified ·
1 Parent(s): 1e94df5

Upload problem_solvers/ktuple_constants.py

Browse files
Files changed (1) hide show
  1. problem_solvers/ktuple_constants.py +97 -0
problem_solvers/ktuple_constants.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ PROBLEM 5: Hardy-Littlewood k-Tuple Constants
3
+ ===============================================
4
+ Verify the density of prime k-tuples against Hardy-Littlewood predictions.
5
+ """
6
+
7
+ import numpy as np
8
+ from typing import Dict, List
9
+
10
+
11
+ class KTupleAnalyzer:
12
+ def __init__(self):
13
+ self.results = {}
14
+
15
+ def sieve_primes(self, limit: int) -> List[int]:
16
+ sieve = np.ones(limit + 1, dtype=bool)
17
+ sieve[:2] = False
18
+ for i in range(2, int(limit ** 0.5) + 1):
19
+ if sieve[i]:
20
+ sieve[i * i::i] = False
21
+ return np.where(sieve)[0].tolist()
22
+
23
+ def count_patterns(self, primes: List[int], pattern: List[int]) -> int:
24
+ """Count occurrences of a k-tuple pattern."""
25
+ prime_set = set(primes)
26
+ count = 0
27
+ for p in primes:
28
+ if all((p + d) in prime_set for d in pattern):
29
+ count += 1
30
+ return count
31
+
32
+ def hardy_littlewood_constant(self, pattern: List[int]) -> float:
33
+ """
34
+ Compute the Hardy-Littlewood constant 𝔖(H) for pattern H.
35
+ 𝔖(H) = ∏_p (1 - 1/p)^{-k} * (1 - ν_H(p)/p)
36
+ where ν_H(p) is number of distinct residues mod p occupied by H.
37
+ Approximate for small p.
38
+ """
39
+ from sympy import primerange, Rational
40
+ k = len(pattern)
41
+ product = 1.0
42
+ for p in primerange(2, 100):
43
+ residues = set((d % p) for d in pattern)
44
+ nu_H = len(residues)
45
+ if nu_H == p:
46
+ continue # Pattern impossible mod p
47
+ term = (1.0 - 1.0 / p) ** (-k) * (1.0 - nu_H / p)
48
+ product *= term
49
+ return product
50
+
51
+ def analyze(self, limit: int = 2_000_000) -> Dict:
52
+ primes = self.sieve_primes(limit)
53
+ prime_set = set(primes)
54
+ n_primes = len(primes)
55
+ x = limit
56
+
57
+ patterns = {
58
+ 'twin': [0, 2],
59
+ 'cousin': [0, 4],
60
+ 'sexy': [0, 6],
61
+ 'triplet1': [0, 2, 6],
62
+ 'triplet2': [0, 4, 6],
63
+ 'quadruplet': [0, 2, 6, 8],
64
+ }
65
+
66
+ results = {}
67
+ for name, pat in patterns.items():
68
+ count = self.count_patterns(primes, pat)
69
+ k = len(pat)
70
+ hl_const = self.hardy_littlewood_constant(pat)
71
+ # Predicted: count ~ 𝔖(H) · x / (log x)^k
72
+ predicted = hl_const * x / (np.log(x) ** k)
73
+ error = abs(count - predicted) / max(predicted, 1)
74
+
75
+ results[name] = {
76
+ 'pattern': pat,
77
+ 'count': count,
78
+ 'predicted': float(predicted),
79
+ 'hardy_littlewood_constant': float(hl_const),
80
+ 'relative_error': float(error),
81
+ 'k': k,
82
+ }
83
+
84
+ self.results = {
85
+ 'limit': limit,
86
+ 'n_primes': n_primes,
87
+ 'patterns': results,
88
+ }
89
+ return self.results
90
+
91
+ def summary(self) -> str:
92
+ r = self.results
93
+ s = f"Hardy-Littlewood k-Tuple Analysis (up to {r['limit']:,})\n{'='*50}\n"
94
+ for name, pat in r['patterns'].items():
95
+ s += f" {name:12s}: count={pat['count']:,}, predicted={pat['predicted']:.1f}, "
96
+ s += f"𝔖={pat['hardy_littlewood_constant']:.6f}, rel_err={pat['relative_error']:.4f}\n"
97
+ return s