back to table · edit · history · where entries came from · files · download
3237 bytes, as of the version from 2026-10-16 10:14 (current). Recorded here, not run.
"""Orbifold Euler characteristics of smooth curves -- numberdb.org/T461.
Run with SageMath (install numberdb once with sage -pip install numberdb):
sage -python generate.py # verify every stored entry
sage -python checks.py # independent checks, no network
sage -python checks.py --stored # check the stored entries
sage -python generate.py --fill # fill this draft using an API key
A draft needs its author's NUMBERDB_API_KEY even for reading. The build
wrapper may instead supply the key on stdin with NUMBERDB_KEY_FROM_STDIN=1.
The --fill operation sends entries and source files; it does not publish or
offer the draft. No publication or review endpoint is used.
The quantity concerns smooth curves with ordered markings and full stack
weights. The seed is the exact Harer-Zagier value, and forgetting the final
marking supplies the recurrence. No floating-point arithmetic is used.
The default range includes all stable pairs 1 <= g <= 12, 0 <= n <= 12.
Genus zero is supported by chi() for the displayed formula but not enumerated:
its values are signed factorials. All rational values are exact, so decimal
precision has no role in this table.
"""
import os
import sys
from functools import lru_cache
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.arith.misc import bernoulli
@lru_cache(None)
def chi(g, n):
"""Exact orbifold Euler characteristic of the smooth moduli stack."""
g, n = int(g), int(n)
if g < 0 or n < 0 or 2 * g - 2 + n <= 0:
raise ValueError('A stable pair g >= 0, n >= 0 is required.')
if g == 0:
result, first = QQ(1), 3
elif g == 1:
result, first = -QQ(1) / QQ(12), 1
else:
result = QQ(bernoulli(2 * g)) / QQ(2 * g * (2 * g - 2))
first = 0
for marks in range(first, n):
result *= 2 - 2 * g - marks
return result
class OrbifoldEulerCharacteristics(numberdb.Generator):
table = 'T461'
parameters = ('g', 'n')
type = 'Q'
rigour = 'exact'
files = ('generate.py', 'checks.py', 'check.py', 'evidence.json')
def enumerate(self, max_genus=12, max_marks=12):
for g in range(1, max_genus + 1):
for n in range(max_marks + 1):
if 2 * g - 2 + n > 0:
yield {'g': g, 'n': n}
def value(self, params, digits):
g, n = int(params['g']), int(params['n'])
result = {'number': chi(g, n)}
if (g, n) == (1, 1):
result['comment'] = r'The orbifold Euler characteristic of the moduli stack of elliptic curves is $-1/12$; the generic elliptic involution is included.'
return result
if __name__ == '__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
numberdb.configure(api_key=sys.stdin.read().strip())
generator = OrbifoldEulerCharacteristics()
if '--fill' in sys.argv or os.environ.get('NUMBERDB_FILL'):
outcome = generator.publish(message='Fill the draft with exact Harer-Zagier characteristics and independent checks.')
print(outcome)
else:
report = generator.verify(sample=None)
print(report)
raise SystemExit(0 if report.ok else 1)