-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBinomial.py
46 lines (35 loc) · 1.23 KB
/
Binomial.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#! usr/bin/python
# All the Binomial related functions by Hector
import math as m
def binomial_coefficient(n, k):
"""
Returns the binomial cofficiend(n, k) for positive 'n' and 'k'.
It generaltes fast binomial coefficeint with the following formula
C(n, k) = prod of{ (n - (k -i))/i } for i = 1 to k
"""
if k > n - k: # take advantage of symmetry
k = n - k
c = 1
for i in range(k):
c = c * (n - i)
c = c / (i + 1)
return c
def binomial_coefficient_app(n, k):
"""
Returns the approximate Binomial coefficient of large 'n' and 'k'
Using the following formula -
T == Gamma function
C(n, k) = exp( ln(T(n + 1)) - ln(T(k+1)) - ln(T(n - k + 1)) )
And ln(T(z)) can be calculated as -
ln(T(z)) = (z - 1/2) * ln(z) - z + ln(2 * pi)/2
"""
if c < 10000:
return binomial_coefficient(n, k)
ln_T_n1 = (n + 1/2.) * m.log(n + 1) - (n + 1) + m.log(2 * m.pi)/2.
ln_T_k1 = (k + 1/2.) * m.log(k + 1) - (k + 1) + m.log(2 * m.pi)/2.
ln_T_nk1 = ( n - k + 1/2.) * m.log( n - k + 1) - (n - k + 1) + m.log(2 * m.pi)/2.
pw = ln_T_n1 - ln_T_k1 - ln_T_nk1
if pw < 700:
return m.exp(pw)
else:
return "exp(%d)"%pw