back to table · edit · history · where entries came from · files · download
2660 bytes, as of the version from 2026-09-21 07:59. Recorded here, not run.
r"""
Bernoulli numbers -- numberdb.org/T13
Run it with SageMath:
$ sage -pip install numberdb # once
$ sage -python generate.sage # check the table against this code
$ sage -python generate.sage --publish # send it, with NUMBERDB_API_KEY set
This generator writes the exact Bernoulli numbers $B_n$ with
$t/(e^t-1)=\sum B_n t^n/n!$. The default range is $0\leq n\leq 250$.
"""
import os
import sys
from math import comb
import numberdb.sage as numberdb
from sage.arith.misc import bernoulli
from sage.rings.rational_field import QQ
DEFAULT_LIMIT = 250
class BernoulliNumbers(numberdb.Generator):
table = 'T13'
parameters = ('n',)
type = 'Q'
rigour = 'exact'
def enumerate(self, limit=DEFAULT_LIMIT):
for n in range(limit + 1):
yield {'n': n}
def value(self, params, digits):
return bernoulli(int(params['n']))
def bernoulli_by_recurrence(limit):
"""Compute B_n from sum binomial(m+1,k) B_k = 0 for m >= 1."""
values = [QQ(1)]
for m in range(1, limit + 1):
previous = sum(QQ(comb(m + 1, k)) * values[k] for k in range(m))
values.append(-previous / QQ(m + 1))
return values
def independent_check(limit):
generated = BernoulliNumbers()
recurrence = bernoulli_by_recurrence(limit)
for n, expected in enumerate(recurrence):
found = generated.value({'n': n}, digits=0)
if found != expected:
raise AssertionError(
'B_%d: Sage gave %s, recurrence gave %s'
% (n, found, expected)
)
print('independent recurrence check passed for 0 <= n <= %d' % limit)
def limit_from_args(args):
if '--limit' not in args:
return DEFAULT_LIMIT
index = args.index('--limit')
try:
return int(args[index + 1])
except (IndexError, ValueError):
raise SystemExit('--limit must be followed by an integer')
def main(args):
limit = limit_from_args(args)
independent_check(limit)
generator = BernoulliNumbers()
publish = (
'--publish' in args
or os.environ.get('NUMBERDB_PUBLISH', '').strip() == '1'
)
if publish:
if os.environ.get('NUMBERDB_KEY_FROM_STDIN', '').strip() == '1':
key = sys.stdin.read().strip()
os.environ['NUMBERDB_API_KEY'] = key
outcome = generator.publish(
overwrite=False,
limit=limit,
message='extended Bernoulli numbers to n = %d' % limit,
)
else:
outcome = generator.preview(overwrite=False, limit=limit)
print(outcome)
if __name__ == '__main__':
main(sys.argv[1:])