Skip to content

Instantly share code, notes, and snippets.

@cwfitzgerald
Last active August 29, 2015 14:17
Show Gist options
  • Save cwfitzgerald/da28c63c570223bb4a29 to your computer and use it in GitHub Desktop.
Save cwfitzgerald/da28c63c570223bb4a29 to your computer and use it in GitHub Desktop.
import math,decimal, os, time, cProfile, multiprocessing
from decimal import Decimal as large
## Simple Libnitz forumla pi calculation SigFig=15
def additivecalc(nlim):
pi = float(0)
while n < xrange(nlim):
pi += float(((-1)**n)*4) / float(2*n + 1)
return pi
## Simple arctan convergence algorithm
def arctan1(z, nlim):
z = abs(z)
answer = large(0)
n=0
while n < nlim:
answer += (large((-1)**n) * (large(z)**large(2*n+1))) / large(2*n+1)
n+=1
return answer
def multiarctan(z, nlim,sigFig,debug):
pipeList = []
answerList = []
worker_list = []
threadCount = multiprocessing.cpu_count()
if debug:
print "prelaunch"
for w in xrange(threadCount):
parent_conn, child_conn = multiprocessing.Pipe(False)
p = multiprocessing.Process(target=arctan2, args=(z, nlim, child_conn, sigFig,w, threadCount,debug,), name="thread_%d" %w)
worker_list.append(p)
pipeList.append(parent_conn)
p.start()
if debug:
print "postlaunch"
for w in worker_list:
w.join()
if debug:
print "finished"
answer = large(0)
for a in xrange(threadCount):
answerList.append(pipeList[a].recv())
if debug:
print answerList[a]
for a in pipeList:
a.close()
for a in answerList:
answer += large(a)
return answer
## Much better arctan
def arctan2(z, nlim,anspipe, sigFig, threadNum, threadCount,debug):
decimal.getcontext().prec = sigFig
if z < 0:
neg = True
else:
neg = False
z = abs(large(z))
answer = large(0)
n=threadNum
if debug:
oppdone = []
while n < nlim:
# ------------------FRACTION #1---------------- ------------FRACTION #2------------
# ((2**(2*n))*(math.factorial(n)**2) / (2*n+1)) * ((z**(2*n+1)) / (1 + z**2)**(n+1)))
# ---------------------------------------------FRACTION #1--------------------------------------------- -----------------------------FRACTION #2--------------------------------
answer += ((large(2)**(large(2)*large(n)))*(large(math.factorial(n))**large(2)) / large(math.factorial(2*n+1))) * ((large(z)**large(2*n+1)) / (large(1) + large(z)**large(2))**large(n+1))
n+=threadCount
if debug:
oppdone.append(n)
if neg:
answer = large(0) - answer
if debug:
print "Thead number %i reporting with oppdone of %s" % (threadNum, str(oppdone))
anspipe.send(answer)
anspipe.close()
return
def arctanpi(nlim,sigFig,debug):
pi = large(0)
pi = large(4)*multiarctan(large(1)/large(5), nlim,sigFig, debug) - multiarctan(large(1)/large(239), nlim,sigFig, debug)
return pi * large(4)
if __name__ == '__main__':
# Choose method of calculation
method = -1
methodName = ""
while method not in [0,1,2]:
os.system('cls' if os.name == 'nt' else 'clear')
method = int(raw_input("Choose a pi method: (0 = Libnitz (additive), 1 = Gregory (arctan))\n"))
iterations = 0
sigFig = 0
debug = False
if method == 0:
iterations = 10**int(raw_input("\nHow many iterations? 10 to the X\n"))
methodName = "Libnitz (additive)"
if (method == 1) or (method == 2):
iterations = int(raw_input("\nHow many iterations?\n"))
methodName = "Gregory (arctan)"
sigFig = int(raw_input("\nHow many signifigant digits? (0 for default of %s)\n" % int(iterations*1.416)))
if sigFig == 0:
sigFig = int(iterations*1.416)
decimal.getcontext().prec = sigFig
if method == 2:
debug = True
checkEnd = -1
while checkEnd not in [0,1]:
checkEnd = int(raw_input("\nDo you want to check against a large pi file? (0 for false and 1 for true)\n"))
startTime = time.clock()
# global finalValue
finalValue = 0;
if method == 0:
finalValue = additivecalc(iterations)
if method == 1:
finalValue = arctanpi(iterations, sigFig, debug)
# End Timing
endTime = time.clock()
funcTime = endTime - startTime
# Check against a pi list.
correctDigits = "An unknown amount"
correctDigitsTotal = sigFig
if checkEnd == 1:
piListFile = open("pi.txt")
piListStrFull = piListFile.read()
piListStr = piListStrFull[0:sigFig+1]
piListFile.close()
piCalcStr = str(finalValue).replace('.', '')
n=0
correctDigitsTotal = 0
while n < len(piCalcStr):
if (int(piCalcStr[n]) == int(piListStr[n])):
correctDigitsTotal+=1
n+=1
else:
n+=1
break;
correctDigits = str(correctDigitsTotal)
print "\nPi is approxematly %s. It took roughly %f seconds using the %s method. %s of them are correct." % (str(finalValue)[0:int(correctDigitsTotal+1)], funcTime, methodName, correctDigits)
raw_input("Press enter to continue...")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment