In [5]:
import math
import decimal
import multiprocessing

d = decimal.Decimal

# calculate one term of the Chudnovsky series
def k_func(k):
    k = d(k)
    return ((d(-1)**k)*math.factorial(d(6)*k)*(d(545140134)*k + d(13591409))/
     (math.factorial(d(3)*k)*(math.factorial(k)**d(3))*(d(640320)**(d(3)*k+(d(3/2.0))))))

# compute Pi using the Chudnovsky algorithm
def calc_pi(n):
    sum = d(0)
    for k in range(n):
        sum += k_func(k)
    one_over_pi = d(12)*sum
    return d(1)/one_over_pi

# compute k0..kn-1 in parallel
def calc_pi_mp(n, num_procs=4):
    pool = multiprocessing.Pool(num_procs)
    one_over_pi = d(12)*sum(pool.map(k_func, range(n)))
    return d(1)/one_over_pi

function_terms = 20
decimal.getcontext().prec = function_terms*14+1
pi = calc_pi(function_terms)
print str(pi)
print "as a float", float(pi)
print
# do the same thing, now in parallel
print str(calc_pi(function_terms))

# see also:
# http://www.craig-wood.com/nick/pub/pymath/pi_chudnovsky.py
# for a faster (integer-math only) implementation


3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266483
as a float 3.14159265359

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266483

In [ ]: