generate.py

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

4303 bytes, as of the version from 2026-10-31 10:48 (current). Recorded here, not run.

"""Monstrous McKay–Thompson values at rectangular CM points -- numberdb.org/T634.

Run with SageMath (install numberdb once with sage -pip install numberdb):
    sage -python generate.py                  # verify every stored entry
    sage -python generate.py --fill-draft     # fill the existing draft

Filling needs NUMBERDB_API_KEY and does not publish the table. The campaign
wrapper can instead supply a key on stdin with NUMBERDB_KEY_FROM_STDIN=1 and
select filling with NUMBERDB_PUBLISH=1. Only a separate human action may make
a draft public. No offering, review or publication endpoint is used here.

The class normalization is Matsusaka, Research in Number Theory 3 (2017), 23,
Introduction, doi:10.1007/s40993-017-0090-x. The default selection and its
arithmetic justification are in argument-selection.md. The working precision
is numberdb.bits(digits, losing=96), or 429 bits for 100 decimal digits.
Independent tests and measured retained accuracy are in checks.py and
numerical-evidence.md. The first two values are exact by the algebraic
certificate in exact_square_lattice(), not by recognizing their digits.
"""
import os
import re
import sys
from functools import lru_cache

import numberdb.sage as numberdb
from sage.rings.complex_arb import ComplexBallField
from sage.rings.integer_ring import ZZ
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing

PRIMES = (2, 3, 5, 7, 13)
CLASSES = tuple(str(p) + suffix for p in PRIMES for suffix in ('A', 'B'))
MAX_R = 30
WORKING_GUARD = 96


def exact_square_lattice():
    """R_2(i)=512 from j(i)=1728 and the canonical level-two equation.

    Put x=4096/R_2(i)>0. Its equation is
    x^3+48*x^2-960*x+4096=(x-8)^2*(x+64)=0.
    Positivity forces x=8, hence R_2(i)=512, T_2B(i)=536,
    T_2A(i)=544. The equation is T309#2 and j(i)=1728 is T83#-4.
    """
    ring = PolynomialRing(ZZ, 'x')
    x = ring.gen()
    assert x**3 + 48*x**2 - 960*x + 4096 == (x-8)**2*(x+64)
    return {'2A': ZZ(544), '2B': ZZ(536)}


@lru_cache(maxsize=None)
def eta_ratio(p, r, digits):
    field = ComplexBallField(numberdb.bits(digits, losing=WORKING_GUARD))
    tau = field(0, 1) * field(r).sqrt()
    value = (tau.modular_eta() / (p*tau).modular_eta())**(24//(p-1))
    assert value.real().is_finite() and value.imag().is_finite() and value.imag().contains_zero()
    result = value.real()
    assert result > 0
    return result


class McKayThompsonCM(numberdb.Generator):
    table = 'T634'
    parameters = ('g', 'r')
    type = 'R'
    digits = 100
    rigour = 'proven'
    files = ('generate.py', 'checks.py', 'argument-selection.md',
             'algebraic-check-data.json', 'numerical-evidence.md',
             'skill-evidence.json', 'source-checks.md')

    def enumerate(self, max_r=MAX_R):
        for g in CLASSES:
            for r in range(1, max_r + 1):
                yield {'g': g, 'r': r}

    def value(self, params, digits):
        g, r = str(params['g']), int(params['r'])
        if g not in CLASSES or r < 1:
            raise ValueError('Expected one of the ten prime-level classes and r>0')
        p = int(g[:-1])
        if r == 1 and p == 2:
            return {'number': exact_square_lattice()[g],
                    'comment': r'The square lattice has $j(i)=1728$; the level-two modular equation gives $R_2(i)=512$.'}
        R = eta_ratio(p, r, digits)
        result = R + ZZ(24//(p-1))
        if g.endswith('A'):
            result += ZZ(p)**(12//(p-1)) / R
        assert result.is_finite() and result > 0
        return result


def configure_key():
    if os.environ.get('NUMBERDB_KEY_FROM_STDIN'):
        key = sys.stdin.read().strip()
        if re.match(r'^[A-Z_][A-Z0-9_]*\s*=', key):
            key = key.split('=', 1)[1].strip().strip('\"\'')
        numberdb.configure(api_key=key)


if __name__ == '__main__':
    configure_key()
    generator = McKayThompsonCM()
    if '--fill-draft' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
        print(generator.publish(message='Compute 300 CM values with certified enclosures and exact square-lattice cases',
                                assisted_by=os.environ.get('NUMBERDB_ASSISTED_BY', '')))
    else:
        report = generator.verify(sample=None)
        print(report)
        sys.exit(0 if report.ok else 1)