bernoulli_numbers_from_factorials_visual.pl 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 02 December 2017
  4. # https://github.com/trizen
  5. # A new algorithm for computing Bernoulli numbers (visualization).
  6. # Inspired from Norman J. Wildberger video lecture:
  7. # https://www.youtube.com/watch?v=qmMs6tf8qZ8
  8. # See also:
  9. # https://en.wikipedia.org/wiki/Bernoulli_number#Connection_with_Pascal’s_triangle
  10. use 5.010;
  11. use strict;
  12. use warnings;
  13. use Math::AnyNum qw(:overload factorial bernfrac);
  14. sub bernoulli_numbers {
  15. my ($n) = @_;
  16. my @B = (1, (0) x $n);
  17. foreach my $i (1 .. $n) {
  18. if ($i % 2 != 0 and $i > 1) {
  19. ## next;
  20. }
  21. foreach my $k (0 .. $i - 1) {
  22. if ($k % 2 != 0 and $k > 1) {
  23. ## next;
  24. }
  25. my $f = factorial($i - $k + 1);
  26. my $d = $B[$i] - $B[$k] / $f;
  27. printf("[%2s, %s] -> %6s / %2s! - %6s / %s! / %2s! = %6s / %2s!\n",
  28. $i, $k, $B[$i] * factorial($i),
  29. $i, $B[$k] * factorial($k),
  30. $k,
  31. $i - $k + 1,
  32. $d * factorial($i), $i);
  33. $B[$i] = $d;
  34. }
  35. say '';
  36. }
  37. map { $B[$_] * factorial($_) } 0 .. $#B;
  38. }
  39. my @B = bernoulli_numbers(10); # first 10 Bernoulli numbers
  40. foreach my $i (0 .. $#B) {
  41. # Verify the results
  42. if ($i > 1 and $B[$i] != bernfrac($i)) {
  43. die "error for i=$i";
  44. }
  45. say "B($i) = $B[$i]";
  46. }
  47. __END__
  48. [ 1, 0] -> 0 / 1! - 1 / 0! / 2! = -1/2 / 1!
  49. [ 2, 0] -> 0 / 2! - 1 / 0! / 3! = -1/3 / 2!
  50. [ 2, 1] -> -1/3 / 2! - -1/2 / 1! / 2! = 1/6 / 2!
  51. [ 3, 0] -> 0 / 3! - 1 / 0! / 4! = -1/4 / 3!
  52. [ 3, 1] -> -1/4 / 3! - -1/2 / 1! / 3! = 1/4 / 3!
  53. [ 3, 2] -> 1/4 / 3! - 1/6 / 2! / 2! = 0 / 3!
  54. [ 4, 0] -> 0 / 4! - 1 / 0! / 5! = -1/5 / 4!
  55. [ 4, 1] -> -1/5 / 4! - -1/2 / 1! / 4! = 3/10 / 4!
  56. [ 4, 2] -> 3/10 / 4! - 1/6 / 2! / 3! = -1/30 / 4!
  57. [ 4, 3] -> -1/30 / 4! - 0 / 3! / 2! = -1/30 / 4!
  58. [ 5, 0] -> 0 / 5! - 1 / 0! / 6! = -1/6 / 5!
  59. [ 5, 1] -> -1/6 / 5! - -1/2 / 1! / 5! = 1/3 / 5!
  60. [ 5, 2] -> 1/3 / 5! - 1/6 / 2! / 4! = -1/12 / 5!
  61. [ 5, 3] -> -1/12 / 5! - 0 / 3! / 3! = -1/12 / 5!
  62. [ 5, 4] -> -1/12 / 5! - -1/30 / 4! / 2! = 0 / 5!
  63. [ 6, 0] -> 0 / 6! - 1 / 0! / 7! = -1/7 / 6!
  64. [ 6, 1] -> -1/7 / 6! - -1/2 / 1! / 6! = 5/14 / 6!
  65. [ 6, 2] -> 5/14 / 6! - 1/6 / 2! / 5! = -1/7 / 6!
  66. [ 6, 3] -> -1/7 / 6! - 0 / 3! / 4! = -1/7 / 6!
  67. [ 6, 4] -> -1/7 / 6! - -1/30 / 4! / 3! = 1/42 / 6!
  68. [ 6, 5] -> 1/42 / 6! - 0 / 5! / 2! = 1/42 / 6!
  69. [ 7, 0] -> 0 / 7! - 1 / 0! / 8! = -1/8 / 7!
  70. [ 7, 1] -> -1/8 / 7! - -1/2 / 1! / 7! = 3/8 / 7!
  71. [ 7, 2] -> 3/8 / 7! - 1/6 / 2! / 6! = -5/24 / 7!
  72. [ 7, 3] -> -5/24 / 7! - 0 / 3! / 5! = -5/24 / 7!
  73. [ 7, 4] -> -5/24 / 7! - -1/30 / 4! / 4! = 1/12 / 7!
  74. [ 7, 5] -> 1/12 / 7! - 0 / 5! / 3! = 1/12 / 7!
  75. [ 7, 6] -> 1/12 / 7! - 1/42 / 6! / 2! = 0 / 7!
  76. [ 8, 0] -> 0 / 8! - 1 / 0! / 9! = -1/9 / 8!
  77. [ 8, 1] -> -1/9 / 8! - -1/2 / 1! / 8! = 7/18 / 8!
  78. [ 8, 2] -> 7/18 / 8! - 1/6 / 2! / 7! = -5/18 / 8!
  79. [ 8, 3] -> -5/18 / 8! - 0 / 3! / 6! = -5/18 / 8!
  80. [ 8, 4] -> -5/18 / 8! - -1/30 / 4! / 5! = 17/90 / 8!
  81. [ 8, 5] -> 17/90 / 8! - 0 / 5! / 4! = 17/90 / 8!
  82. [ 8, 6] -> 17/90 / 8! - 1/42 / 6! / 3! = -1/30 / 8!
  83. [ 8, 7] -> -1/30 / 8! - 0 / 7! / 2! = -1/30 / 8!
  84. [ 9, 0] -> 0 / 9! - 1 / 0! / 10! = -1/10 / 9!
  85. [ 9, 1] -> -1/10 / 9! - -1/2 / 1! / 9! = 2/5 / 9!
  86. [ 9, 2] -> 2/5 / 9! - 1/6 / 2! / 8! = -7/20 / 9!
  87. [ 9, 3] -> -7/20 / 9! - 0 / 3! / 7! = -7/20 / 9!
  88. [ 9, 4] -> -7/20 / 9! - -1/30 / 4! / 6! = 7/20 / 9!
  89. [ 9, 5] -> 7/20 / 9! - 0 / 5! / 5! = 7/20 / 9!
  90. [ 9, 6] -> 7/20 / 9! - 1/42 / 6! / 4! = -3/20 / 9!
  91. [ 9, 7] -> -3/20 / 9! - 0 / 7! / 3! = -3/20 / 9!
  92. [ 9, 8] -> -3/20 / 9! - -1/30 / 8! / 2! = 0 / 9!
  93. [10, 0] -> 0 / 10! - 1 / 0! / 11! = -1/11 / 10!
  94. [10, 1] -> -1/11 / 10! - -1/2 / 1! / 10! = 9/22 / 10!
  95. [10, 2] -> 9/22 / 10! - 1/6 / 2! / 9! = -14/33 / 10!
  96. [10, 3] -> -14/33 / 10! - 0 / 3! / 8! = -14/33 / 10!
  97. [10, 4] -> -14/33 / 10! - -1/30 / 4! / 7! = 19/33 / 10!
  98. [10, 5] -> 19/33 / 10! - 0 / 5! / 6! = 19/33 / 10!
  99. [10, 6] -> 19/33 / 10! - 1/42 / 6! / 5! = -14/33 / 10!
  100. [10, 7] -> -14/33 / 10! - 0 / 7! / 4! = -14/33 / 10!
  101. [10, 8] -> -14/33 / 10! - -1/30 / 8! / 3! = 5/66 / 10!
  102. [10, 9] -> 5/66 / 10! - 0 / 9! / 2! = 5/66 / 10!
  103. B(0) = 1
  104. B(1) = -1/2
  105. B(2) = 1/6
  106. B(3) = 0
  107. B(4) = -1/30
  108. B(5) = 0
  109. B(6) = 1/42
  110. B(7) = 0
  111. B(8) = -1/30
  112. B(9) = 0
  113. B(10) = 5/66