generate.py

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

2761 bytes, as of the version from 2026-10-27 18:01 (current). Recorded here, not run.

"""Uniformization radius of the plane punctured at roots of unity -- numberdb.org/T555.

Run with SageMath (or passagemath with numberdb):
    sage -pip install numberdb
    sage -python generate.py                 # verify all stored entries
    sage -python generate.py --fill          # write entries with NUMBERDB_API_KEY
    sage -python checks.py                  # independent numerical checks

The table holds |F_n'(0)| for the universal cover of C minus the n-th roots
of unity, F_n(0)=0. The default enumeration is every integer 2 <= n <= 30.
The Gamma formula is Calegari--Dimitrov--Tang, Theorem 5.1.4, equation
(5.1.5) in https://web.math.princeton.edu/~yunqingt/UDC.pdf.
All Gamma arguments are formed as exact Sage rationals before coercion to
Arb. Positive roots and Gamma values are evaluated in real ball arithmetic.
The 128-bit guard left at least 455 bits of relative accuracy over the
default range at 461 working bits. Checks.py verifies containment of the entire
computed ball in the interval represented by each 100-digit stored decimal.
See argument-selection.md for the independent role of n and its finite bound.
"""
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 = 128


class UniformizationRadius(numberdb.Generator):
    table = 'T555'
    parameters = ('n',)
    type = 'R'
    digits = 100
    rigour = 'proven'
    files = ('generate.py', 'checks.py', 'argument-selection.md', 'numerical-evidence.json',
             'skill-evidence.json', 'dry-run.log', 'sources.md')

    def enumerate(self, limit=30):
        for n in range(2, int(limit) + 1):
            yield {'n': n}

    def value(self, params, digits):
        n = QQ(params['n'])
        if n.denominator() != 1 or n < 2:
            raise ValueError('n must be an integer at least 2')
        a = QQ(1) / n
        h = a / 2
        R = RealBallField(numberdb.bits(digits, losing=WORKING_GUARD))
        value = (R(16)**R(a) * R(1+h).gamma()**2 * R(1-a).gamma()
                 / (R(1-h).gamma()**2 * R(1+a).gamma()))
        if not value.is_finite() or value <= 0:
            raise ArithmeticError('A finite positive enclosure is required')
        return value


if __name__ == '__main__':
    if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
        numberdb.configure(api_key=sys.stdin.read().strip())
    generator = UniformizationRadius()
    if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
        print(generator.publish(message='Compute 29 cyclic puncture radii with certified 100-digit enclosures'))
    else:
        report = generator.verify(sample=None)
        print(report)
        sys.exit(0 if report.ok else 1)