我正在尝试使用Euler的方法之一在Python中定义一个近似pi
的函数。他的公式如下:
到目前为止,我的代码是:
def pi_euler1(n):
numerator = list(range(2 , n))
for i in numerator:
j = 2
while i * j <= numerator[-1]:
if i * j in numerator:
numerator.remove(i * j)
j += 1
for k in numerator:
if (k + 1) % 4 == 0:
denominator = k + 1
else:
denominator = k - 1
#Because all primes are odd, both numbers inbetween them are divisible by 2,
#and by extension 1 of the 2 numbers is divisible by 4
term = numerator / denominator
我知道这是错误的,并且也不完整。我只是不太确定我前面提到的 TypeError 到底是什么意思。我对此非常了解,我想创建一个术语列表,然后找到他们的产品。我在正确的路线上吗?
更新: 我已经解决了这一问题,修复了由于msconi和Johanc而普遍存在的明显错误,现在使用了以下代码:
import math
def pi_euler1(n):
numerator = list(range(2 , 13 + math.ceil(n*(math.log(n)+math.log(math.log(n))))))
denominator=[]
for i in numerator:
j = 2
while i * j <= numerator[-1]:
if (i * j) in numerator:
numerator.remove(i * j)
j += 1
numerator.remove(2)
for k in numerator:
if (k + 1) % 4 == 0:
denominator.append(k+1)
else:
denominator.append(k-1)
a=1
for i in range(n):
a *= numerator[i] / denominator[i]
return 4*a
这似乎可行,当我尝试以符号学轴比例绘制pi的误差图时,我遇到了域误差,但是我需要将范围的上限更改为n + 1,因为log (0)未定义。谢谢你们
答案 0 :(得分:0)
在term = numerator / denominator
中,您将列表除以数字,这没有意义。将k
除以循环中的分母,以便将numerator
分别用于每个方程式的因数。然后,您可以将它们重复乘以术语term *= i / denominator
,并在开头将其初始化为term = 1
。
另一个问题是第一个循环,它不会为您提供第一个n
质数。例如,对于n=3
,list(range(2 , n)) = [2]
。因此,您将获得的唯一素数是2。
答案 1 :(得分:0)
下面是进行一些小的修改以使其正常工作的代码:
import math
def pi_euler1(n):
lim = n * n + 4
numerator = list(range(3, lim, 2))
for i in numerator:
j = 3
while i * j <= numerator[-1]:
if i * j in numerator:
numerator.remove(i * j)
j += 2
euler_product = 1
for k in numerator[:n]:
if (k + 1) % 4 == 0:
denominator = k + 1
else:
denominator = k - 1
factor = k / denominator
euler_product *= factor
return euler_product * 4
print(pi_euler1(3))
print(pi_euler1(10000))
print(math.pi)
输出:
3.28125
3.148427801913721
3.141592653589793
备注:
j
可以以3
开头,并以2的步长递增。实际上,j
可以以i
开头,因为i
的所有倍数都较小比i*i
早已被删除。n
解释为最高质数的限制,而实际上n
应该是质数。我修改了代码以纠正这一点。在上述版本中,有粗略的限制;下面的版本尝试更严格地限制。这是经过重新设计的版本,没有从要迭代的列表中删除。而不是删除元素,它只是标记它们。这要快得多,因此可以在合理的时间内使用较大的n
:
import math
def pi_euler_v3(n):
if n < 3:
lim = 6
else:
lim = n*n
while lim / math.log(lim) / 2 > n:
lim //= 2
print(n, lim)
numerator = list(range(3, lim, 2))
odd_primes = []
for i in numerator:
if i is not None:
odd_primes.append(i)
if len(odd_primes) >= n:
break
j = i
while i * j < lim:
numerator[(i*j-3) // 2] = None
j += 2
if len(odd_primes) != n:
print(f"Wrong limit calculation, only {len(odd_primes)} primes instead of {n}")
euler_product = 1
for k in odd_primes:
denominator = k + 1 if k % 4 == 3 else k - 1
euler_product *= k / denominator
return euler_product * 4
print(pi_euler_v2(100000))
print(math.pi)
输出:
3.141752253548891
3.141592653589793