back to table · edit · history · where entries came from · files · download
4882 bytes, as of the version from 2026-11-09 12:11 (current). Recorded here, not run.
"""Genus-zero GW invariants of projective Calabi–Yau complete intersections -- numberdb.org/T688.
Run with SageMath (or passagemath-symbolics) and the numberdb package:
sage -pip install numberdb # once, inside SageMath
sage -python generate.py # verify every stored entry
sage -python checks.py # offline independent checks
sage -python generate.py --submit # fill the existing draft
The last command requires NUMBERDB_API_KEY and submits entries only. It cannot
publish or offer a draft. NUMBERDB_KEY_FROM_STDIN=1 reads the key from stdin;
NUMBERDB_PUBLISH=1 is the build-wrapper equivalent of --submit.
All series coefficients are Sage rationals. Arrays contain coefficients through
an inclusive degree bound, with explicit convolution, reciprocal, exponential,
and composition. The mirror inverse is computed by x=q exp(-h(x)), gaining an
order each iteration. K(x)=kappa/((1-C*x)*F(x)^2*(1+x*h'(x))^3), h=G/F.
Its q^d coefficient divided by d^3 is the unmarked, connected genus-zero GW
invariant. No instanton/GV values are submitted. Default enumeration is all five
nonlinear ordinary-projective types and every curve degree 1 through 20.
See argument-selection.md and numerical-evidence.md for scope and checks.
"""
import os
import sys
from functools import lru_cache
from math import factorial, prod
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
TARGETS = ((5,), (2, 4), (3, 3), (2, 2, 3), (2, 2, 2, 2))
MAX_DEGREE = 20
EXTRA_ORDERS = 4
def multiply(a, b):
n = len(a)
assert n == len(b)
return [sum((a[j] * b[k-j] for j in range(k+1)), QQ(0))
for k in range(n)]
def reciprocal(a):
assert a[0]
b = [QQ(1) / a[0]]
for k in range(1, len(a)):
b.append(-sum((a[j] * b[k-j] for j in range(1, k+1)), QQ(0)) / a[0])
return b
def exponential(a):
assert a[0] == 0
b = [QQ(1)]
for k in range(1, len(a)):
b.append(sum((QQ(j) * a[j] * b[k-j] for j in range(1, k+1)), QQ(0)) / QQ(k))
return b
def compose(a, b):
assert len(a) == len(b) and b[0] == 0
out = [QQ(0)] * len(a)
for coefficient in reversed(a):
out = multiply(out, b)
out[0] += coefficient
return out
def factorial_periods(ell, order):
harmonics = [QQ(0)]
for j in range(1, max(ell) * order + 1):
harmonics.append(harmonics[-1] + QQ(1) / QQ(j))
f, g = [], []
for m in range(order + 1):
a = QQ(prod(factorial(l*m) for l in ell)) / QQ(factorial(m)**(len(ell)+4))
b = sum((QQ(l) * harmonics[l*m] for l in ell), QQ(0)) - QQ(len(ell)+4)*harmonics[m]
f.append(a)
g.append(a*b)
return f, g
@lru_cache(None)
def yukawa_series(ell, order):
assert ell in TARGETS
f, g = factorial_periods(ell, order)
h = multiply(g, reciprocal(f))
u = [QQ(1)] + [QQ(m)*h[m] for m in range(1, order+1)]
inv_u = reciprocal(u)
inv_f = reciprocal(f)
c = prod(l**l for l in ell)
k_x = [QQ(prod(ell)) * QQ(c)**m for m in range(order+1)]
for factor in (inv_f, inv_f, inv_u, inv_u, inv_u):
k_x = multiply(k_x, factor)
x = [QQ(0), QQ(1)] + [QQ(0)] * (order-1)
for _ in range(order):
correction = exponential([-v for v in compose(h, x)])
new_x = [QQ(0)] + correction[:-1]
if new_x == x:
break
x = new_x
q_x = [QQ(0)] + exponential(h)[:-1]
assert compose(q_x, x) == [QQ(0), QQ(1)] + [QQ(0)]*(order-1)
return tuple(compose(k_x, x))
class ProjectiveCalabiYauGW(numberdb.Generator):
table = 'T688'
parameters = ('multidegree', 'd')
type = 'Q'
rigour = 'exact'
files = ('generate.py', 'checks.py', 'check.py', 'argument-selection.md',
'numerical-evidence.md', 'localization-controls.json',
'skill-manifest.json', 'source-evidence.md')
def enumerate(self, max_degree=MAX_DEGREE):
for ell in TARGETS:
for d in range(1, max_degree+1):
yield {'multidegree': ','.join(map(str, ell)), 'd': str(d)}
def value(self, params, digits):
ell = tuple(map(int, params['multidegree'].split(',')))
d = int(params['d'])
if d < 1:
raise ValueError('Curve degree must be positive')
return yukawa_series(ell, max(MAX_DEGREE, d)+EXTRA_ORDERS)[d] / QQ(d)**3
if __name__ == '__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
os.environ['NUMBERDB_API_KEY'] = sys.stdin.read().strip()
generator = ProjectiveCalabiYauGW()
if '--submit' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
print(generator.publish(message='Fill exact genus-zero Calabi-Yau GW invariants after independent checks'))
else:
report = generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)