Python Pi approximation

Question:

So I have to approximate Pi with following way: 4*(1-1/3+1/5-1/7+1/9-…). Also it should be based on number of iterations. So the function should look like this:

>>> piApprox(1)
4.0
>>> piApprox(10)
3.04183961893
>>> piApprox(300)
3.13825932952

But it works like this:

>>> piApprox(1)
4.0
>>> piApprox(10)
2.8571428571428577
>>> piApprox(300)
2.673322240709928

What am I doing wrong? Here is the code:

def piApprox(num):
    pi=4.0
    k=1.0
    est=1.0
    while 1<num:
        k+=2
        est=est-(1/k)+1/(k+2)
        num=num-1

    return pi*est
Asked By: user4511836

||

Answers:

This is what you’re computing:

4*(1-1/3+1/5-1/5+1/7-1/7+1/9...)

You can fix it just by adding a k += 2 at the end of your loop:

def piApprox(num):
    pi=4.0
    k=1.0
    est=1.0
    while 1<num:
        k+=2
        est=est-(1/k)+1/(k+2)
        num=num-1
        k+=2
    return pi*est

Also the way you’re counting your iterations is wrong since you’re adding two elements at the time.

This is a cleaner version that returns the output that you expect for 10 and 300 iterations:

def approximate_pi(rank):
    value = 0
    for k in xrange(1, 2*rank+1, 2):
        sign = -(k % 4 - 2)
        value += float(sign) / k
    return 4 * value

Here is the same code but more compact:

def approximate_pi(rank):
    return 4 * sum(-float(k%4 - 2) / k for k in xrange(1, 2*rank+1, 2))
Answered By: Vincent
def piApprox(num):                                                              
  pi=4.0                                                                      
  k=3.0                                                                       
  est=1.0                                                                     
  while 1<num:                                                                
    est=est-(1/k)+1/(k+2)                                                   
    num=num-1                                                               
    k+=4                                                                    

  return pi*est

Also for real task use math.pi

Answered By: user4600699

Important edit:
whoever expects this approximation to yield PI — quote from Wikipedia:

It converges quite slowly, though – after 500,000 terms, it produces
only five correct decimal digits of π

Original answer:
This is an educational example. You try to use a shortcut and attempt to implement the “oscillating” sign of the summands by handling two steps for k in the same iteration. However, you adjust k only by one step per iteration.

Usually, in math at least, an oscillating sign is achieved with (-1)**i. So, I have chosen this for a more readable implementation:

def pi_approx(num_iterations):
    k = 3.0
    s = 1.0

    for i in range(num_iterations):
        s = s-((1/k) * (-1)**i)
        k += 2

    return 4 * s

As you can see, I have changed your approach a bit, to improve readability. There is no need for you to check for num in a while loop, and there is no particular need for your pi variable. Your est actually is a sum that grows step by step, so why not call it s (“sum” is a built-in keyword in Python). Just multiply the sum with 4 in the end, according to your formula.

Test:

>>> pi_approx(100)
3.1514934010709914

The convergence, however, is not especially good:

>>> pi_approx(100) - math.pi
0.009900747481198291

Your expected output is flaky somehow, because your piApprox(300) (should be 3.13825932952, according to your) is too far away from PI. How did you come up with that? Is that possibly affected by an accumulated numerical error?

Edit

I would not trust the book too much in regard of what the function should return after 10 and 300 iterations. The intermediate result, after 10 steps, should be rather free of numerical errors, indeed. There, it actually makes a difference whether you take two steps of k at the same time or not. So this most likely is the difference between my pi_approx(10) and the books’. For 300 iterations, numerical error might have severely affected the result in the book. If this is an old book, and they have implemented their example in C, possibly using single precision, then a significant portion of the result may be due to accumulation of numerical error (note: this is a prime example for how bad you can be affected by numerical errors: a repeated sum of small and large values, it does not get worse!).

What counts is that you have looked at the math (the formula for PI), and you have implemented a working Python version of approximating that formula. That was the learning goal of the book, so go ahead and tackle the next problem :-).

Here is a slightly simpler version:

def pi_approx(num_terms):
    sign    = 1.                  # +1. or -1.
    pi_by_4 = 1.                  # first term
    for div in range(3, 2 * num_terms, 2):   # 3, 5, 7, ...
        sign     = -sign          # flip sign
        pi_by_4 += sign / div     # add next term
    return 4. * pi_by_4

which gives

>>> for n in [1, 10, 300, 1000, 3000]:
...     print(pi_approx(n))

4.0
3.0418396189294032
3.1382593295155914
3.140592653839794
3.1412593202657186
Answered By: Hugh Bothwell

While all of these answers are perfectly good approximations, if you are using the Madhava-Leibniz Series than you should arrive at ,”an approximation of π correct to 11 decimal places as 3.14159265359″ within in first 21 terms according to this website: https://en.wikipedia.org/wiki/Approximations_of_%CF%80

Therefore, a more accurate solution could be any variation of this:

import math

def estimate_pi(terms):
    ans = 0.0
    for k in range(terms):
        ans += (-1.0/3.0)**k/(2.0*k+1.0)
    return math.sqrt(12)*ans

print(estimate_pi(21))

Output: 3.141592653595635

Answered By: sjbcode
def pi_approx(pts: List[List[float]]) -> float:
points_that_satisfy_the_formula = []
for i in pts:
    point = i
    x = point[0]
    y = point[1]
    if math.pow(x, 2) + math.pow(y, 2) <= 1:
        points_that_satisfy_the_formula.append(point)
return 4 * (len(points_that_satisfy_the_formula)/ len(pts))
Answered By: Yousra ADDALI
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.