My first Python program.. Calculating pi geometrically.

R

Ron Adam

Hi, I'm having fun learning Python and want to say thanks to everyone
here for a great programming language.

Below is my first Python program (not my first program) and I'd
apreciate any feedback on how I might do things differently to make it
either more consice, readable, or faster. ie... are there better ways
to do it in Python?

It won't break any records for calculating pi, that wasn't my goal,
learning Python was. But it might be good for testing floating point
and decimal performance. It also might make a good demo of the same.


Anyway, here it is, any feedback would be apreciated.

_Ron




"""
## Program name: pi10.py
## Author: Ronald R. Adam
## Version: 1.01
## Date: 11/01/2003
##
## Email: (e-mail address removed) or (e-mail address removed)
##
## This program calculates Pi using a geometric progression of
## triangles. The program is written in Python and requires
## the gmpy math module in order to use extended floating point
## precision.
##
## This is a rough diagram of the location of the points used.
##
## |
## A* --.__
## | \ `-._
## | \ `* D
## | \ / \
## | C * \
## | . \ \
## | . \ |
## | . \ |
## *---------------*---
## O B
##
## Pint C is the mid point of line AB.
## Point D is on the circle 90 degrees to line AB from point C.
##
## Area = OAB*4 + CDB*8 + ...
##
## ... Point A is relocated to point D and then new points
## C and D are calculated. This is repeated ...
##
## ... + CDB*16 + CDB*32 + ... (Repeats until done)
##
## When it's done, the last line of AB length multiplied by with
## the number of sides (2^n) is used to calculate the
## circumference, and then calculate pi again to check the result.
##
## Pi to 10,000 digits take about 5 minutes on my desktop computer.
## I'm not sure what the maximum is so drop me an email if you get
## some really long sequences. This program progrssivly slows down
## as the number of digits increases because it uses the entire
## length of each floating point number.
"""

import gmpy
import datetime
import time

print """
Pi10.py Version 1.0, by Ronald R. Adam

This program calculates Pi by using a geometric progression
of triangles to measure the area of a circle with a radius of 1.

"""

d=1
while d>0:

try:
d = gmpy.mpz(raw_input('Number of decimal digits: '))
except:
break

# Estimate the precision needed.
# This may need some adjustment.
p = int(d*3.325)+16 # gmpy precision value

start = time.clock()
t_old = start
print 'Calculating Pi ...'


# set variable values and precision.
n = gmpy.mpz('2') # number of triangles
radius = gmpy.mpf('1.0',p) # radius
area = gmpy.mpf((radius*radius)/2 * 2**n) #area=(base*height)/2*4
Ax, Ay = gmpy.mpf('0.0',p) , radius # point A
Bx, By = radius , gmpy.mpz('0') # point B
Cx = Cy = gmpy.mpf('0.0',p) # point C
OC = CD = CB = gmpy.mpf('0.0',p) # lines OC,CD,CB
vx = vy = gmpy.mpf('0.0',p) # vectors of line CD

# Loop until additions to area are too small to calculate
# using the requested precision + 2 digits.
p_area = gmpy.mpf('0.0',p)
while gmpy.fdigits(p_area,10,d+2) <> gmpy.fdigits(area,10,d+2):
p_area = area

Cx, Cy = (Ax+1)/2, Ay/2 # find midpoint of line AB
OC = gmpy.fsqrt(Cx**2 + Cy**2) # find length of line OC
CD = radius - OC # find length of line CD
CB = gmpy.fsqrt((Bx-Cx)**2+Cy**2) # find length of line CB
n += 1 # double triangles 2^(n+1)
area = area + (CB*CD/2) * 2**n # add trianges BCD * 2^n
vx = CD * Cx/OC # find x vector of line CD
vy = CD * Cy/OC # find y vector of line CD
Ax, Ay = Cx+vx, Cy+vy # Ax,Ay = Dx,Dy

t = time.clock()
if t > t_old+10:
t_old = t
print 'Exceeding 2^', n ,'sides ...'


# pi1 = area/radius^2
pi1 = gmpy.fdigits(area) # use (area/radius**2) if radius <>1
# pi2 = circumference /(2*radius)

pi2=gmpy.fdigits((gmpy.fsqrt((Bx-Ax)**2+(By-Ay)**2)*2**n)/(2*radius))

# Compare the two above calculations to each other
# and copy the matching & requested digits to the
# result string.
pi = ''
k = 0
while pi1[k] == pi2[k]:
pi = pi+pi1[k]
k += 1
pi = pi[0:int(d+2)]


# Report the result
print
print 'Pi =\n',pi
print
print len(pi)-2, 'decimal places'
print 'Radius =', radius
print '2^', n, ' sides'
stop = time.clock()
print 'Elapsed time:',datetime.timedelta( 0, stop-start)
print

