[Math] Approximating log of factorial

approximationfactorial

I'm wondering if people had a recommendation for approximating $\log(n!)$. I've been using Stirlings formula,

$ (n + \frac{1}{2})\log(n) – n + \frac{1}{2}\log(2\pi) $

but it is not so great for smaller values of $n$. Is there something better? If not, should I calculate the exact value and switch to the approximation for larger values? If so, what would be a good value of $n$ for making the switch?

UPDATE: Thanks for all the replies! I did a calculation of the choices presented (see Python code at the bottom of this message). Results below. And the winner is… Ramanujan, with the supernatural ability of being within $10^{-4}$ of the correct answer for all values of $n$, or at least it seems so – I did not experiment extensively. Assuming this is the case, approximations are hardly needed, though I might use exact values up to n=10 or so.

I came across Ramanujan's formula yesterday at the bottom of the Wikipedia page for Stirlings formula yesterday, where it was chacterized as "apparently superior". 🙂 I initially did not take it seriously, but then saw it again here. Does anyone know of a derivation?

*************
value to take the log factorial of is 1
Exact value is 0.0
Small value approximation (K.V. Raman) is -1.0
Stirling is -0.0810614667953
Stirling with extra term is -0.00101875912179
Ramanujan is -0.000143497498377
*************
*************
value to take the log factorial of is 2
Exact value is 0.69314718056
Small value approximation (K.V. Raman) is 0.0794415416798
Stirling is 0.651806484605
Stirling with extra term is 0.805957164432
Ramanujan is 0.693112511922
*************
*************
value to take the log factorial of is 5
Exact value is 4.78749174278
Small value approximation (K.V. Raman) is 4.6566274746
Stirling is 4.77084705159
Stirling with extra term is 5.11915374586
Ramanujan is 4.78748794075
*************
*************
value to take the log factorial of is 10
Exact value is 15.1044125731
Small value approximation (K.V. Raman) is 15.3284360229
Stirling is 15.0960820096
Stirling with extra term is 15.7022178132
Ramanujan is 15.1044119984
*************
*************
value to take the log factorial of is 20
Exact value is 42.3356164608
Small value approximation (K.V. Raman) is 42.9103777446
Stirling is 42.3314501411
Stirling with extra term is 43.3122793941
Ramanujan is 42.3356163818
*************
*************
value to take the log factorial of is 1000
Exact value is 5912.12817849
Small value approximation (K.V. Raman) is 5914.66303426
Stirling is 5912.12809515
Stirling with extra term is 5916.56287235
Ramanujan is 5912.12817849
*************

def logfact(n):
    from math import log
    sum = 0
    for i in range(1, n+1):
        sum = sum + log(i)
    return sum

def smallvalapprox(n):
    from math import log, pi
    return (n+1)*log(n) - n

def stirling(n):
    from math import log, pi
    return n*log(n) - n + 0.5*log(n) + 0.5*log(2*pi)

def stirlinge(n):
    from math import log, pi
    return n*log(n) - n + 0.5*log(n) + 0.5*log(2*pi) + log(1+(1.0/12*n))

def r(n):
    from math import log, exp, sqrt, pi
    #return sqrt((2*x + (1.0/3))*pi) * (x**pi)*(exp(-x))                                                                                                           
    return n*log(n) - n + (log(n*(1+4*n*(1+2*n))))/6 + log(pi)/2


def logfactapprox(x):
    print "*************"
    print "value to take the log factorial of is", x
    print "Exact value is", logfact(x)
    print "Small value approximation (K.V. Raman) is", smallvalapprox(x)
    print "Stirling is", stirling(x)
    print "Stirling with extra term is", stirlinge(x)
    print "Ramanujan is", r(x)
    print "*************"

logfactapprox(1)
logfactapprox(2)
logfactapprox(5)
logfactapprox(10)
logfactapprox(20)
logfactapprox(1000)

Best Answer

Approximation for $\log n!$ given by Srinivasa Ramanujan :

$$\log n! \approx n\log n-n+\frac{\log(n(1+4n(1+2n)))}{6}+\frac{\log(\pi)}{2}$$