bernoulli_numbers_ramanujan_congruences.pl 735 B

12345678910111213141516171819202122232425262728293031
  1. #!/usr/bin/perl
  2. # Formula due to Ramanujan for computing the nth-Bernoulli number.
  3. # See also:
  4. # https://en.wikipedia.org/wiki/Bernoulli_number#Ramanujan's_congruences
  5. use 5.020;
  6. use warnings;
  7. use experimental qw(signatures);
  8. use Math::AnyNum qw(:overload sum binomial);
  9. sub ramanujan_bernoulli_number ($n, $cache = {}) {
  10. return 1/2 if ($n == 1);
  11. return 0 if ($n%2 == 1);
  12. $cache->{$n} //= do {
  13. (($n%6 == 4 ? -1/2 : 1) * ($n+3)/3 -
  14. sum(map {
  15. binomial($n+3, $n - 6*$_) * __SUB__->($n - 6*$_, $cache)
  16. } 1 .. ($n - $n%6) / 6)
  17. ) / binomial($n+3, $n)
  18. };
  19. }
  20. foreach my $i (0 .. 50) {
  21. printf "B%-3d = %s\n", 2 * $i, ramanujan_bernoulli_number(2 * $i);
  22. }