factorial_approximation_bernoulli.sf 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. #!/usr/bin/ruby
  2. # Approximation formula for log(n!), with correction terms based on Bernoulli numbers.
  3. # See also:
  4. # https://arxiv.org/pdf/1002.3894.pdf
  5. # https://en.wikipedia.org/wiki/Stirling%27s_approximation
  6. func approx_log_factorial(n, terms=10) {
  7. n*(log(n) - 1) + log(Num.tau*n)/2 + sum(1..terms, {|k|
  8. bernreal(2*k) / (2*k * (2*k - 1) * n**(2*k - 1))
  9. })
  10. }
  11. func approx_factorial(n, terms=10) {
  12. (n/Num.e)**n * sqrt(Num.tau*n) * prod(1..terms, {|k|
  13. exp(bernreal(2*k) / (2*k * (2*k - 1) * n**(2*k - 1)))
  14. })
  15. }
  16. func log_factorial_correction_terms(terms=10) {
  17. sum(1..terms, {|k|
  18. bernoulli(2*k) / (2*k * (2*k - 1) * Poly(2*k - 1))
  19. })
  20. }
  21. say log(10!) #=> 15.1044125730755152952257093292510703718822507443
  22. say approx_log_factorial(10) #=> 15.1044125730755152952136860557170535087521444435
  23. say ''
  24. say 20! #=> 2432902008176640000
  25. say approx_factorial(20) #=> 2432902008176639999.99999998489098511686006355696
  26. say ''
  27. for k in (1..6) {
  28. say log_factorial_correction_terms(k).pretty
  29. }
  30. __END__
  31. (1/6)/(2*x)
  32. (2*x^3 - 1/15*x)/(24*x^4)
  33. (60*x^8 - 2*x^6 + 4/7*x^4)/(720*x^9)
  34. (3360*x^15 - 112*x^13 + 32*x^11 - 24*x^9)/(40320*x^16)
  35. (302400*x^24 - 10080*x^22 + 2880*x^20 - 2160*x^18 + 33600/11*x^16)/(3628800*x^25)
  36. (39916800*x^35 - 1330560*x^33 + 380160*x^31 - 285120*x^29 + 403200*x^27 - 11940480/13*x^25)/(479001600*x^36)