Wiki
Wiki

Research notes on every problem, and a library of the papers behind them. Built from the open erdos repository.

erdos_699_off_diagonal_gcd_numeric.py

py
#!/usr/bin/env python3
"""Exact uniform coefficient-gcd bounds for both off-diagonal rectangles.

Directions (A,B,C) give rectangles (Am,Bm-1,Cm) and
(Am+1,Bm-2,Cm+1).  Write H=A+B+C and k_X=floor(X*t/H).
For eligible t, sum(k_X)=t-2, and both rectangles have these same
floors for every m at least the explicitly calculated stability bound.
The common prime interval is contained in both BFT Lemma 5.2 intervals:

 U_t(m)=(H*m-1)/t,
 V_t(m)=m*max((A+1/m0)/(k_A+1),B/(k_B+1),(C+1/m0)/(k_C+1)).

For m>=m0 the interval (V_t(m),U_t(m)] therefore divides both gcds.
The intervals are disjoint because each is a subset of the corresponding
interval for the first rectangle, and BFT's intervals are disjoint.

Dusart's theta upper bound (1+1/36260)x and the retained lower bound
x*(1-max(2.072/sqrt(x),1/60000)) give an exact rational lower rate for
log(G)/m. All divisions in the final sum round down to a fixed grid.
Only integer arithmetic is used in the certificate itself.
"""
from __future__ import annotations

from fractions import Fraction
import json
from math import isqrt
from pathlib import Path

RECTANGLE_SHIFTS = ((0, -1, 0), (1, -2, 1))


