Leibniz_Pi.py

Mike C. Fletcher mcfletch at rogers.com
Fri Oct 11 15:02:22 EDT 2002


Well, the rounding errors with FP make this, as far as I can tell, 
basically pointless, but if you want a "better" approach, I think this 
is still "correct", and is a lot clearer (IMO), though as David points 
out, this isn't a "good" way to calculate pi.

Basic principles I'm following are that ranges are the enemy (xranges 
are your friend, that alone gives a marked increase in speed for your 
algo), and that doing an extra (N) arithmetic operations (to switch 
sign) will be expensive when N is very large:

def sum(bottom, top=1.0):
    result = 0
    for divisor in bottom:
        result += (top /divisor)
    return result

def calculate( iterations ):
    """Approximate pi with iterations number of iterations"""
    pos = sum( xrange( 1, iterations*2, 4),  1.0)
    neg = sum( xrange( 3, iterations*2, 4), -1.0)
    return 4.0* (pos + neg)

Note that this will produce slightly different results than yours even 
for low numbers of iterations (such as 12 on my machine).  I'm not sure 
if that's a bug in my code, or just FP being non-commutative.  If you 
really wanted to play with this algo more, you'd probably use Numeric, 
which, with an algo like above, would probably make it necessary to use 
a much higher number of iterations to be timeable (but would still 
return junk most likely).

BTW, for interest's sake: Using psyco to bind "sum" above makes my algo 
run in approx 22% of original time (.98s to .21s).  While using it on 
yours still takes 29% of its original (1.32s to .39s) (which gets you 
right about the same overall run-time as the Java version).  Overall 
improvement from original algo to psyco'd new algo is to run in around 
16% of time, or about 1.6 seconds on your machine (assuming psyco is ~ 
equivalent in optimisations across CPUs).  Just using the new algo gives 
you only about 74%, so still twice as slow as the Java.

Enjoy yourself,
Mike

Cousin Stanley wrote:

>Yesterday in the news group  comp.lang.java.help
>I found a Java example of the  Leibniz Pi  approximation
>and converted the Java code to Python ... 
>
>The numerical results from either version 
>using a  LARGE  number of terms as a program argument
>provide approximations for the number  Pi   that seems correct ... 
>
>Using  1 million  terms as an input argument,
>the Java version is a bit faster, which I think
>is expected ... 
>
>   On a 250 MHz Win98 machine ... 
>   
>     Java SDK 1.4 .......  ~ 3-4   seconds
>    Python 2.2.1 .........  ~ 9-10 seconds
>
>Since I am fairly new to  BOTH  Java  AND  Python,
>I'm wondering if there are any ... 
>
>  obvious oversights        ???
>  Python improvements ???
>
>Python code follows ...
>
>Cousin Stanley
>
>----------------------------------------------------------------
>
>''' 
>    Leibniz_Pi.py
>
>    Pi = 4 * ( 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 ... )
>
>    Using one million terms provides a good approximation ...
>
>    Posted to the NewsGroup
>    comp.lang.java.help           2002-10-10 
>    By Jonas Lindström
>
>    Converted to Python
>    By Stanley C. Kitching
>'''
>
>import sys
>print '\n    Approximate  Pi  via Leibniz Sequence '
>
>def calculate_pi( nTerms ) :
>
>    limit = ( 2 * nTerms ) - 1 
>
>    if ( ( limit - 1 ) % 4 ) == 0 :  
>           sign = +1.0 
>    else : 
>           sign = -1.0
>
>    sum = 0.0
>
>    for i in range( limit , 0 , -2 ) : 
>        sum +=  sign / i
>        sign = -sign
>
>    return 4.0 * sum 
>
>nTerms = int( sys.argv[ 1 ] ) 
>
>Pi = calculate_pi( nTerms  )
>
>print '\n    Terms : ' , nTerms
>print '\n       Pi : ' , Pi
>
>
>  
>

-- 
_______________________________________
  Mike C. Fletcher
  Designer, VR Plumber, Coder
  http://members.rogers.com/mcfletch/







More information about the Python-list mailing list