back to table · edit · history · where entries came from · files · download
4367 bytes, as of the version from 2026-10-26 04:51 (current). Recorded here, not run.
"""Check Dedekind eta branch conventions and stored values -- numberdb.org/T506.
Run with SageMath; it reads the live table unless T506-document.json is beside
this file. A private draft needs NUMBERDB_API_KEY, or a key piped to stdin
with NUMBERDB_KEY_FROM_STDIN=1:
sage -python check_eta_repair.py
In the campaign use agents/sage.sh check_eta_repair.py T506-document.json.
This reads no key and writes no table. Results are JSON on stdout.
For tau in the upper half-plane, -i*tau has positive real part. Its principal
square root is analytic there and positive for tau positive imaginary.
DLMF 23.18.5-7 with (a,b,c,d)=(0,-1,1,0) has epsilon=1 (empty Dedekind sum),
so this is the root in eta(-1/tau)=sqrt(-i*tau)*eta(tau).
The independent eta product at tau=i*sqrt(r) is enclosed by truncating at
M=256: 1-S <= product(n>M)(1-Q**n) <= 1, S=Q**(M+1)/(1-Q).
S bounds the sum of omitted factors; the lower bound follows by induction.
"""
import json
import os
import sys
from pathlib import Path
from decimal import Decimal
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.complex_arb import ComplexBallField
from sage.rings.real_arb import RealBallField
from sage.env import SAGE_VERSION
C=ComplexBallField(512)
R=RealBallField(512)
i=C.gen(0)
eps=R(10)**-140
def narrow(z):
assert z.real().is_finite() and z.imag().is_finite(), str(z)
if hasattr(z,'imag'):
assert z.real().rad_as_ball()<eps and z.imag().rad_as_ball()<eps, str(z)
else:
assert z.rad_as_ball()<eps, str(z)
return z
def agrees(a,b):
narrow(a); narrow(b)
assert a.overlaps(b), (str(a),str(b))
def decimal_rational(s):
d=Decimal(s)
t=d.as_tuple()
coefficient=int(''.join(map(str,t.digits))) * (-1 if t.sign else 1)
return QQ(coefficient)*QQ(10)**int(t.exponent),QQ(10)**int(t.exponent)
# Known-value and sign controls precede the comparisons.
eta_i=narrow(i.modular_eta())
gamma=narrow(C(QQ(1)/4).gamma()/(2*C.pi()**(QQ(3)/4)))
agrees(eta_i,gamma)
assert not eta_i.overlaps(-gamma)
assert (-i*(1+i)) == C(1,-1)
branch_results=[]
for tau in [C(1,1),C(-1,1),C(QQ(1)/2)+i*C(3).sqrt()/2]:
radicand=-i*tau
root=narrow(radicand.sqrt())
assert root.real()>0 and not root.imag().contains_zero()
lhs=narrow((-1/tau).modular_eta())
rhs=narrow(root*tau.modular_eta())
agrees(lhs,rhs)
assert not lhs.overlaps(-rhs)
branch_results.append({'tau':str(tau),'principal_root':str(root),'identity':True,'opposite_root_rejected':True})
export = Path(__file__).with_name('T506-document.json')
if export.exists():
doc = json.loads(export.read_text())
else:
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
numberdb.configure(api_key=sys.stdin.read().strip())
doc = numberdb.table('T506')
rows=[]
for key,entry in doc['Numbers'].items():
r=int(key)
text=entry['number'] if isinstance(entry,dict) else entry
center,ulp=decimal_rational(text)
y=R(r).sqrt()
value=narrow((i*C(r).sqrt()).modular_eta())
assert value.imag().contains_zero() and value.real()>0
assert value.real().lower().exact_rational()>center-ulp and value.real().upper().exact_rational()<center+ulp
Q=(-2*R.pi()*y).exp()
partial=(-R.pi()*y/12).exp()
for n in range(1,257): partial*=1-Q**n
tail=Q**257/(1-Q)
# The interval [1-S,1] encloses the omitted product.
enclosure=(1-tail).union(R(1))
product=narrow(partial*enclosure)
agrees(product,value.real())
assert product.lower().exact_rational()>center-ulp and product.upper().exact_rational()<center+ulp
# Wrong stored decimals must be rejected even though the real value is small.
assert not (product.lower().exact_rational()<=center+11*ulp and product.upper().exact_rational()>=center+9*ulp)
root=narrow((-i*(i*C(r).sqrt())).sqrt())
assert root.real()>0 and root.imag().contains_zero()
agrees(root,C(r)**(QQ(1)/4))
agrees((i/C(r).sqrt()).modular_eta(),root*value)
rows.append({'r':r,'stored_encloses_arb_and_product':True,'positive_root':True,'reciprocity':True,'ten_ulp_control_rejected':True,'eta_accuracy_bits':int(value.real().accuracy())})
print(json.dumps({'sage':SAGE_VERSION,'numberdb':numberdb.__version__,'bits':512,'known_value_control':True,'wrong_sign_control':True,'branch_checks':branch_results,'rows':rows,'all_passed':True},indent=2))