modular_bernoulli_numbers_numberphile.sf 818 B

1234567891011121314151617181920212223242526272829303132333435
  1. #!/usr/bin/ruby
  2. # A nice recursive formula for computing the n-th Bernoulli number (modulo another integer).
  3. # Formula presented in the following Numberphile video:
  4. # Faulhaber's Fabulous Formula (and Bernoulli Numbers) - Numberphile
  5. # https://youtube.com/watch?v=83NFR7JDlww
  6. func modular_bernoulli_numberphile(n, m) is cached {
  7. return 1 if (n == 0)
  8. return ((1/2)%m) if (n == 1)
  9. return 0 if (n.is_odd)
  10. var x = PolyMod(1, m)
  11. var t = ((x - 1)**(n+1) - x**(n+1))
  12. var cf = t.coeffs
  13. var lt = cf.pop
  14. var term = cf.sum_2d {|a,b|
  15. mulmod(__FUNC__(a, m), b, m)
  16. }
  17. divmod(term, -lt[1], m)
  18. }
  19. var m = next_prime(1e9)
  20. for n in (0..20) {
  21. var B = modular_bernoulli_numberphile(n, m)
  22. assert_eq(B, n.bernoulli % m)
  23. say "B_#{n} = #{B.as_rat}"
  24. }