back to table · edit · history · where entries came from · files · download
3773 bytes, as of the version from 2026-10-24 20:26 (current). Recorded here, not run.
"""Multiple zeta values of length 4 -- numberdb.org/T465.
Run with SageMath (or passagemath with its modular multiple-zeta module):
sage -pip install numberdb
sage -python generate.py # verify every stored entry
sage -python checks.py # independent checks, no API writes
sage -python generate.py --fill # fill with NUMBERDB_API_KEY set
The four parameters use descending summation indices. Sage's multiple-zeta
indices are reversed. All admissible length-four indices of weight <= 12 are
included. The two PARI caches are explicitly recomputed at 150 and 200 decimal
working digits (plus 16 guard bits), rather than rounding one shared cache to
two precisions. The measured agreement and independent evidence are attached
in checks.py and build-evidence.json. Values are written to 100 significant
digits under the heuristic (agreement-checked) rigour level.
--fill writes entries to the existing table; it does not publish the draft.
"""
from functools import lru_cache
import os
import sys
import numberdb.sage as numberdb
from sage.modular.multiple_zeta import MultizetaValues
MAX_WEIGHT = 12
WORKING_DIGITS = (150, 200)
GUARD_BITS = 16
PARAMETERS = ('s1', 's2', 's3', 's4')
def indices(max_weight=MAX_WEIGHT):
"""Natural increasing parameter order, with no holes at any weight."""
for a in range(2, max_weight - 2):
for b in range(1, max_weight - a - 1):
for c in range(1, max_weight - a - b):
for d in range(1, max_weight - a - b - c + 1):
yield (a, b, c, d)
@lru_cache(maxsize=2)
def working_values(working):
"""A fresh PARI zetamultall computation at this working precision."""
precision = numberdb.bits(working, losing=GUARD_BITS)
cache = MultizetaValues()
cache.reset(max_weight=MAX_WEIGHT, prec=precision)
return {index: cache(tuple(reversed(index)), prec=precision)
for index in indices()}
class LengthFourMZV(numberdb.Generator):
table = 'T465'
parameters = PARAMETERS
type = 'R'
digits = 100
rigour = 'heuristic (agreement-checked)'
files = ('generate.py', 'checks.py', 'check.py', 'build-evidence.json')
def enumerate(self):
for index in indices():
yield dict(zip(self.parameters, index))
def value(self, params, digits):
if digits > 100:
raise ValueError('This generator is validated for 100 stored digits.')
index = tuple(int(params[name]) for name in self.parameters)
value = numberdb.agreeing(
lambda working: str(working_values(working)[index]),
at=WORKING_DIGITS)
# Equalities are theorems, not numerical duplicate guesses.
annotations = {}
if index == (2, 1, 1, 1):
annotations = {
'comment': r'Duality identifies this value with HREF{Values_of_the_Riemann_zeta_function_at_rational_numbers#5}[$\zeta(5)$].',
'equals': 'HREF{Values_of_the_Riemann_zeta_function_at_rational_numbers#5}'}
elif index == (2, 2, 2, 2):
annotations = {'comment': r'$\zeta(2,2,2,2)=\pi^8/9!$.'}
return {'number': value, **annotations}
if __name__ == '__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
key = sys.stdin.read().strip()
if '=' in key and key.split('=', 1)[0].isupper():
key = key.split('=', 1)[1].strip().strip('\'"')
numberdb.configure(api_key=key)
generator = LengthFourMZV()
if '--fill' in sys.argv:
print(generator.publish(message='Fill 330 independently checked length-four multiple zeta values'))
else:
report = generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)