back to table · edit · history · where entries came from · files · download
4691 bytes, as of the version from 2026-10-27 01:12 (current). Recorded here, not run.
"""Check T513's standalone Programs example with SageMath.
Download repair_program.py and generate.py beside this file, then run:
sage -python repair_checks.py
For a private draft, configure NUMBERDB_API_KEY, or pipe its key on stdin
with NUMBERDB_KEY_FROM_STDIN=1. A local T513-document.json is used if present.
No table or attachment is changed. JSON results are printed to stdout.
"""
import contextlib
import io
import json
import os
import pathlib
import sys
import platform
import importlib.metadata
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
import mpmath as mp
from generate import scan, sign_at, coulomb_g, CoulombGZeros
base = pathlib.Path(__file__).resolve().parent
snapshot = base / 'T513-document.json'
if snapshot.exists():
document = json.loads(snapshot.read_text())
else:
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
numberdb.configure(api_key=sys.stdin.read().strip())
document = numberdb.table('T513')
text = document['Numbers']['0']['1']['1']['number']
source = (base / 'repair_program.py').read_text()
def run_example(dps):
code = source.replace('mp.mp.dps = 150', 'mp.mp.dps = %d' % dps)
namespace = {}
output = io.StringIO()
with contextlib.redirect_stdout(output):
exec(compile(code, 'repair_program.py', 'exec'), namespace)
return namespace, output.getvalue().strip()
first, printed150 = run_example(150)
root150 = first['root']
assert printed150 == text, (printed150, text)
controls = []
# Controls for the exact code used in Programs, away from cancellation.
for rho in (3, 4):
actual = first['G'](rho)
expected = mp.coulombg(0, 1, rho)
assert mp.isfinite(actual) and mp.isfinite(expected)
assert abs(actual - expected) < mp.mpf('1e-140')
controls.append({'rho': rho, 'absolute_difference': mp.nstr(abs(actual-expected), 8)})
# Change the same namespace to the free order-zero case: G=cos(rho).
first['eta'] = 0
first['sigma'] = mp.mpf(0)
first['phase'] = mp.mpf(1)
for rho in (1, 2, 3, 4):
v = first['G'](rho)
assert mp.isfinite(v)
assert abs(v-mp.cos(rho)) < mp.mpf('1e-140')
assert abs(mp.findroot(first['G'], (1, 2))-mp.pi/2) < mp.mpf('1e-140')
second, printed200 = run_example(200)
root200 = second['root']
assert printed200 == text
assert abs(root150-root200) < mp.mpf('1e-145')
# Parse the decimal exactly, including its last-place interval.
integer, fraction = text.split('.')
center = QQ(int(integer + fraction)) / QQ(10**len(fraction))
ulp = QQ(1) / QQ(10**len(fraction))
outer = scan(0, '1', 1)[0]
assert QQ(3) < outer[0] < center-ulp < center+ulp < outer[1] < QQ(4)
assert sign_at(0, '1', QQ(3), 681) == 1
assert sign_at(0, '1', QQ(4), 681) == -1
# The attached generator's small-radius and zero-separation argument applies:
# |eta|<=2, ell>=0, G(1/16)>0, and pi/sqrt(65)>1/4.
R = RealBallField(681)
assert R.pi()/R(65).sqrt() > R(QQ(1)/4)
assert sign_at(0, '1', QQ(1)/16, 681) == 1
endpoints = [center-ulp, center+ulp]
balls = [coulomb_g(0, '1', endpoint, 681) for endpoint in endpoints]
assert balls[0] > 0 and balls[1] < 0
for ball in balls:
assert ball.is_finite() and R(ball.rad()) < R(QQ(1)/10**180)
# Execute the original example too; its proof-bearing interval must fit.
original = CoulombGZeros().value({'ell':'0','eta':'1','n':'1'}, 100)['number']
assert original.lower().exact_rational() > center-ulp
assert original.upper().exact_rational() < center+ulp
scaled_error = abs((root200-mp.mpf(text)) / mp.mpf(str(ulp)))
assert scaled_error < 1
results = {
'table': 'T513',
'entry': {'ell':'0','eta':'1','n':'1'},
'printed_100_digits': printed150,
'matches_stored_at_150_and_200_dps': True,
'root_difference_150_vs_200_dps': mp.nstr(abs(root150-root200), 12),
'error_in_stored_last_place_units': mp.nstr(scaled_error, 12),
'direct_coulombg_controls_at_150_dps': controls,
'free_cosine_controls': 4,
'free_first_root_pi_over_2': True,
'certified_first_scan_bracket': [str(x) for x in outer],
'signs_at_3_and_4': [1, -1],
'stored_decimal_endpoint_signs': [1, -1],
'endpoint_ball_radii': [str(x.rad()) for x in balls],
'original_generator_interval_inside_stored_decimal_interval': True,
'scope': 'The Programs example and its first-root bracket; no entries changed or full-table recomputation claimed.',
'versions': {'python':platform.python_version(), 'mpmath':mp.__version__,
'numberdb':importlib.metadata.version('numberdb')},
}
try:
from sage.env import SAGE_VERSION
results['versions']['sage'] = SAGE_VERSION
except ImportError:
pass
print(json.dumps(results, indent=2))