generate.py

back to table · edit · history · where entries came from · files · download

2844 bytes, as of the version from 2026-11-01 08:46 (current). Recorded here, not run.

"""Alternating sum of the Báez-Duarte coefficients -- numberdb.org/T646.

Run with SageMath and the numberdb package:
    sage -pip install numberdb
    sage -python generate.py                 # verify the existing draft/table
    sage -python checks.py                   # local independent checks

An authorized editor may fill the existing draft with:
    NUMBERDB_FILL_DRAFT=1 sage -python generate.py
using NUMBERDB_API_KEY. This writes entries; it never offers or publishes the
website draft. NUMBERDB_KEY_FROM_STDIN=1 instead reads the key from stdin.

S = sum_{m>=1} 1/(2^m*zeta(2*m)), with the ordinary Riemann zeta function.
After m=N, 0 < remainder < 2^(-N), since 1 < zeta(2*m).
The computation uses Arb real balls and explicitly includes this tail.
At digits=100, N=400, working precision=413 bits; checks.py records actual
retained accuracy and verifies containment in the written last-place interval.
See argument-selection.md and numerical-evidence.md for the scope and checks.
"""
import os
import sys

import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField

WORKING_GUARD_BITS = 80


class AlternatingSum(numberdb.Generator):
    table = 'T646'
    parameters = ()
    type = 'R'
    digits = 100
    rigour = 'proven'
    files = ('generate.py', 'checks.py', 'argument-selection.md',
             'numerical-evidence.md', 'checks-evidence.json', 'skill-evidence.json')

    def enumerate(self):
        yield {}

    def value(self, params, digits):
        if params:
            raise ValueError('This constant has no free parameters')
        digits = int(digits)
        if digits < 1:
            raise ValueError('digits must be positive')
        field = RealBallField(numberdb.bits(digits, losing=WORKING_GUARD_BITS))
        terms = 4 * digits
        total = sum((field(QQ(1) / 2**m) / field(2*m).zeta()
                     for m in range(1, terms + 1)), field(0))
        tail = QQ(1) / 2**terms
        result = total + field(0, tail)
        assert result.is_finite()
        assert result.accuracy() >= numberdb.bits(digits, losing=0)
        return result


if __name__ == '__main__':
    if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
        key = sys.stdin.read().strip()
        if key.startswith('NUMBERDB_'):
            key = key.split('=', 1)[1].strip().strip('\"\'')
        numberdb.configure(api_key=key)
    generator = AlternatingSum()
    if os.environ.get('NUMBERDB_FILL_DRAFT') == '1' or os.environ.get('NUMBERDB_PUBLISH') == '1':
        outcome = generator.publish(message='Fill the alternating-sum constant with a certified enclosure')
        print(outcome)
        print('FILL_RUN', outcome.run)
    else:
        report = generator.verify(sample=None)
        print(report)
        sys.exit(0 if report.ok else 1)