back to table · edit · history · where entries came from · files · download
4517 bytes, as of the version from 2026-11-10 01:43 (current). Recorded here, not run.
"""Elliptic trilogarithm L31 at CM torsion points -- numberdb.org/T702.
Install numberdb in an existing SageMath environment:
sage -pip install numberdb
Run with SageMath or passagemath and numberdb installed:
sage -python generate.py # verify every stored entry
sage -python generate.py --fill # send entries to this draft
The latter requires NUMBERDB_API_KEY. It cannot publish or offer a draft.
Samart, arXiv:1309.7730v2, section 1 fixes the single-valued normalization.
The finite selection is explained in argument-selection.md. For 0<t<1,
|L3(z)| <= t/(1-t)*(1+|log(t)|+log(t)^2/3), t=|z|.
Each of the two omitted q-tails is bounded by summing this quadratic times
a geometric series. Its bound is added to the Arb result, including all
rounding and argument uncertainty. The boundary x=1 is zeta(3); for any
unit-modulus x the zero logarithmic factors are omitted exactly.
128 extra working bits and a tail target 24 decimal places beyond the
requested digits give substantially more than 100 significant digits across
the default selection; checks.py records the measured minimum accuracy.
"""
import os
import sys
from math import gcd
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
from sage.rings.complex_arb import ComplexBallField
DISCRIMINANTS = (-3, -4, -7, -8, -11, -12, -16, -19, -27, -28, -43, -67, -163)
WORKING_GUARD = 128
TAIL_GUARD = 24
def tail_bound(R, A, v):
"""Bound sum_{k>=0} |L3(z_k)|, where |z_k|=R^(v+k)."""
t = (-A*v).exp()
S0 = 1/(1-R)
S1 = R/(1-R)**2
S2 = R*(1+R)/(1-R)**3
return t/(1-t)*((1+A*v+A*A*v*v/3)*S0
+(A+2*A*A*v/3)*S1+A*A*S2/3)
def compute(params, digits=100, diagnostics=False):
D,N,r,s = (int(params[k]) for k in ('Delta','N','r','s'))
if D >= 0 or D % 4 not in (0,1) or N < 1:
raise ValueError('Expected a negative quadratic-order discriminant and N>=1')
# Accept redundant coordinates for checking periodicity, but default
# enumeration is reduced and of exact order N.
r %= N; s %= N
B=RealBallField(numberdb.bits(digits, losing=WORKING_GUARD))
C=ComplexBallField(B.precision())
b=int(D%4 != 0)
A=B.pi()*B(-D).sqrt()
R=(-A).exp()
q=C((-1 if b else 1)*R)
a=QQ(r)/N
x=C(-A*a, B.pi()*(QQ(2*s-b*r)/N)).exp()
def L(z, v):
logmod=-A*v
if v==0:
if s==0: return B(3).zeta()
return z.polylog(3).real()
return (z.polylog(3)-logmod*z.polylog(2)
-logmod**2*(1-z).log()/3).real()
total=L(x,a)
qpower=C(1)
target=B(10)**(-digits-TAIL_GUARD)
for K in range(0,10000):
bound=tail_bound(R,A,K+1+a)+tail_bound(R,A,K+1-a)
if total.is_finite() and not total.contains_zero() and bound < abs(total)*target:
result=total.add_error(bound)
if not result.is_finite() or result.accuracy() < numberdb.bits(digits):
raise ArithmeticError('Insufficient relative enclosure accuracy')
if diagnostics:
return result, {'terms_each_side':K,'relative_accuracy_bits':int(result.accuracy()),'tail_bound':str(bound)}
return result
qpower*=q
n=K+1
total+=L(qpower*x,n+a)+L(qpower/x,n-a)
raise ArithmeticError('Tail target not reached; investigate an exact zero or cancellation')
class Table(numberdb.Generator):
table='T702'
parameters=('Delta','N','r','s')
type='R'
digits=100
rigour='proven'
def enumerate(self, max_order=6, discriminants=DISCRIMINANTS):
for D in discriminants:
for N in range(1,max_order+1):
for r in range(N):
for s in range(N):
if gcd(gcd(N,r),s)!=1:
continue
if (r,s)>((-r)%N,(-s)%N):
continue
yield dict(Delta=D,N=N,r=r,s=s)
def value(self, params, digits):
return compute(params,digits)
if __name__=='__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN')=='1':
numberdb.configure(api_key=sys.stdin.read().strip())
g=Table()
if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH')=='1':
print(g.publish(message='Fill L31 CM torsion values with certified tails and independent checks'))
else:
report=g.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)