'Wallis' formula for pi

def wallis(n):
    pi = 0.0

    for i in range(n):
        left = (2 * i)/(2 * i - 1)
        right = (2 * i)/(2 * i + 1)
        total = left * right
        pi = pi + total

    return pi

print wallis(1000)
print wallis(10000)
print wallis(100000)

I copied the formula exactly but I keep getting 0 as the output. Can someone please tell me what I am doing wrong. Python 2.7.

The link to the formula is here



Solution 1:[1]

Python is doing integer division, and truncates the decimals. This is because both values to division are integers. Convert one of the numbers to a float to get a floating point value in return.

left = float(2 * i)/(2 * i - 1)
right = float(2 * i)/(2 * i + 1)

OR, as @kindall points out, you can change the constants to floats directly and avoid the call to the float function:

left = (2.0 * i)/(2 * i - 1) # just 2. works, too
right = (2.0 * i)/(2 * i + 1)

If/when you switch to python 3.x, you won't need to do this. In fact, you need to explicitly request integer division with //.

As per a comment by @Serdalis, you could also add from __future__ import division at the top of your file to get the same behavior as python 3.x (i.e. you won't need to add the float in your equation.)

Solution 2:[2]

Apart from problem highlighted by @SethMMorton your formula is wrong. First it is a product not sum, second it gives pi/2 not pi. At last there is no reason to loop from 0.

def wallis(n):
    pi = 2.
    for i in xrange(1, n):
        left = (2. * i)/(2. * i - 1.)
        right = (2. * i)/(2. * i + 1.)
        pi = pi * left * right
    return pi

Solution 3:[3]

Just to add that you can do this in a pythonic way that also looks a lot closer to the mathematical expression. (Here the .25 takes care of the floating point conversion)

def product(iterator):
    return reduce(lambda x, y: x * y, iterator)

print 2 * product(i * i / (i * i - .25) for i in xrange(1, 1000))

Solution 4:[4]

According to the Wallis formula:

enter image description here

...and with implementation in Python 3.4.2 with total execution time of ~0.095s for n = 100000:

def wallis(n):
    pi = 0.0   
    for i in range(1, n):
        x = 4 * (i ** 2)
        y = x - 1
        z = float(x) / float(y)
        if (i == 1):
            pi = z
        else:
            pi *= z
    pi *= 2
    return pi

print(wallis(100000))

Solution 5:[5]

Yet another solution, using list Built-in functions and list comprehension for maximum "pythonicness" :)

2 * reduce(lambda x, y: x*y, [(4.0*(i**2))/(4.0*(i**2)-1) for i in range (1, 1000000)])

Solution 6:[6]

The formula used as Wallis is wrong.The formula is 4 * productory from 1 to n of (2i * (2i+1)) / (2i+1)(2i+1). With 1000 iterations I found 3.1423781499034176 But using Newton´s method with just 10 iterations I found 3.141592653589793 for those who don´t remember, the Newton´s method uses derivatives and the formula is (of course it must be used the command import math) x-= f(x)/derivative_f(x) where x is the initial value for the root (I used x=1) and defined def f(x): return = math.tan(x/4)-1 def sec(x): # the secant does not belong to math library return 1/math.cos(x) def derivative_f: return (1/4)*sec(x/4)*sec(x)

Solution 7:[7]

pi = 2
count = 0
    while True:
        count = count + 1
        tcount = count * 2
        pi = pi * (((tcount) / ((tcount) - 1)) * ((tcount) / (tcount + 1)))
        print(pi, count)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Stuart
Solution 4
Solution 5 Pau
Solution 6 Marcilio Carneiro
Solution 7 Bryan Smith