Last active
February 28, 2024 01:59
-
-
Save juliusgeo/dd1373df3a95b7cd3c543527f0d3d6a8 to your computer and use it in GitHub Desktop.
4 Ways to Calculate Pi
This file contains hidden or 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
from functools import reduce | |
from math import factorial, comb, ceil, log2 | |
from decimal import getcontext, Decimal as Dec | |
def bernoulli(n): | |
bs = [Dec(1)] | |
for m in range(1, n+1): | |
bs.append(1 - sum(comb(m, k)*b / (m - k + 1) for k, b in zip(range(m), bs))) | |
return abs(bs[-1]) | |
# Formula taken from Plouffe (2022): https://arxiv.org/abs/2201.12601 | |
def pi(n): | |
getcontext().prec = n | |
return (2*factorial(n)/((bernoulli(n))*2**n*reduce(Dec.__mul__, [1-(1/Dec(x)**n) for x in [2, 3, 5, 7]])))**(1/Dec(n)) | |
# Bailey–Borwein–Plouffe formula for reference. | |
def bbp(n): | |
getcontext().prec = n | |
return sum(1/Dec(16**k) * (4/Dec(8*k+1)-2/Dec(8*k+4)-1/Dec(8*k+5)-1/Dec(8*k+6)) for k in range(n)) | |
# Gauss-Legendre formula | |
def gauss_legendre(prec): | |
getcontext().prec = prec | |
half = Dec(1/2) | |
a = Dec(1) | |
b = Dec(a / Dec(2)**Dec(1/2)) | |
t = Dec(a / 4) | |
for x in map(lambda x: Dec(2**x), range(ceil(log2(prec)))): | |
y=a | |
a+=b | |
a*=half | |
t-=x*(y-a)**2 | |
b*=y | |
b **= half | |
return (a + b)**2 / (4 * t) | |
if __name__ == "__main__": | |
precision = 1000 | |
print(b := bbp(precision)) | |
print(c := gauss_legendre(precision)) | |
print(c := pi(precision)) | |
print(''.join(b:=open(__file__).readlines()[49:]).count("#")/len(b)/4) | |
####### | |
################# | |
#######--------######## | |
######-------------####### | |
######-----------------###### | |
#####------------------###### | |
######-------------------###### | |
#####--------------------###### | |
#####---------!\---------###### | |
######--------!$#\-------###### | |
######-------!#$#$#\---###### | |
######-------!#$#$##$#\##### | |
#######-----!$#$#$#$#$#\### | |
##########!$#$#$#$#$##\ | |
######!$#$#$### | |
##!#### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@LukePrior I was actually looking into that a month or so ago, but seem to have lost the code. For the Plouffe paper, it seems that individual digits are calculated by getting the value from the normal formula for all the digits (formula at the bottom of the second page). The hardest part about the Plouffe algorithm is that it requires relatively large bernoulli numbers, which are pretty computationally intense to calculate. There are other approaches to calculating the nth digit of pi, but they generally calculate the nth digit in some other base, like 16. It doesn't seem like there is currently an algorithm for the nth decimal digit of pi according to the internet: https://math.stackexchange.com/questions/4491628/is-there-a-formula-that-allows-you-calculate-the-n-th-decimal-digit-of-pi-withou