Last active
August 29, 2015 14:17
-
-
Save cwfitzgerald/da28c63c570223bb4a29 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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