generate.py

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

5442 bytes, as of the version from 2026-11-02 14:05. Recorded here, not run.

"""Normalized holomorphic periods of hypergeometric Calabi–Yau families -- numberdb.org/T679.

Run with SageMath (mpmath 1.4.1 was used for this build):
    sage -pip install numberdb mpmath
    sage -python generate.py                 # verify every stored entry
    sage -python generate.py --fill          # fill an authorized draft

The 14 cyclotomic templates are evaluated at 1, 1/2, -1, 2, in that order.
The upper bank at 2 is the conjugate of mpmath's real-cut default; checks.py
independently follows a path in the upper half-plane to verify this sign.
Every value is evaluated at 140 and 190 decimal working digits for a
100-digit submission. The intervals record agreement, not certification.
The build also compared all entries with independent Taylor continuation or
an asymptotic tail sum, and the all-half conifold with a modular L-value.
See argument-selection.md and numerical-evidence.md for scope and evidence.
"""
import os
import sys
from functools import lru_cache
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.complex_interval_field import ComplexIntervalField
import mpmath as mp

TEMPLATES = ('2.2.2.2','2.2.3','2.2.4','2.2.6','3.3','3.4','3.6',
             '4.4','4.6','6.6','5','8','10','12')
FIBRES = ('1','1/2','-1','2')
LOCAL_LINKS = {'2.2.2.2': {'1/2': ('3', '5'), '-1': ('3', '5'), '2': ('3', '5')}, '2.2.3': {'1/2': ('5', '5'), '-1': ('5', '5'), '2': ('5', '7')}, '2.2.4': {'1/2': ('3', '3'), '-1': ('3', '3'), '2': ('3', '3')}, '2.2.6': {'1/2': ('5', '5'), '-1': ('5', '5'), '2': ('5', '5')}, '3.3': {'1/2': ('5', '5'), '-1': ('5', '5'), '2': ('5', '5')}, '3.4': {'1/2': ('5', '5'), '-1': ('5', '5'), '2': ('5', '5')}, '3.6': {'1/2': ('5', '5'), '-1': ('5', '5'), '2': ('5', '5')}, '4.4': {'1/2': ('3', '3'), '-1': ('3', '3'), '2': ('3', '3')}, '4.6': {'1/2': ('5', '5'), '-1': ('5', '5'), '2': ('5', '5')}, '6.6': {'1/2': ('5', '5'), '-1': ('5', '5'), '2': ('5', '5')}, '5': {'1/2': ('3', '3'), '-1': ('3', '3'), '2': ('3', '3')}, '8': {'1/2': ('3', '3'), '-1': ('3', '3'), '2': ('3', '3')}, '10': {'1/2': ('3', '3'), '-1': ('3', '3'), '2': ('3', '3')}, '12': {'1/2': ('5', '5'), '-1': ('5', '5'), '2': ('5', '5')}}



def upper_parameters(template):
    from math import gcd
    if template not in TEMPLATES:
        raise ValueError('Unclassified template')
    return [QQ(a)/d for d in map(int, template.split('.'))
            for a in range(1,d) if gcd(a,d)==1]


@lru_cache(maxsize=256)
def components(template,z,working):
    with mp.workdps(working):
        alpha=[mp.mpf(int(a.numerator()))/int(a.denominator())
               for a in upper_parameters(template)]
        x=QQ(z)
        value=mp.hyper(alpha,[1,1,1],mp.mpf(int(x.numerator()))/int(x.denominator()))
        if x>1:
            value=mp.conj(value)
        if not mp.isfinite(value):
            raise ArithmeticError('Nonfinite evaluation')
        if x<1 or x==1:
            assert mp.im(value)==0
        return tuple(mp.nstr(v,working) for v in (mp.re(value),mp.im(value)))


class HolomorphicPeriods(numberdb.Generator):
    table='T679'
    parameters=('template','z')
    type='C'
    digits=100
    rigour='heuristic (agreement-checked)'
    files=('generate.py','checks.py','exact_checks.py','argument-selection.md','numerical-evidence.md',
           'checks.jsonl','dry-run.log','source-evidence.md')

    def enumerate(self):
        for template in TEMPLATES:
            for z in FIBRES:
                yield {'template':template,'z':z}

    def value(self,params,digits):
        at=(digits+40,digits+90)
        real=numberdb.agreeing(lambda w: components(params['template'],params['z'],w)[0],at=at)
        imag=numberdb.agreeing(lambda w: components(params['template'],params['z'],w)[1],at=at)
        value=ComplexIntervalField(numberdb.bits(max(at)))(real,imag)
        comment=''
        if params['z']=='2':
            comment='The upper-bank value retains its positive imaginary component.'
        if params['template']=='2.2.2.2' and params['z']=='1':
            comment=r'This value is $16L(f,2)/\pi^2$ for $f(\tau)=\eta(2\tau)^4\eta(4\tau)^4$, where $\eta$ is the Dedekind eta function CITE{RWZ}.'
        if params['z'] != '1':
            template=params['template']; z=params['z']
            p,q=LOCAL_LINKS[template][z]
            comment += (' ' if comment else '') + (
                'Local arithmetic of this fibre includes '
                f'HREF{{Frobenius_polynomials_of_hypergeometric_Calabi_Yau_motives#{template},{z},{p}}}[the Frobenius polynomial at $p={p}$] and '
                f'HREF{{Unit_roots_of_hypergeometric_Calabi_Yau_motives#{template},{z},{q}}}[the unit eigenvalue at $p={q}$].'
            )
        return {'number':value,'comment':comment} if comment else value


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].replace('_','').isalnum():
            key=key.split('=',1)[1].strip().strip('\"\'')
        os.environ['NUMBERDB_API_KEY']=key
    generator=HolomorphicPeriods()
    if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH')=='1':
        print(generator.publish(message='Compute 56 normalized periods at two precisions; independent continuation and conifold checks.'))
    else:
        report=generator.verify(sample=None)
        print(report)
        sys.exit(0 if report.ok else 1)