factorial_approximations.sf 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #!/usr/bin/ruby
  2. define ℯ = Num.e
  3. define π = Num.pi
  4. define τ = Num.tau
  5. define γ = Num.EulerGamma
  6. define ϕ = Num.phi
  7. # Unknown
  8. # sqrt(2*pi*e) * e^(-((3 - sqrt(3)) / 6)) * (((3 - sqrt(3)) / 6 + n) / e)^(n + 1/2)
  9. func f1(n) {
  10. define w = ((3 - √3) / 6)
  11. define d = (√(τ * ℯ) * exp(-w))
  12. d * pow((n+w) / ℯ, n + 1/2)
  13. }
  14. # S. Ramanujan's formula (simplified)
  15. # sqrt(pi) * (n/e)^n * (n*(4*n*(2*n + 1) + 1))^(1/6)
  16. func f2(n) {
  17. define d = √π
  18. d * exp(-n) * n**n * root(n*(4*n*(2*n + 1) + 1), 6)
  19. }
  20. # Stirling's formula + Trizen's approximation
  21. # sqrt(2*pi*n) * (n/e)^n * (digamma(n+1) + gamma) / (log(n + 1/(phi * sqrt(n))) + gamma) / zeta(n)
  22. func f3(n) {
  23. (√(τ*n) * exp(-n) * n**n * ((digamma(n+1) + γ) / (log(n + 1/(ϕ * √n)) + γ)) / zeta(n))
  24. }
  25. # Stirling's formula
  26. # sqrt(2*pi*n) * (n/e)^n
  27. func f4(n) {
  28. √(τ * n) * exp(-n) * n**n
  29. }
  30. # Stirling's formula + Laplace's method (1)
  31. # sqrt(2*pi*n) * (n/e)^n * (1 + 1/(12*n))
  32. func f5(n) {
  33. √(τ * n) * exp(-n) * n**n * (1 + 1/(12*n))
  34. }
  35. # S. Ramanujan (2)
  36. # sqrt(pi) * n^n * e^(-n) * ((8 * n^3) + (4 * n^2) + n + 1/30)^(1/6)
  37. func f6(n) {
  38. define w = √π
  39. w * pow(n, n) * exp(-n) * pow(((8 * n**3) + (4 * n**2) + n + 1/30), 1/6)
  40. }
  41. # N. Batir
  42. # sqrt(2*pi) * n^n * e^(-n) * sqrt(n + 1/2) * e^(-(1 / (6 * (n + 3/8))))
  43. func f7(n) {
  44. define w = √τ
  45. w * pow(n, n) * exp(-n) * √(n + 1/2) * exp(-(1 / (6 * (n + 3/8))))
  46. }
  47. # N. Batir(2)
  48. # sqrt(2*pi) * n^n * e^(-n) * sqrt(n + 1/6 + 1/(72*n) - 31/(6480 * n^2) - 139/(155520 * n^3) + 9871/(6531840 * n^4))
  49. func f8(n) {
  50. define w = √τ
  51. w * pow(n, n) * exp(-n) * √(n + 1/6 + 1/(72*n) - 31/(6480 * n**2) - 139/(155520 * n**3) + 9871/(6531840 * n**4))
  52. }
  53. # N. Batir(2) derivation by Wolfram|Alpha
  54. # 1/216 * sqrt(pi/70) * exp(-n) * n^(n-2) * sqrt(42*n*(24*n*(90*n*(12*n*(6*n + 1) + 1) - 31) - 139) + 9871)
  55. func f9(n) {
  56. 1/216 * √(π/70) * exp(-n) * n**(n-2) * √(42*n*(24*n*(90*n*(12*n*(6*n + 1) + 1) - 31) - 139) + 9871);
  57. }
  58. # Gamma approximation
  59. # n! ~ (1-i) * (-1)^(1/4) * sqrt(pi) * 12^(-n) * exp(-2*n) * sqrt(n) * ((12*e*n^2 + e)/n)^n
  60. # n! ~ sqrt(pi) * 2^(1/2 - 2*n) * exp(-n) * n^(1/2-n) * (4*n^2 + 1/3)^n
  61. func f10(n) {
  62. sqrt(π) * 2**(1/2 - 2*n) * exp(-n) * n**(1/2 - n) * (4 * n**2 + 1/3)**n
  63. }
  64. # Gamma approximation (2)
  65. # n! ~ limit_{k -> Infinity} sqrt(2*pi) * ((12*n^2 + 24*k*n + 12*k^2 + 1)/(12*e*n + 12*k*e))^(n+k) / ((n+k-1)!/(n!)) / sqrt(n+k)
  66. func f11(n) {
  67. define k = 50 # higher value of k => higher precision
  68. sqrt(τ) * ((12*n**2 + (24*k)*n + 12*k**2 + 1)/(12*ℯ*n + 12*k*ℯ))**(n+k) / prod(1..^k, {|j| n + j }) / sqrt(n+k)
  69. }
  70. # Gamma approximation (3)
  71. # n! ~ (sqrt(2*pi) * ((12*n^2 + 24*n + 12 + 1)/(12*e*n + 12*e))^(n + 1))/sqrt(n + 1)
  72. func f12(n) {
  73. sqrt(τ) * ((12*n**2 + 24*n + 12 + 1)/(12*ℯ*n + 12*ℯ))**(n+1) / sqrt(n+1)
  74. }
  75. const FORMULAS = [
  76. [Unknown => f1],
  77. [Ramanujan => f2],
  78. ["Stirling+Trizen" => f3],
  79. [Stirling => f4],
  80. ["Stirling+Laplace" => f5],
  81. [Ramanujan2 => f6],
  82. [Batir => f7],
  83. [Batir2 => f8],
  84. [Batir2WA => f9],
  85. [Gamma => f10],
  86. [Gamma2 => f11],
  87. [Gamma3 => f12],
  88. ]
  89. #
  90. ## TESTS
  91. #
  92. var report = Hash()
  93. for n in (15..30) {
  94. for name,f in (FORMULAS) {
  95. report{name} := [] << f(n)
  96. }
  97. report{:EXACT} := [] << n!
  98. say "\n=> #{n}!"
  99. for k,v in (report.sort_by {|_,v| v }) {
  100. "%20s: %s\n".printf(k, v[-1]);
  101. }
  102. }
  103. func A(a) { a.sum / a.len }
  104. func G(a) { a.prod.root(a.len) }
  105. func H(a) { a.len / a.map{1/_}.sum }
  106. var r1 = Hash()
  107. var r2 = Hash()
  108. var r3 = Hash()
  109. for k,v in (report) {
  110. k == :EXACT && next;
  111. var arr = v.range.map {|i| abs(report{:EXACT}[i] - v[i])}
  112. r1{k} = A(arr);
  113. r2{k} = G(arr);
  114. r3{k} = H(arr);
  115. }
  116. func print_report(h) {
  117. for k,v in (h.sort_by {|_,v| v }) {
  118. "%20s: %s\n".printf(k, v);
  119. }
  120. }
  121. say ("\n", '-'*80);
  122. say "\n=>> A <<=";
  123. print_report(r1);
  124. say "\n=>> G <<=";
  125. print_report(r2)
  126. say "\n=>> H <<=";
  127. print_report(r3);
  128. say ("\n", '-'*80);