balanced_root_checks.py

back to table · edit · history · where entries came from · files · download

5595 bytes, as of the version from 2026-10-27 01:12 (current). Recorded here, not run.

"""Recheck retained Coulomb roots without changing their values or generators.

Run: python balanced_root_checks.py T512 table.json

For |eta|<=2, the power-series coefficient bound |a_k|<=5**k proves
F>0 on (0,1/16]. G/F is strictly decreasing, so G(1/16)>0 also
proves G>0 there. On [1/16,infinity), the ODE coefficient q<=65.
Wirtinger's inequality bounds zero separation below by pi/sqrt(65)>1/4.
A certified nonzero-sign scan at spacing 1/4 therefore counts all zeros.
This is the same mathematical certificate as the preserved attached source,
implemented separately with python-flint rather than the Sage source.
Each stored last-place interval must lie inside its indexed scan interval
and have the expected opposite endpoint signs. Free cases are independently
compared with mpmath Bessel zeros. No new roots are proposed.
"""

import argparse
import hashlib
import json
from fractions import Fraction
from pathlib import Path

import mpmath as mp
from flint import acb, arb

from balanced_checks import controls, mp_rational
from balanced_generate import precision, written_interval


def value(kind, order, coupling, argument):
    method = "coulomb_f" if kind == "F" else "coulomb_g"
    result = getattr(acb(arb(str(argument))), method)(order, arb(str(coupling)))
    if not result.is_finite() or not result.imag.contains(0):
        raise ArithmeticError("Coulomb sign evaluation not finite and real")
    return result.real


def sign_at(kind, order, coupling, argument, bits):
    for precision_bits in (bits, 2 * bits, 4 * bits):
        with precision(precision_bits):
            result = value(kind, order, coupling, argument)
            if result > 0:
                return 1
            if result < 0:
                return -1
    raise ArithmeticError("Coulomb endpoint sign unresolved")


def check(tid, document):
    kind = "F" if tid == "T512" else "G"
    records = []
    control_results = controls()
    for order_key, couplings in document["Numbers"].items():
        order = int(order_key)
        for coupling_key, roots in couplings.items():
            coupling = Fraction(coupling_key)
            if abs(coupling) > 2 or order < 0:
                raise ValueError("Selection outside the root-index proof")
            lower = Fraction(1, 16)
            previous = sign_at(kind, order, coupling, lower, 180)
            if previous != 1:
                raise ArithmeticError("Initial-interval positivity failed")
            brackets = []
            while len(brackets) < len(roots):
                upper = lower + Fraction(1, 4)
                following = sign_at(kind, order, coupling, upper, 180)
                if following != previous:
                    brackets.append((lower, upper))
                lower, previous = upper, following
                if upper > 100:
                    raise ArithmeticError("Unexpectedly long root scan")
            for index_key, entry in roots.items():
                index = int(index_key)
                text = entry["number"] if isinstance(entry, dict) else entry
                written_lower, written_upper = written_interval(text)
                outer_lower, outer_upper = brackets[index - 1]
                if not outer_lower < written_lower < written_upper < outer_upper:
                    raise ArithmeticError("Root ordinal does not match scan")
                signs = [sign_at(kind, order, coupling, endpoint, 900)
                         for endpoint in (written_lower, written_upper)]
                if signs != [(-1)**(index - 1), (-1)**index]:
                    raise ArithmeticError("Stored decimal does not enclose its indexed root")
                record = {"ell": order_key, "eta": coupling_key, "n": index_key,
                          "decimal_endpoint_signs": signs,
                          "indexed_scan_bracket": [str(outer_lower), str(outer_upper)]}
                if coupling == 0:
                    with mp.workdps(150):
                        function = mp.besseljzero if kind == "F" else mp.besselyzero
                        independent = function(order + mp.mpf("0.5"), index)
                        if not mp_rational(written_lower) < independent < mp_rational(written_upper):
                            raise ArithmeticError("Free Bessel zero differs")
                    record["independent_free_bessel_zero_150_digits"] = True
                records.append(record)
            print(tid, order_key, coupling_key, "indexed decimal brackets checked", flush=True)
    return {"tid": tid, "all_passed": True, "count": len(records), "controls": control_results,
            "numbers_sha256": hashlib.sha256(json.dumps(document["Numbers"], ensure_ascii=False).encode()).hexdigest(),
            "new_roots": 0, "all_existing_numbers_and_annotations_unchanged": True,
            "independent_free_checks": sum("independent_free_bessel_zero_150_digits" in row for row in records),
            "limitations": "No extension of zero depth or coupling range; fresh endpoint and index checks validate retained roots rather than claim new values.",
            "records": records}


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("tid", choices=("T512", "T513"))
    parser.add_argument("document", type=Path)
    options = parser.parse_args()
    evidence = check(options.tid, json.loads(options.document.read_text()))
    options.document.with_name("balanced-root-checks.json").write_text(json.dumps(evidence, indent=2) + "\n")
    print(options.tid, "passed", evidence["count"], flush=True)