back to table · edit · history · where entries came from · files · download
3552 bytes, as of the version from 2026-09-15 18:27 (current). Recorded here, not run.
"""https://numberdb.org/T228
Generate T228, the values of the derivative zeta'(s) of the Riemann zeta
function at rational arguments.
Run it with SageMath:
$ sage -pip install numberdb
$ sage -python generate.py
$ sage -python generate.py --publish
Under the repository's agent runner, pipe the API key on stdin:
$ cat "$NUMBERDB_KEY_FILE" | NUMBERDB_KEY_FROM_STDIN=1 \
agents/sage.sh generators/zeta-derivative-rational-values/generate.py
Set NUMBERDB_PUBLISH=preview to preview the write, or NUMBERDB_PUBLISH=1 to
send the entries and attach this file.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.complex_arb import ComplexBallField
from sage.rings.rational_field import QQ
WORKING_GUARD = 96
def configure_key_from_stdin():
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') != '1':
return
token = sys.stdin.read().strip()
if '=' in token and token.split('=', 1)[0].isupper():
token = token.split('=', 1)[1].strip().strip('\'"')
if token:
numberdb.configure(api_key=token)
def rational_arguments(denominator=4, lower=-20, upper=20):
for b in range(1, denominator + 1):
for n in range(0, upper * b + 1):
numerators = [n] if n == 0 else [n, -n]
for a in numerators:
s = QQ(a) / QQ(b)
if s.denominator() != b or s < lower or s > upper or s == 1:
continue
yield s
def finite_real(value, label):
if not value.real().is_finite() or not value.imag().is_finite():
raise ArithmeticError('computed a non-finite ball for %s' % (label,))
if not value.imag().contains_zero():
raise ArithmeticError('expected a real value for %s' % (label,))
return value.real()
def derivative_comment(s):
text = str(s)
if text == '0':
return '$-\\frac12\\log(2\\pi)$.'
if text == '-1':
return (
'$\\frac1{12}-\\log A$, where $A$ is '
'HREF{T227#1,A}[the Glaisher-Kinkelin constant] '
'CITE{DLMFBarnes}.'
)
if text == '-2':
return '$-\\zeta(3)/(4\\pi^2)$.'
if text == '-4':
return '$3\\zeta(5)/(4\\pi^4)$.'
if text == '2':
return (
'$\\frac{\\pi^2}{6}(\\gamma+\\log(2\\pi)-12\\log A)$ '
'CITE{DLMFBarnes}.'
)
return ''
class RiemannZetaDerivativeAtRationals(numberdb.Generator):
table = 'T228'
parameters = ('s',)
type = 'R'
digits = 100
rigour = 'proven'
def enumerate(self):
for s in rational_arguments():
yield {'s': str(s)}
def value(self, params, digits):
field = ComplexBallField(numberdb.bits(digits, losing=WORKING_GUARD))
rational_s = QQ(params['s'])
s = field(rational_s)
number = finite_real(s.zetaderiv(1), "zeta'(%s)" % (rational_s,))
comment = derivative_comment(rational_s)
if comment:
return {'number': number, 'comment': comment}
return number
def main():
configure_key_from_stdin()
generator = RiemannZetaDerivativeAtRationals()
mode = os.environ.get('NUMBERDB_PUBLISH')
if '--publish' in sys.argv or mode == '1':
print(generator.publish(message='split T228 derivative entries'))
return
if '--preview' in sys.argv or mode == 'preview':
print(generator.preview())
return
report = generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)
if __name__ == '__main__':
main()