checks.py

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

6504 bytes, as of the version from 2026-11-02 04:36 (current). Recorded here, not run.

"""Independent exact checks for numberdb.org/T667.

Run: sage -python checks.py
Use --stored with NUMBERDB_API_KEY to repeat them on the website entries.
The campaign wrapper accepts NUMBERDB_KEY_FROM_STDIN=1 on standard input.

This checker expands EOT 1004.0956 equation (1.2) as a bivariate theta
quotient. It does not call the generator's multiplication, theta, or partition
routines. It uses rational long division, contrasting with the generator's
integer theta-decomposition and colored-partition product.
"""
import os
import sys
import json
import math
from collections import defaultdict
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.integer_ring import ZZ


def theta_quotient(n, half_integer):
    # Squared theta2 after cancelling q^(1/4), or squared theta3 in t=q^(1/2).
    lim = n if half_integer else 2 * n
    bound = math.isqrt(2 * lim) + 2
    numerator = defaultdict(lambda: [ZZ(0)] * (lim + 1))
    denominator = [ZZ(0)] * (lim + 1)
    for a in range(-bound, bound + 1):
        for b in range(-bound, bound + 1):
            exponent = (a * (a + 1) + b * (b + 1)) // 2 if half_integer else a*a + b*b
            if exponent > lim:
                continue
            charge = a + b + 1 if half_integer else a + b
            numerator[charge][exponent] += 1
            denominator[exponent] += 1
    inverse = [QQ(0)] * (lim + 1)
    inverse[0] = QQ(1) / QQ(denominator[0])
    for k in range(1, lim + 1):
        inverse[k] = -sum(denominator[j] * inverse[k-j]
                          for j in range(1, k+1)) / QQ(denominator[0])
    # Control the division itself before interpreting any quotient.
    for k in range(lim + 1):
        assert sum(denominator[j] * inverse[k-j] for j in range(k+1)) == (1 if k == 0 else 0)
    result = {}
    for charge, terms in numerator.items():
        nonzero = [(i, v) for i, v in enumerate(terms) if v]
        row = [sum(v * inverse[k-i] for i, v in nonzero if i <= k)
               for k in range(lim + 1)]
        result[charge] = row if half_integer else row[::2]
    return result


def independent_expansion(n):
    second = theta_quotient(n, True)
    third = theta_quotient(n, False)
    # theta4 is theta3 with t replaced by -t. Their sum keeps even powers.
    genus = {}
    for ell in set(second) | set(third):
        genus[ell] = [8 * second.get(ell, [0]*(n+1))[k]
                      + 16 * third.get(ell, [0]*(n+1))[k]
                      for k in range(n+1)]
    return genus



def character_series(genus, n, y):
    # EOT (1.3)-(1.9), with theta1 in the standard odd convention.
    # T=q^(-1/8)*theta1(z)^2/eta^3 and B=theta1(z)^2*mu/eta^3.
    y = QQ(y)
    w = [QQ(1)] + [QQ(0)] * n
    t = [2 - y - 1/y] + [QQ(0)] * n
    for m in range(1, n+1):
        for scale in (y, 1/y):
            for j in range(n, m-1, -1):
                w[j] -= scale*w[j-m]
            for _ in range(2):
                for j in range(n, m-1, -1):
                    t[j] -= scale*t[j-m]
        for _ in range(2):
            for j in range(m, n+1):
                w[j] += w[j-m]
        for j in range(m, n+1):
            t[j] += t[j-m]
    appell = [QQ(1)/(1-y)] + [QQ(0)]*n
    k = 1
    while k*(k+1)//2 <= n:
        start=k*(k+1)//2
        for j in range((n-start)//k+1):
            appell[start+j*k] += (-1)**k*(y**(k+j)-y**(-k-1-j))
        k += 1
    b = [(1-y)*sum(w[j]*appell[k-j] for j in range(k+1))
         for k in range(n+1)]
    assert b[0] == 1
    z = [sum(row[k]*y**ell for ell,row in genus.items()) for k in range(n+1)]
    h = [QQ(0)]*(n+1)
    for k in range(n+1):
        h[k] = (z[k]-24*b[k]-sum(t[j]*h[k-j] for j in range(1,k+1)))/t[0]
    return h


def check(values, max_d):
    n = max_d // 4
    z = independent_expansion(n)
    # Nonzero known-answer controls, before full comparisons.
    controls = {-1: 2, 0: 20, 3: -128, 4: 216, 7: -1026,
                8: 1616, 11: -5504, 12: 8032, 15: -23550, 16: 33048}
    for d, expected in controls.items():
        ell = d % 4 == 3
        grade = (d + ell) // 4
        assert z[int(ell)][grade] == expected, ('control', d)
        assert values[d] == expected, ('stored control', d)
    expected_keys = {d for d in range(-1, max_d+1) if d % 4 in (0,3)}
    assert set(values) == expected_keys
    comparisons = 0
    polar_zeros = 0
    for ell, row in z.items():
        for k, coefficient in enumerate(row):
            d = 4*k - ell*ell
            expected = values[d] if d >= -1 else 0
            assert coefficient == expected, (k, ell, d, coefficient, expected)
            assert QQ(coefficient).denominator() == 1
            assert coefficient == z[-ell][k]
            comparisons += 1
            polar_zeros += d < -1
    for k in range(n+1):
        assert sum(row[k] for row in z.values()) == (24 if k == 0 else 0), ('Euler characteristic',k)
    h_minus_one = character_series(z, n, -1)
    h_minus_two = character_series(z, n, -2)
    assert h_minus_one[:10] == [-2,90,462,1540,4554,11592,27830,61686,131100,265650]
    assert h_minus_two == h_minus_one
    assert all(h.denominator() == 1 for h in h_minus_one)
    return {'character_relation_grades_at_each_of_two_y':n+1,
            'character_published_controls':10,
            'coefficient_comparisons':comparisons, 'vanishing_terms_below_D_minus_1':polar_zeros,
            'known_answer_controls':len(controls), 'euler_characteristic_grades_checked':n+1,
            'charge_reflection':True, 'elliptic_discriminant_dependence':True,
            'all_rational_quotients_integral':True}



def stored_values(document):
    block = document['Numbers']
    if isinstance(block, dict):
        return {int(d): ZZ(value['number'] if isinstance(value, dict) else value)
                for d, value in block.items()}
    return {int(entry['params']['D']): ZZ(entry['number']) for entry in block}


if __name__ == '__main__':
    from generate import K3EllipticGenus, MAX_D
    if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
        key = sys.stdin.read().strip()
        if '=' in key and key.split('=',1)[0].isidentifier():
            key=key.split('=',1)[1].strip().strip('\"\'')
        numberdb.configure(api_key=key)
    if '--stored' in sys.argv or os.environ.get('CHECK_STORED') == '1':
        doc=numberdb.table('T667')
        values=stored_values(doc)
    else:
        g=K3EllipticGenus()
        values={int(p['D']):g.value(p,100) for p in g.enumerate()}
    print(json.dumps(check(values,MAX_D),indent=2))