def floor_stability_bound(directions, t):
    """Least nonnegative m ensuring the selected three floors, both shifts."""
    H = sum(directions)
    floors = [X*t//H for X in directions]
    assert sum(floors) == t-2
    bound = 1
    for shifts in RECTANGLE_SHIFTS:
        total_shift = sum(shifts)
        for X, k, shift in zip(directions, floors, shifts):
            remainder = X*t-k*H
            assert 0 < remainder < H
            # k <= ((X*m+shift)*t)/(H*m+total_shift):
            rhs = k*total_shift-t*shift
            if rhs > 0:
                bound = max(bound, (rhs+remainder-1)//remainder)
            # ((X*m+shift)*t)/(H*m+total_shift) < k+1:
            rhs = t*shift-(k+1)*total_shift
            if rhs >= 0:
                bound = max(bound, rhs//(H-remainder)+1)
    return bound


def gcd_exponent_lower(A, B, C, *, terms=4000, m0=10**8,
                       scale=10**12, root_scale=10**6, theta_mode="fixed"):
    """Certify G >= exp(ell_lower*m) for both rectangles, every m>=m0.

    Returns a JSON-ready record. The caller compares ell_lower with its
    desired rate using Fraction. m0 must satisfy the exact floor bounds.
    """
    assert min(A, B, C, terms, m0, scale, root_scale) > 0
    assert theta_mode in ("fixed", "log")
    assert B*m0 >= 2
    directions = (A, B, C)
    H = sum(directions)
    total = eligible = positive = largest = 0
    floor_bound = 1
    for t in range(1, terms+1):
        floors = [X*t//H for X in directions]
        if sum(floors) != t-2:
            continue
        eligible += 1
        stable = floor_stability_bound(directions, t)
        floor_bound = max(floor_bound, stable)
        assert m0 >= stable, (directions, t, m0, stable)
        # Values V_t(m0) of the common lower endpoint; dividing by m0
        # bounds V_t(m)/m above for both shifted rectangles.
        candidates = [(A*m0+1, floors[0]+1),
                      (B*m0, floors[1]+1),
                      (C*m0+1, floors[2]+1)]
        v_num, v_den = candidates[0]
        for numerator, denominator in candidates[1:]:
            if numerator*v_den > v_num*denominator:
                v_num, v_den = numerator, denominator
        root = isqrt((H*m0-1)*root_scale**2//t)
        assert root > 0
        err_num, err_den = 259*root_scale, 125*root
        if err_num*60000 < err_den:
            err_num, err_den = 1, 60000
        if err_num >= err_den:
            continue
        upper_err_num, upper_err_den = 1, 36260
        if theta_mode == "log":
            # BFT theta(x)<x through 10^11 and Dusart above it give
            # the global upper error 1/60000. For an endpoint >=10^11,
            # log(x)>=floor(log2(x))*.69, since log(2)>.69.
            upper_err_num, upper_err_den = 1, 60000
            def log_error(numerator, denominator):
                k = numerator.bit_length()-denominator.bit_length()
                if denominator*(1 << k) > numerator:
                    k -= 1
                assert k >= 36
                return 100, 4761*k*k
            if H*m0-1 >= 10**11*t:
                en, ed = log_error(H*m0-1, t)
                if en*err_den < err_num*ed:
                    err_num, err_den = en, ed
            if v_num >= 10**11*v_den:
                en, ed = log_error(v_num, v_den)
                if en*upper_err_den < upper_err_num*ed:
                    upper_err_num, upper_err_den = en, ed
        numerator = ((err_den-err_num)*(H*m0-1)*upper_err_den*v_den
                     - err_den*(upper_err_den+upper_err_num)*v_num*t)
        denominator = err_den*upper_err_den*m0*t*v_den
        if numerator <= 0:
            continue
        positive += 1
        largest = t
        total += numerator*scale//denominator
    lower = Fraction(total, scale)
    assert lower > 0
    record = {
        'directions': list(directions), 'rectangular_shifts': [list(x) for x in RECTANGLE_SHIFTS],
        'terms': terms, 'm0': m0, 'floor_stability_bound': floor_bound,
        'rounding_denominator': scale, 'root_scale': root_scale,
        'eligible_terms': eligible, 'positive_terms': positive,
        'largest_positive_t': largest, 'ell_lower': str(lower),
        'upper_relative_error': '1/36260',
        'lower_relative_error_floor': '1/60000',
        'source': 'BFT Lemma 5.2; Dusart 2010 Proposition 5.1 and Theorem 5.2; retained BFT theta lower bound through 10^11',
        'conclusion': 'For every integer m>=m0, both coefficient gcds are at least exp(ell_lower*m).',
    }
    if theta_mode == "log":
        record.update({'theta_mode':'log',
                       'upper_relative_error':'min(1/60000, .01/log(x0)^2) when x0>=10^11',
                       'logarithm_lower_bound':'log(2)>69/100; 2^k<=x0 gives log(x0)>69k/100'})
    return record


def normalized_edge(record):
    p, q = record['primes']
    a, b = record['endpoints_scaled']
    return (p, q, a, b) if p < q else (q, p, b, a)


def main():
    directory = Path(__file__).parent
    ramp_path = directory/'erdos_699_index_12_ramp.json'
    ramp = json.loads(ramp_path.read_text())
    source_path = directory/ramp['source_file']
    sources = json.loads(source_path.read_text())
    by_edge = {normalized_edge(row): row for row in sources['records']}
    records = []
    for binding in ramp['source_bindings']:
        source = by_edge[tuple(binding['source_edge'])]
        requested = Fraction(source['gcd_log_rate'])
        for exponent in range(6, 13):
            record = gcd_exponent_lower(*source['directions'], m0=10**exponent)
            if Fraction(record['ell_lower']) > requested:
                break
        else:
            raise AssertionError(('No bound found through 10^12', binding))
        record.update({'edge': binding['edge'], 'source_edge': binding['source_edge'],
                       'requested_log_rate': str(requested),
                       'strict_rate_margin': str(Fraction(record['ell_lower'])-requested)})
        records.append(record)
    result = {
        'scope': 'Numerical coefficient-gcd starting indices for the twenty index-twelve ramp sources.',
        'ramp_file': ramp_path.name,
        'source_file': source_path.name,
        'records': records,
    }
    output = Path(__file__).with_suffix('.json')
    output.write_text(json.dumps(result, indent=2)+'\n')
    print(json.dumps({'output': str(output), 'source_count': len(records),
                      'maximum_m0': max(row['m0'] for row in records),
                      'm0_by_edge': [[row['edge'], row['m0']] for row in records]}, indent=2))


if __name__ == '__main__':
    main()