Calculating π ( Pi ) with Python

pi

For fun I decided to write a python script to calculate the mathematical constant \pi (Pi). Here’s my code


# Author: Muhammad Ahmad Tirmazi
# Date: January 4, 2014
from decimal import *
import math

class PiCalculator(): #Calculates Pi
    def __init__(self, prec):
        getcontext().prec = prec # the precision
        return
    
    def nilakantha(self, end): # Nilakantha's series
        op = '+'
        x = Decimal(3)
        for n in range(2, end, 2):
            if (op == '-'):
                x -= ( Decimal(4) / Decimal((n * (n+1) * (n+2))) )
                op = '+'
            else:
                x += ( Decimal(4) / Decimal((n * (n+1) * (n+2))) )
                op = '-'
        return x

    def gregory_leibniz(self, end): # Gregory-Leibniz's series 
        op = '+'
        x = Decimal(0)
        for n in range(1, end):
            if (op == '-'):
                x -= ( Decimal(4) / Decimal(2*n - 1) )
                op = '+'
            else:
                x += ( Decimal(4) / Decimal(2*n - 1) )
                op = '-'
        return x

    def ramanujan(self, end): # Ramanujan's series
        y = Decimal(0)
        
        for n in range(0, end):
            y += ( Decimal(math.factorial(4*n)) * Decimal((1103 + 26390*n)) )\
              / (Decimal(math.pow( Decimal(math.factorial(n)), 4)) \
                 * Decimal(math.pow(396, 4*n)) )
        y *= ( Decimal(2) * Decimal(math.sqrt(2)) ) / Decimal(9801)
        
        y = Decimal(1/y)
        return y

    def chudnovsky(self, end):
        y = Decimal(0)
        
        for n in range(0, end):
            y += ( Decimal(math.factorial(6*n)) * \
                   Decimal((13591409 + 545140134*n)) )\
              / ( Decimal(math.pow( \
                  Decimal(math.factorial(3*n)) * Decimal(math.factorial(n)), 3)) \
                 * Decimal(math.pow(-640320, 3*n)) )
            
        y *= ( Decimal(12) / Decimal(math.pow(640320, 1.5)) )
        
        y = Decimal(1/y)
        return y        

    def in_built(self): # Stored Value by Python implementation
        return Decimal(math.pi)

I did a test-run allowing ten iterations to each method:

def main():

    calc_pi = PiCalculator(10**3)

    pi_s = calc_pi.in_built()
    pi_n = calc_pi.nilakantha(10)
    pi_gl = calc_pi.gregory_leibniz(10)
    pi_r = calc_pi.ramanujan(10)
    pi_c = calc_pi.chudnovsky(10)

    separator = "\n\n\n********\n\n"

    print("Stored Value: ", pi_s, separator)
    print("Nilakantha: ", pi_n, separator)
    print("Gregory-Leibniz: ", pi_gl, separator)
    print("Ramanujan: ", pi_r, separator)
    print("Chudnovsky: ", pi_c, separator)
    input("press any key to continue")
    return

main()

I compared my results with this. The Gregory-Leibniz method was accurate only to the first digit. Nilakantha to the first 2 digits. Chudnovsky was accurate to the first 14 digits and Ramanujan’s method turned out to be the best so far by yielding 16 accurate digits.

Next, I decided to give the Nilakantha and Gregory-Leibniz methods a bit of an advantage by allowing then 10^4 iterations each, while I increased the iterations of the Chudnovsky and Ramanujan to only 15.


 pi_s = calc_pi.in_built()
 pi_n = calc_pi.nilakantha(10**4)
 pi_gl = calc_pi.gregory_leibniz(10**4)
 pi_r = calc_pi.ramanujan(15)
 pi_c = calc_pi.chudnovsky(15)

This time Gregory-Leibniz was accurate to the first 4 digits and Nilakantha to the first 11 digits. Chudnovsky’s and Ramanujan’s methods still gave an accuracy of 14 digits and 16 digits respectively.

Overall, it was a pretty educational experience. I found out that for the number of iterations I tried out (unless I made a mistake), the methods, in order of decreasing accuracy are:

  • Ramanujan — 16 digits on 15 iterations (Most Accurate)
  • Chudnovsky — 14 digits on 15 iterations
  • Nilakantha — 11 digits on 10^4 iterations
  • Gregory-Leibniz — 4 digits on 10^4 iterations (Least Accurate)
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s