back to table · edit · history · where entries came from · files · download
3032 bytes, as of the version from 2026-11-02 20:37 (current). Recorded here, not run.
"""Exact reconstruction helpers from T683; provenance in source-provenance.json."""
import sys
import json
from pathlib import Path
from functools import lru_cache
import numberdb.sage as numberdb
from sage.libs.pari import pari
from sage.rings.rational_field import QQ
from sage.rings.integer_ring import ZZ
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.qqbar import QQbar, _init_qqbar
from sage.rings.complex_mpfr import ComplexField
from sage.rings.complex_interval_field import ComplexIntervalField
# Sage's named import does not run this initializer, which exact complex
# conjugation needs. Initialize it explicitly without importing sage.all.
_init_qqbar()
BASE = Path(__file__).resolve().parent
ROSTER = json.loads((BASE / 'roster.json').read_text())
BY_FORM = {e['label']: (r, e) for r in ROSTER for e in r['embeddings']}
WORKING_DIGITS = (160, 220)
P = PolynomialRing(QQ, 'x')
def rational_decimal(text):
from fractions import Fraction
x = Fraction(text)
return QQ(x.numerator) / QQ(x.denominator)
def coeff_poly(value):
return P(str(pari.lift(value)).replace('y', 'x'))
@lru_cache(maxsize=None)
def algebra(label):
row = next(r for r in ROSTER if r['label'] == label)
F = P(row['field_poly'])
cs = [P([QQ(c) for c in v]) for v in row['an_power_basis']]
roots = [z for z, mult in F.roots(QQbar) if mult == 1]
assert len(roots) == row['degree']
embedded = {}
for e in row['embeddings']:
box = [[rational_decimal(c) for c in edge] for edge in e['root_rectangle']]
found = [z for z in roots if box[0][0] < z.real() < box[0][1]
and box[1][0] < z.imag() < box[1][1]]
assert len(found) == 1, e['label']
z = found[0]
is_real = all(c(z).imag() == 0 for c in cs)
embedded[e['label']] = (z, is_real)
zs = [z for z, real in embedded.values()]
assert all(zs[i] != zs[j] for i in range(len(zs)) for j in range(i))
return F, cs, embedded
def reconstruct(row):
N, k = row['level'], row['weight']
spec = [N, k, row['character_discriminant']]
mf = pari.mfinit(spec, 0)
F, cs, embedded = algebra(row['label'])
h = P([QQ(c) for c in row['pari_generator_in_catalogue_field']])
choices = []
for f in pari.mfeigenbasis(mf):
fp = pari.mfparams(f)[3]
if str(fp) != row['pari_field_poly']:
continue
cf = list(pari.mfcoefs(f, row['sturm_bound']))
if all(coeff_poly(a)(h) % F == c for a, c in zip(cf, cs)):
choices.append(f)
assert len(choices) == 1, ('exact reconstruction', row['label'])
f = choices[0]
if row['fricke_eigenvalue'] is not None:
A = pari.mfatkininit(mf, N, precision=128)
assert A[2] == 1
af = pari.mfatkin(A, f)
ac = list(pari.mfcoefs(af, row['sturm_bound']))
fc = list(pari.mfcoefs(f, row['sturm_bound']))
assert all(a == row['fricke_eigenvalue'] * b for a, b in zip(ac, fc))
return mf, f, h, embedded