back to table · edit · history · where entries came from · files · download
8009 bytes, as of the version from 2026-10-16 10:44 (current). Recorded here, not run.
"""Independent arithmetic checks for lambda_g Hodge integrals, numberdb.org/T462.
sage -python checks.py # local generated values
sage -python checks.py --stored # values read from T462; needs its key
The checker uses Python fractions and a Bernoulli recurrence, independently
of the generator's sine-series inversion and binomial products. It also uses
three published Macaulay2 HodgeIntegrals examples, genus-one boundary
reduction to genus-zero string recursion, the corpus Bernoulli numbers,
and a 512-bit Arb calculation from even zeta values. Files bernoulli.json
and T458.json are API snapshots dated 2026-10-16; the latter is a companion
draft and is used only as an additional check, not as mathematical authority.
"""
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
from fractions import Fraction as F
from functools import lru_cache
from itertools import combinations_with_replacement
from math import factorial
from pathlib import Path
import json
import os
import sys
from check import exactness, measure, agrees_with, names_its_rings
ROOT = Path(__file__).resolve().parent
def bernoullis(limit):
# B_0=1 and sum_{k=0}^{m} binomial(m+1,k) B_k = 0 for m>0.
from math import comb
bs = [F(1)]
for m in range(1, limit+1):
bs.append(-sum(F(comb(m+1,k))*bs[k] for k in range(m))/F(m+1))
return bs
def independent(key):
g, n, ds = key
bs = bernoullis(2*g)
if g == 0:
base = F(1)
else:
base = (1-F(1, 2**(2*g-1))) * abs(bs[2*g]) / factorial(2*g)
denominator = 1
for d in ds:
denominator *= factorial(d)
return base * F(factorial(sum(ds)), denominator)
@lru_cache(None)
def genus_zero(ds):
# Pure psi intersections from the string equation alone; no multinomial.
if len(ds) < 3 or min(ds) < 0 or sum(ds) != len(ds)-3:
return F(0)
if ds == (0,0,0):
return F(1)
rest = list(ds)
rest.remove(0)
answer = F(0)
for j, d in enumerate(rest):
if d:
lowered = rest.copy()
lowered[j] -= 1
answer += genus_zero(tuple(sorted(lowered)))
return answer
def scalar(value):
return value['number'] if isinstance(value,dict) else value
def flatten(doc):
return {(int(g),int(n),tuple(map(int,d.split(',')))): QQ(scalar(value))
for g, ns in doc['Numbers'].items() for n, profiles in ns.items()
for d, value in profiles.items()}
def validate(vals):
# Controls are evaluated before comparisons with the proposed data.
bs = bernoullis(10)
assert bs[:5] == [F(1),F(-1,2),F(1,6),F(0),F(-1,30)]
assert genus_zero((0,0,0)) == 1
assert genus_zero((0,0,0,1,1)) == 2
assert genus_zero((0,0,1)) == 0
assert independent((1,1,(0,))) == F(1,24)
assert independent((2,2,(1,2))) == F(7,1920)
assert not agrees_with({(1,1,(0,)):F(1,24)},independent)
assert agrees_with({(1,1,(0,)):F(1,12)},independent)
assert exactness({'float-control':0.5})
expected = set()
for g in range(1,6):
for n in range(1,6):
total = 2*g-3+n
for ds in combinations_with_replacement(range(total+1),n):
if sum(ds) == total:
expected.add((g,n,ds))
assert set(vals) == expected
assert not exactness(vals)
measurement = measure(vals)
vals = {k:F(int(v.numerator()), int(v.denominator())) for k,v in vals.items()}
assert not names_its_rings(str(ROOT/'generate.py'))
disagreements = agrees_with(vals, independent)
assert not disagreements, disagreements[:5]
for (g,n,ds), value in vals.items():
assert len(ds) == n and ds == tuple(sorted(ds)) and min(ds) >= 0
assert 2*g-2+n > 0 and sum(ds)+g == 3*g-3+n
assert value > 0
# Published outputs from the independent Macaulay2 HodgeIntegrals package.
examples = {(1,1,(0,)):F(1,24), (2,2,(1,2)):F(7,1920),
(3,3,(1,2,3)):F(31,16128)}
for key, value in examples.items():
assert vals[key] == value
# b_g values tested against an external Bernoulli table, and via zeta.
corpus = json.loads((ROOT/'bernoulli.json').read_text())['Numbers']
R = RealBallField(512)
def zeta_base(g):
return 2*(1-R(2)**(1-2*g))*R(2*g).zeta()/(2*R.pi())**(2*g)
control = zeta_base(1)
assert control.is_finite() and R(control.rad()) < R(10)**(-140)
assert control.overlaps(R(QQ(1)/QQ(24)))
assert not control.overlaps(R(QQ(1)/QQ(12)))
zeta_radii = []
b = [QQ(1)]
for g in range(1,6):
B = F(str(scalar(corpus[str(2*g)])))
assert B == bs[2*g]
base = vals[(g,1,(2*g-2,))]
assert base == (1-F(1,2**(2*g-1)))*abs(B)/factorial(2*g)
ball = zeta_base(g)
assert ball.is_finite() and R(ball.rad()) < R(10)**(-140)
assert ball.overlaps(R(QQ(base.numerator)/QQ(base.denominator)))
zeta_radii.append(str(ball.rad()))
b.append(QQ(base.numerator)/QQ(base.denominator))
for g in range(1,6):
convolution = sum(QQ((-1)**k)/QQ(2**(2*k)*factorial(2*k+1))*b[g-k]
for k in range(g+1))
assert convolution == 0
# Genus one: lambda_1=delta_irr/12, with gluing degree two.
# This reduces to 1/24 of a genus-zero pure-psi intersection with two
# extra zero exponents. The genus-zero recursion above is independent.
genus_one = 0
companion = 0
psi = json.loads((ROOT/'T458.json').read_text())['Numbers']['0']
for (g,n,ds), value in vals.items():
if g != 1:
continue
zero_profile = tuple(sorted(ds+(0,0)))
assert value == genus_zero(zero_profile)/24
genus_one += 1
key = ','.join(map(str,zero_profile))
if str(n+2) in psi and key in psi[str(n+2)]:
assert value == F(str(scalar(psi[str(n+2)][key])))/24
companion += 1
string_count = dilaton_count = 0
for (g,n,ds), value in vals.items():
if n <= 1:
continue
if ds[0] == 0:
rest = list(ds[1:])
rhs = F(0)
for j,d in enumerate(rest):
if d:
lowered = rest.copy()
lowered[j] -= 1
rhs += vals[(g,n-1,tuple(sorted(lowered)))]
assert value == rhs
string_count += 1
if 1 in ds:
rest = list(ds)
rest.remove(1)
assert value == (2*g-3+n)*vals[(g,n-1,tuple(rest))]
dilaton_count += 1
return {'entries':len(vals), 'exactness':'pass', 'range':'all g=1..5, n=1..5, sorted top-degree profiles',
'independent_bernoulli_formula_matches':len(vals),
'published_macaulay2_examples':len(examples),
'corpus_bernoulli_matches':5, 'arb_zeta_matches':5,
'arb_zeta_working_bits':512, 'arb_zeta_absolute_radii':zeta_radii,
'sine_series_coefficients':5, 'genus_one_boundary_checks':genus_one,
'T458_genus_zero_matches':companion,
'string_equations':string_count, 'dilaton_equations':dilaton_count,
'controls':'known rational, nonzero genus-zero, wrong-degree, wrong normalization and float controls passed',
'measurement':measurement}
if __name__ == '__main__':
stored = '--stored' in sys.argv or os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1'
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
os.environ['NUMBERDB_API_KEY'] = sys.stdin.read().strip()
if stored:
vals = flatten(numberdb.table('T462'))
else:
from generate import LambdaGHodge
gen = LambdaGHodge()
vals = {(int(p['g']),int(p['n']),tuple(map(int,p['d'].split(',')))):
scalar(gen.value(p,100)) for p in gen.enumerate()}
result = validate(vals)
result['source'] = 'database T462' if stored else 'local generator'
print(json.dumps(result,indent=2,default=str))