back to table · edit · history · where entries came from · files · download
3772 bytes, as of the version from 2026-11-02 02:56 (current). Recorded here, not run.
"""Holomorphic periods of Fermat curves -- numberdb.org/T665.
Run with SageMath (or a compatible passagemath installation):
sage -pip install numberdb
sage -python generate.py
sage -python checks.py
The default command checks every stored entry; reading a private draft needs
NUMBERDB_API_KEY. To fill a writable draft with these entries and attachments:
sage -python generate.py --fill
This writes numbers only; it cannot offer, review or publish the table itself.
The algebraic differential is x^(a-1)y^(b-N) dx on x^N+y^N=1.
The oriented integral cycle is (1-alpha_*)(1-beta_*)delta, where delta
runs from (0,1) to (1,0) through the nonnegative real quadrant, and alpha,
beta multiply x,y respectively by exp(2*pi*i/N). Thus its period is
(1-zeta^a)(1-zeta^b) Gamma(a/N)Gamma(b/N)/(N Gamma((a+b)/N)).
Every ordered holomorphic pair is retained for each N=3,...,10. See the
attached argument-selection.md for the coverage decision and conventions.md
for character/Hodge metadata and homology context. No normalization by a
transcendental period is made. WORKING_GUARD=96 adds bits to the requested
decimal accuracy; checks.py measures both component radii, and independently
bounds the split Euler integral by positive convergent series.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
from sage.rings.real_mpfi import RealIntervalField
from sage.rings.complex_arb import ComplexBallField
WORKING_GUARD = 96
MAX_DEGREE = 10
class FermatPeriods(numberdb.Generator):
table = 'T665'
parameters = ('N', 'a', 'b')
type = 'C'
digits = 100
rigour = 'proven'
files = ('generate.py', 'checks.py', 'argument-selection.md',
'conventions.md', 'character-data.json', 'skill-manifest.json', 'check.py')
def enumerate(self, max_degree=MAX_DEGREE):
for N in range(3, max_degree + 1):
for a in range(1, N - 1):
for b in range(1, N - a):
yield {'N': N, 'a': a, 'b': b}
def value(self, params, digits):
N, a, b = (int(params[k]) for k in self.parameters)
if not (N >= 3 and a >= 1 and b >= 1 and a + b < N):
raise ValueError('Expected N>=3, a,b>=1, a+b<N')
prec = numberdb.bits(digits, losing=WORKING_GUARD)
R = RealBallField(prec)
C = ComplexBallField(prec)
x, y = R(QQ(a) / N), R(QQ(b) / N)
beta = x.gamma() * y.gamma() / R(QQ(a + b) / N).gamma()
zeta = (2 * C.pi() * C.gen(0) / N).exp()
result = (1 - zeta**a) * (1 - zeta**b) * beta / N
# The phase is -exp(pi*i*(a+b)/N) times a positive real number.
# Its real part is exactly zero when 2*(a+b)=N, independent of digits.
if 2 * (a + b) == N:
imaginary = RealIntervalField(prec)(result.imag())
return numberdb.ComplexInterval(
0, numberdb.RealInterval(imaginary.lower(), imaginary.upper()))
assert result.real().is_finite() and result.imag().is_finite()
return result
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].isidentifier():
key = key.split('=', 1)[1].strip().strip('\"\'')
numberdb.configure(api_key=key)
generator = FermatPeriods()
if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
print(generator.publish(message='Fill every holomorphic character period for degrees 3 through 10',
assisted_by='codex-cli'))
else:
report = generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)