back to table · edit · history · where entries came from · files · download
7677 bytes, as of the version from 2026-10-16 09:08 (current). Recorded here, not run.
"""Independent checks for Weil--Petersson volumes -- numberdb.org/T459.
Run: sage -python checks.py
Read back the draft too: NUMBERDB_KEY_FROM_STDIN=1 sage -python checks.py < keyfile
No network writes. JSON evidence goes to stdout.
Independent coefficient method: Kaufmann-Manin-Zagier's set-partition
transform (Liu-Xu, arXiv:0708.0565v2, Lemma 2.2), evaluated using a separate
Fraction implementation of the pure-psi DVV recurrence. No arithmetic or
combinatorial helpers are shared with the mixed-kappa generator. The 17
constant terms transcribed from Norman Do, arXiv:1103.4674v1 Appendix B,
are an external tabulation. A third method checks every genus-zero value
using Zograf's scalar volume recurrence (Do Section 3.1).
MPFI at 512 bits independently encloses each exact coefficient times pi^(2m).
Written decimals are interpreted as their full last-place intervals.
"""
import os
import sys
import json
from fractions import Fraction as F
from functools import lru_cache
from math import factorial, comb, prod
from collections import Counter
from decimal import Decimal
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_mpfi import RealIntervalField
from check import exactness, measure, agrees_with, names_its_rings
from generate import coefficient, volume, WeilPeterssonVolumes
def odd(n):
return prod(range(1,n+1,2))
def psi(g, ds):
return _psi(g,tuple(sorted(ds)))
@lru_cache(None)
def _psi(g, ds):
n=len(ds)
if g<0 or 2*g-2+n<=0 or any(d<0 for d in ds) or sum(ds)!=3*g-3+n:
return F(0)
if g==0:
return F(factorial(n-3),prod(factorial(d) for d in ds))
if n==1:
return F(1,24**g*factorial(g))
if ds[0]==0:
rest=ds[1:]
return sum((psi(g,rest[:j]+(e-1,)+rest[j+1:])
for j,e in enumerate(rest) if e), F(0))
if ds[0]==1:
return (2*g-3+n)*psi(g,ds[1:])
d=ds[0]
rest=ds[1:]
result=F(0)
for j,e in enumerate(rest):
result += F(odd(2*d+2*e-1),odd(2*e-1))*psi(g,rest[:j]+(d+e-1,)+rest[j+1:])
for a in range(d-1):
b=d-2-a
result += F(odd(2*a+1)*odd(2*b+1),2)*psi(g-1,(a,b)+rest)
for mask in range(1<<len(rest)):
left=tuple(rest[j] for j in range(len(rest)) if mask>>j&1)
right=tuple(rest[j] for j in range(len(rest)) if not(mask>>j&1))
for h in range(g+1):
result += (F(odd(2*a+1)*odd(2*b+1),2)*psi(h,(a,)+left)
*psi(g-h,(b,)+right))
return result/odd(2*d+1)
def partitions(total, minimum=1):
if total==0:
yield ()
for first in range(minimum,total+1):
for tail in partitions(total-first,first):
yield (first,)+tail
def independent_coefficient(g,n):
m=3*g-3+n
out=F(0)
for parts in partitions(m):
divisor=prod(factorial(p) for p in parts)*prod(factorial(a) for a in Counter(parts).values())
out += F((-1)**(m-len(parts)),divisor)*psi(g,(0,)*n+tuple(p+1 for p in parts))
return out*2**m
@lru_cache(None)
def zograf(n):
if n==3:
return F(1)
return sum((F(k*(n-k-2)*comb(n-4,k-1)*comb(n,k+1),2*(n-1))
*zograf(k+2)*zograf(n-k) for k in range(1,n-2)),F(0))
# Coefficients of pi^(6g-6+2n), Do Appendix B, pp. 33-34.
PUBLISHED={
(0,3):F(1), (0,4):F(2), (0,5):F(10), (0,6):F(244,3), (0,7):F(2758,3),
(1,1):F(1,12), (1,2):F(1,4), (1,3):F(14,9), (1,4):F(529,36), (1,5):F(16751,90),
(2,0):F(43,2160), (2,1):F(29,192), (2,2):F(787,480), (2,3):F(1498069,64800),
(3,0):F(176557,1209600), (3,1):F(9292841,4082400), (3,2):F(2800144027,65318400),
}
def as_qq(x):
return QQ(x.numerator)/QQ(x.denominator)
def written_interval(text):
dec=Decimal(text)
q=as_qq(F(dec))
if '.' not in text and 'e' not in text.lower():
return q,q
exponent=dec.as_tuple().exponent
ulp=QQ(10)**exponent
return q-ulp,q+ulp
def read_numbers(doc):
return {(int(g),int(n)):str(v['number'] if isinstance(v,dict) else v)
for g,rows in doc['Numbers'].items() for n,v in rows.items()}
def run():
# Controls run first, including zero, a non-unit value and a positive-genus case.
assert psi(0,(0,0,0))==1
assert psi(0,(1,1,0,0,0))==2
assert psi(1,(1,))==F(1,24)
assert psi(2,(2,3))==F(29,5760)
assert psi(1,(0,))==0
assert independent_coefficient(0,4)==2
assert zograf(4)==1 and zograf(5)==5
R=RealIntervalField(512)
assert (R(1)/R(3)).lower().exact_rational() <= QQ(1)/3 <= (R(1)/R(3)).upper().exact_rational()
assert (R(1)/R(3)).absolute_diameter().exact_rational()<QQ(10)**(-150)
expected={(g,n) for g in range(4) for n in range(9) if 2*g-2+n>0}
gen=WeilPeterssonVolumes()
keys=[(p['g'],p['n']) for p in gen.enumerate()]
assert set(keys)==expected and len(keys)==len(expected)
values={k:volume(*k) for k in keys}
assert not names_its_rings(os.path.join(os.path.dirname(__file__),'generate.py'))
assert not exactness(values)
coefficients={k:coefficient(*k) for k in keys}
comparison=agrees_with(coefficients,lambda k:as_qq(independent_coefficient(*k)))
assert not comparison, comparison
assert not agrees_with({k:coefficients[k] for k in PUBLISHED},lambda k:as_qq(PUBLISHED[k]))
for g,n in keys:
if g==0:
assert coefficients[g,n]==as_qq(zograf(n)*F(2**(n-3),factorial(n-3)))
widths=[(values[k].upper().exact_rational()-values[k].lower().exact_rational())/values[k].lower().exact_rational()
for k in keys if k!=(0,3)]
min_bits=min(int(x.denominator().nbits()-x.numerator().nbits()-1) for x in widths)
assert min_bits>=340
independent={}
for g,n in keys:
v=R(as_qq(independent_coefficient(g,n)))*R.pi()**(6*g-6+2*n)
assert v.lower().exact_rational()>0 and v.absolute_diameter().exact_rational()/v.lower().exact_rational()<QQ(10)**(-145)
if (g,n)!=(0,3):
ball=values[g,n]
# This is interval overlap, with narrow widths tested separately.
assert v.lower().exact_rational()<=ball.upper().exact_rational() and ball.lower().exact_rational()<=v.upper().exact_rational()
else:
assert values[g,n]==1 and v==1
independent[g,n]=v
result={'table':'T459','entries':len(keys),'exact_coefficient_comparisons':len(keys),
'published_constant_terms':len(PUBLISHED),'zograf_genus_zero_checks':sum(g==0 for g,n in keys),
'independent_mpfi_checks':len(keys),'minimum_arb_relative_accuracy_bits':min_bits,
'mpfi_relative_width_bound':'1e-145','measurement':measure(values),
'rational_coefficients':{','.join(map(str,k)):str(v) for k,v in coefficients.items()},
'controls':'passed: non-unit genus-zero, genus-one, genus-two, dimension-zero, rational interval and Zograf base cases',
'stored_checks':0}
if os.environ.get('NUMBERDB_KEY_FROM_STDIN')=='1':
numberdb.configure(api_key=sys.stdin.read().strip())
stored=read_numbers(numberdb.table('T459'))
assert set(stored)==expected
for k,s in stored.items():
lo,hi=written_interval(s)
v=independent[k]
assert lo<=v.lower().exact_rational() and v.upper().exact_rational()<=hi,(k,s)
assert stored[0,3]=='1'
result['stored_checks']=len(stored)
report=gen.verify(sample=None)
assert report.ok,str(report)
result['verify']=str(report)
result['stored_numbers']={','.join(map(str,k)):v for k,v in stored.items()}
return result
if __name__=='__main__':
print(json.dumps(run(),indent=2,default=str))