back to table · edit · history · where entries came from · files · download
3439 bytes, as of the version from 2026-10-28 22:59 (current). Recorded here, not run.
"""Umemura polynomials for Painlevé III -- numberdb.org/T558.
Run with SageMath (install numberdb once with sage -pip install numberdb):
sage -python generate.py # verify the stored table
sage -python generate.py --fill # fill the existing draft
sage -python checks.py # independent exact checks
Authenticated draft reads and writes require NUMBERDB_API_KEY. The campaign
wrapper can supply the key on stdin with NUMBERDB_KEY_FROM_STDIN=1, and request
filling with NUMBERDB_PUBLISH=1. Filling entries does not publish the table.
Clarkson, Law and Lin, SIGMA 19 (2023), 080, equation (1.5), with
S_{-1}=S_0=1. Both x and mu are indeterminates; only n indexes the table.
The storage letter m denotes mu because NumberDB uses single-letter variables.
Division is explicit monic polynomial long division over ZZ[x,mu].
See argument-selection.md for the measured finite extent.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.integer_ring import ZZ
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
R = PolynomialRing(ZZ, names=('x', 'm'), order='lex')
x, mu = R.gens()
MAX_N = 5
_POLYS = [R.one(), x + mu]
def monic_quotient(numerator, denominator):
"""Exact division in x; a nonzero remainder is a hard failure."""
degree = denominator.degree(x)
assert denominator.coefficient({x: degree}) == 1
quotient = R.zero()
remainder = numerator
while remainder and remainder.degree(x) >= degree:
top = remainder.degree(x)
term = remainder.coefficient({x: top}) * x**(top - degree)
quotient += term
remainder -= term * denominator
assert remainder == 0, 'Nonzero recurrence remainder'
return quotient
def polynomial(n):
integer = ZZ(n)
if str(n).strip() != str(integer):
raise ValueError('n must be an integer identity')
n = int(integer)
if n < 0:
raise ValueError('n must be nonnegative')
while len(_POLYS) <= n:
previous, current = _POLYS[-2:]
derivative = current.derivative(x)
numerator = ((x + mu)*current**2
- x*(current*derivative.derivative(x) - derivative**2)
- current*derivative)
_POLYS.append(monic_quotient(numerator, previous))
return _POLYS[n]
class Umemura(numberdb.Generator):
table = 'T558'
parameters = ('n',)
type = 'Z[]'
rigour = 'exact'
digits = 100 # Exact polynomial coefficients are never rounded.
files = ('generate.py', 'checks.py', 'check.py', 'argument-selection.md')
def enumerate(self, maximum=MAX_N):
for n in range(maximum + 1):
yield {'n': n}
def value(self, params, digits):
return polynomial(params['n'])
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].replace('_', '').isupper():
key = key.split('=', 1)[1].strip().strip('\"\'')
os.environ['NUMBERDB_API_KEY'] = key
generator = Umemura()
if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
print(generator.publish(overwrite=False, message='Fill exact monic Umemura polynomials after determinant and Bessel checks.'))
else:
report = generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)