back to table · edit · history · where entries came from · files · download
4074 bytes, as of the version from 2026-11-01 17:38 (current). Recorded here, not run.
"""Minimum point of the Ellenberg–Gijswijt bound -- numberdb.org/T656.
Run with SageMath (or a modular Sage installation):
sage -pip install numberdb
sage -python generate.py # verify all stored entries
sage -python generate.py --fill # fill this draft, with NUMBERDB_API_KEY
sage -python checks.py # independent checks of local values
sage -python checks.py --stored # check values read from the draft
The finite family is n=2,...,32 and the two source conventions rho and gamma.
Read argument-selection.md for the justification and skill-manifest.json for
this run's coordinated instruction hashes. No extra continuous parameter is
sampled. The table stores a minimizer, not the minimum objective value.
For n>=2, strict convexity of log F_n(exp(s)) follows from a positive variance.
Its derivative changes sign from negative to positive, so P_n has precisely
one positive root, between zero and one. Exact rational bisection therefore
certifies that root. A RealBallField conversion encloses both rational
endpoints, and reciprocation propagates their uncertainty. The 96 extra
working bits and 24 additional bisection steps are measured in checks.py;
the resulting balls comfortably support 100 significant decimal digits.
Dimension two returns the exactly known rationals 1/2 and 2.
"""
import os
import sys
from functools import lru_cache
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
WORKING_GUARD = 96
BISECTION_GUARD = 24
MAX_DIMENSION = 32
def stationary(n, t):
"""Horner evaluation of P_n over the coefficient's exact parent."""
result = QQ(0)
for j in range(n - 1, -1, -1):
result = result * t + (3 * j - n + 1)
return result
@lru_cache(maxsize=None)
def root_bounds(n, steps):
if n < 2:
raise ValueError('The algebra dimension must be at least two.')
lo, hi = QQ(0), QQ(1)
assert stationary(n, lo) < 0 < stationary(n, hi)
for _ in range(steps):
mid = (lo + hi) / QQ(2)
sign = stationary(n, mid)
if sign == 0:
return mid, mid
if sign < 0:
lo = mid
else:
hi = mid
assert stationary(n, lo) < 0 < stationary(n, hi)
return lo, hi
class MinimumPoint(numberdb.Generator):
table = 'T656'
parameters = ('n', 'convention')
type = 'R'
digits = 100
rigour = 'proven'
files = ('generate.py', 'checks.py', 'argument-selection.md',
'skill-manifest.json', 'source-evidence.md', 'numerical-evidence.json')
def enumerate(self, maximum=MAX_DIMENSION):
for n in range(2, maximum + 1):
for convention in ('rho', 'gamma'):
yield {'n': n, 'convention': convention}
def value(self, params, digits):
n = int(params['n'])
convention = params['convention']
if convention not in ('rho', 'gamma'):
raise ValueError('Use rho or gamma.')
bits = numberdb.bits(digits, losing=WORKING_GUARD)
lo, hi = root_bounds(n, bits + BISECTION_GUARD)
if lo == hi:
return lo if convention == 'rho' else QQ(1) / lo
R = RealBallField(bits)
rho = R((lo + hi) / QQ(2)).add_error(R((hi - lo) / QQ(2)))
result = rho if convention == 'rho' else QQ(1) / rho
assert result.is_finite() and result > 0
return result
def configured_client():
key = None
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
key = sys.stdin.read().strip()
if '=' in key:
key = key.split('=', 1)[1].strip().strip('\"\'')
return numberdb.Client(api_key=key)
if __name__ == '__main__':
client = configured_client()
generator = MinimumPoint()
if '--fill' in sys.argv:
print(generator.publish(client=client, message='Fill the certified minimizing arguments'))
else:
report = generator.verify(sample=None, client=client)
print(report)
sys.exit(0 if report.ok else 1)