# End #
 
R

Ron Adam

Hi, I'm having fun learning Python and want to say thanks to everyone
here for a great programming language.

Below is my first Python program (not my first program) and I'd
apreciate any feedback on how I might do things differently to make it
either more consice, readable, or faster. ie... are there better ways
to do it in Python?

It won't break any records for calculating pi, that wasn't my goal,
learning Python was. But it might be good for testing floating point
and decimal performance. It also might make a good demo of the same.


Anyway, here it is, any feedback would be apreciated.

_Ron


BTW, I do know I can do this and get pi much much faster.

That gives me over 300,000 decimal places in 2 to 3 minutes.

Which is very impressive. :)

Doing it geometrically was strictly a learning exercise. And I did
learn quite a bit by doing it.

_Ron
 
I

Irmen de Jong

Ron said:
Doing it geometrically was strictly a learning exercise. And I did
learn quite a bit by doing it.

And you only scratched the surface of what Python offers you :)
While it's nice to hear that you learned a lot by making this
arithmetic python program, it certainly is not the most
inspiring thing that Python is capable of...

I even think you learned more about calculating Pi than you
did about programming in Python ;-)

--Irmen
 
R

Ron Adam

And you only scratched the surface of what Python offers you :)
While it's nice to hear that you learned a lot by making this
arithmetic python program, it certainly is not the most
inspiring thing that Python is capable of...

I even think you learned more about calculating Pi than you
did about programming in Python ;-)

--Irmen

The challenging parts were, figuring out how to do the calculation
without using sin or cos, (nice geometry refresher), getting the gmpy
module to work and how to set the precision, and working out by trial
and error the precision calculation. If there is a formula to
convert digits of precision to bits of precision, I'd like to know.
And the last was to figure out how to use the clock and timedelta
functions.

Other interesting things I learned was how to convert to and from
stings, use slices, and for-in loops are very fast for small lists,
but can eat up a lot of memory, hit the swap file and be extremely
slow for large lists. For-in loops aren't suited for everything.

And yes, before I started, I did not know how to calculate pi. So you
are right about that. ;-) That was an interesting subject in it
self.

Overall, it was a very good learning project.

_Ron
 
G

GrayGeek

Ron said:
The challenging parts were, figuring out how to do the calculation
without using sin or cos, (nice geometry refresher), getting the gmpy
module to work and how to set the precision, and working out by trial
and error the precision calculation. If there is a formula to
convert digits of precision to bits of precision, I'd like to know.
And the last was to figure out how to use the clock and timedelta
functions.

Other interesting things I learned was how to convert to and from
stings, use slices, and for-in loops are very fast for small lists,
but can eat up a lot of memory, hit the swap file and be extremely
slow for large lists. For-in loops aren't suited for everything.

And yes, before I started, I did not know how to calculate pi. So you
are right about that. ;-) That was an interesting subject in it
self.

Overall, it was a very good learning project.

_Ron

As I recall, Ron, your method is the same one used by Archimedes when he
computed PI.
http://itech.fgcu.edu/faculty/clindsey/mhf4404/archimedes/archimedes.html
The method of diminishing triangles is SO similar to Gauss & Newton's
method of diminishing rectangles one wonders how much faster the scientific
advances of Man would have occurred if Archimedes had gone on to develop
Calculus.
 
R

Ron Adam

As I recall, Ron, your method is the same one used by Archimedes when he
computed PI.
http://itech.fgcu.edu/faculty/clindsey/mhf4404/archimedes/archimedes.html
The method of diminishing triangles is SO similar to Gauss & Newton's
method of diminishing rectangles one wonders how much faster the scientific
advances of Man would have occurred if Archimedes had gone on to develop
Calculus.

Yes, the concept is the same, but slightly different method. All
the examples I found used trig functions to do it with or used ratios
related to trig functions. I used vectors to get around that.

How much did calculus contributed to advances in mankind after it was
developed? I think other developments in production methods and
economics had a bigger impact and didn't require calculus.

Correction, a quick search found this....
http://www-gap.dcs.st-and.ac.uk/~history/HistTopics/The_rise_of_calculus.html

This shows calculus was developed over quite a long time in
conjunction with, and driven by developments in production, which in
turn were related to economics.

But 2,500 years is a long time ago and who knows what would have
happened? What would have happened if the telescope was invented
sooner? :)

Something interesting about gmpy accuracy is after calculating pi to
10,000 digits and displaying the entire floating point number, only
the last 4 digits are off due to rounding errors. I think that is
exceptional and only occasionally are the last 5 digits not correct.
I get around that by calculating at least 5 extra digits and then
truncating.

_Ron
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,060
Latest member
BuyKetozenseACV

Latest Threads

Top