summaryrefslogtreecommitdiff
path: root/src/eval.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.py')
-rw-r--r--src/eval.py23
1 files changed, 8 insertions, 15 deletions
diff --git a/src/eval.py b/src/eval.py
index ad1d7f3..191ac79 100644
--- a/src/eval.py
+++ b/src/eval.py
@@ -57,8 +57,10 @@ def _sieve_rank_signature(k: int, lo: int, hi: int) -> set[int]:
def _compute_sieve_rank(preds: list[int], lo: int, hi: int) -> int | None:
- """Find the smallest composite predicted as 'prime' with all factors > p_k.
+ """Find the most specific sieve rank that explains the model's error predictions.
Returns k (the number of primes in the sieve, 1-indexed) or None.
+ A rank-k sieve checks {2,3,...,p_k} and misses composites with all factors > p_k.
+ We want the LARGEST k whose signature set contains the model's error predictions.
"""
primes = sieve_primes(hi + 100)
composites_in_range = set()
@@ -77,21 +79,12 @@ def _compute_sieve_rank(preds: list[int], lo: int, hi: int) -> int | None:
pred_composites = sorted(composites_in_range & set(preds))
if not pred_composites:
return None # no composites predicted — either exact or garbage
- smallest = pred_composites[0]
- # find k such that all factors of smallest are > primes[k-1]
- for k in range(1, 50):
+ # find the LARGEST k whose rank-k signature contains all error predictions
+ for k in range(40, 0, -1):
if k >= len(primes):
- return None
- pk = primes[k - 1]
- # check if ANY prime ≤ pk divides smallest
- has_small_factor = False
- for p in primes:
- if p > pk:
- break
- if smallest % p == 0:
- has_small_factor = True
- break
- if not has_small_factor:
+ continue
+ sig = _sieve_rank_signature(k, lo, hi)
+ if all(p in sig for p in pred_composites):
return k
return None