back to table · edit · history · where entries came from · files · download
7043 bytes, as of the version from 2026-11-02 11:01 (current). Recorded here, not run.
"""Shared reproducible generators for Hessian periods and CM determinants.
Download this file, hessian_periods.py, hessian-catalogue.json and
entry-metadata.json beside the table's generate.py. The metadata file contains
labels and explanations only, never numerical answers. All values are
recomputed from the exact arguments in the catalogue.
"""
import argparse
from functools import lru_cache
import itertools
import json
from pathlib import Path
import numberdb.sage as numberdb
import mpmath as mp
from hessian_periods import evaluate, exact_argument, MINIMUM_AGREEMENT_MARGIN
ROOT = Path(__file__).resolve().parent
@lru_cache(maxsize=1)
def catalogue():
return json.loads((ROOT / 'hessian-catalogue.json').read_text())
@lru_cache(maxsize=1)
def arguments():
return {item['key']: item for item in catalogue()['arguments']}
@lru_cache(maxsize=512)
def scalar_result(key, digits):
return evaluate(arguments()[key], digits)
def determinant_matrix(orbit, values):
scaled = [mp.sqrt(coefficient) * value
for coefficient, value in zip(orbit['coefficients'], values)]
arrangement = ((0, 1, 2, 3), (1, 0, 3, 2), (2, 3, 0, 1), (3, 2, 1, 0))
signs = catalogue()['sign_matrices'][str(orbit['variant'])]
return mp.matrix([[signs[row][column] * scaled[arrangement[row][column]]
for column in range(4)] for row in range(4)])
def quartic_determinant(orbit, values):
matrix = determinant_matrix(orbit, values)
result = mp.det(matrix)
absolute_terms = mp.fsum(mp.fprod(abs(matrix[row, permutation[row]]) for row in range(4))
for permutation in itertools.permutations(range(4)))
if not mp.isfinite(result) or result == 0:
raise ArithmeticError('Invalid quartic determinant')
return result, absolute_terms / abs(result)
def determinant_result(kind, orbit, digits, scalar_results=None):
results = scalar_results or {key: scalar_result(key, digits) for key in orbit['keys']}
working_precisions = next(iter(results.values()))['working_precisions']
measurements = []
cancellations = []
for position, working in enumerate(working_precisions):
with mp.workdps(working):
periods = []
for key in orbit['keys']:
result = results[key]
assert result['working_precisions'] == working_precisions
quantity = 'modified' if arguments()[key]['modified'] else 'ordinary'
periods.append(mp.mpf(result['measurements'][position][quantity]))
if kind == 'quadratic':
terms = [coefficient * period**2
for coefficient, period in zip(orbit['coefficients'], periods)]
value = mp.fsum(terms)
if not mp.isfinite(value) or value == 0:
raise ArithmeticError('Invalid quadratic determinant')
cancellation = mp.fsum(abs(term) for term in terms) / abs(value)
else:
value, cancellation = quartic_determinant(orbit, periods)
measurements.append(mp.nstr(value, working - 8))
cancellations.append(mp.nstr(cancellation, 16))
with mp.workdps(working_precisions[-1] + 20):
lower, higher = map(mp.mpf, measurements)
discrepancy = abs((lower - higher) / higher)
agreement = -mp.log10(discrepancy) if discrepancy else mp.inf
if agreement < digits + MINIMUM_AGREEMENT_MARGIN:
raise ArithmeticError('Insufficient determinant agreement: ' + str(agreement))
return {
'key': orbit['keys'][0], 'kind': kind, 'source_row': orbit['source_row'],
'number': mp.nstr(higher, digits, strip_zeros=False),
'working_precisions': working_precisions, 'measurements': measurements,
'agreement_digits': str(agreement), 'cancellation_factors': cancellations,
}
class HessianTable(numberdb.Generator):
parameters = ('t',)
type = 'R'
digits = 100
rigour = 'heuristic (agreement-checked)'
kind = None
files = ('generate.py', 'hessian_generator.py', 'hessian_periods.py',
'hessian-catalogue.json', 'entry-metadata.json', 'argument-selection.md',
'verification.json')
def items(self):
if self.kind in ('ordinary', 'modified'):
return [item for item in catalogue()['arguments'] if item[self.kind]]
return catalogue()[self.kind + '_orbits']
def enumerate(self):
for item in self.items():
yield {'t': item['key'] if self.kind in ('ordinary', 'modified') else item['keys'][0]}
def value(self, params, digits):
key = str(params['t'])
if key not in {entry['t'] for entry in self.enumerate()}:
raise ValueError('The argument is outside this generator selection')
if self.kind in ('ordinary', 'modified'):
number = scalar_result(key, digits)['values'][self.kind]
else:
orbit = next(item for item in self.items() if item['keys'][0] == key)
number = determinant_result(self.kind, orbit, digits)['number']
metadata = json.loads((ROOT / 'entry-metadata.json').read_text()).get(key, {})
if set(metadata) - {'comment', 'param-latex'}:
raise ValueError('Unexpected value-bearing entry metadata')
return dict(metadata, number=number)
def environment(self):
return dict(super().environment(), mpmath=mp.__version__)
class SnapshotClient:
def __init__(self, table_id, document):
self.table_id = table_id
self.document = document
def request(self, path, parameters):
if path != 'api/table' or parameters != {'id': self.table_id}:
raise RuntimeError('Only the specified offline table may be read')
return self.document
def run(generator):
parser = argparse.ArgumentParser(description=generator.__doc__)
parser.add_argument('--snapshot', type=Path, help='verify an offline JSON table export')
parser.add_argument('--digits', type=int, default=100)
parser.add_argument('--publish', action='store_true', help='submit entries for review; requires an API key')
options = parser.parse_args()
generator.digits = options.digits
if options.publish:
if options.snapshot:
parser.error('--publish cannot be combined with --snapshot')
print(generator.publish(message='Extend the source-backed Hessian reference selection'))
return 0
client = None
if options.snapshot:
document = json.loads(options.snapshot.read_text())
expected = [parameters['t'] for parameters in generator.enumerate()]
if expected != list(document['Numbers']):
raise ArithmeticError('Snapshot and default enumeration differ')
client = SnapshotClient(generator.table, document)
report = generator.verify(sample=None, digits=options.digits, client=client)
print(report)
return 0 if report.ok and not report.coarser else 1