2

我正在做一个练习,要求一个使用莱布尼茨公式逼近 pi 值的函数。这些是维基百科上的解释:

在此处输入图像描述

在此处输入图像描述

逻辑思维对我来说很容易,但我没有接受过太多正规的数学教育,所以我对第二个最左边的符号代表什么有点迷茫。我尝试编写代码pi = ( (-1)**n / (2*n + 1) ) * 4,但返回1.9999990000005e-06的不是 3.14159...,所以我使用了累加器模式(因为指南中的章节也提到了它们)并且效果很好。但是,我不禁认为它有点做作,并且可能有更好的方法来做到这一点,因为 Python 专注于简单性和使程序尽可能短。这是完整的代码:

def myPi(n):
    denominator = 1
    addto = 1

    for i in range(n):
        denominator = denominator + 2
        addto = addto - (1/denominator)
        denominator = denominator + 2
        addto = addto + (1/denominator)

    pi = addto * 4

    return(pi)

print(myPi(1000000))

有谁知道更好的功能?

4

7 回答 7

6

Leibniz 公式直接转换成 Python,没有任何麻烦或大惊小怪:

>>> steps = 1000000
>>> sum((-1.0)**n / (2.0*n+1.0) for n in reversed(range(steps))) * 4
3.1415916535897934
于 2013-08-03T21:08:00.723 回答
3

这里的大写 sigma 是sigma 表示法。它是用来表示简明形式的总和的符号。

所以你的总和实际上是一个无限的总和。第一项,对于 n=0,是:

(-1)**0/(2*0+1)

这被添加到

(-1)**1/(2*1+1)

然后到

(-1)**2/(2*2+1)

以此类推。求和在数学上称为收敛和

在 Python 中,你会这样写:

def estimate_pi(terms):
    result = 0.0
    for n in range(terms):
        result += (-1.0)**n/(2.0*n+1.0)
    return 4*result

如果你想稍微优化一下,你可以避免取幂。

def estimate_pi(terms):
    result = 0.0
    sign = 1.0
    for n in range(terms):
        result += sign/(2.0*n+1.0)
        sign = -sign
    return 4*result

....

>>> estimate_pi(100)
3.1315929035585537
>>> estimate_pi(1000)
3.140592653839794
于 2013-08-03T19:36:35.537 回答
1

使用纯 Python,您可以执行以下操作:

def term(n):
    return ( (-1.)**n / (2.*n + 1.) )*4.

def pi(nterms):
    return sum(map(term,range(nterms)))

然后计算pi达到给定精度所需的项数:

pi(100)
# 3.13159290356

pi(1000)
# 3.14059265384
于 2013-08-03T19:34:40.690 回答
0

以下版本使用此SO 帖子中概述的 Ramanujan 公式 - 如本文所述,它使用 pi 和“怪物组”之间的关系。

import math

def Pi(x):
    Pi = 0
    Add = 0
    for i in range(x):
        Add =(math.factorial(4*i) * (1103 + 26390*i))/(((math.factorial(i))**4)*(396**(4*i)))
        Pi = Pi + (((math.sqrt(8))/(9801))*Add)
    Pi = 1/Pi
    print(Pi)

Pi(100)
于 2018-01-29T18:58:47.027 回答
0

这是我的方法:

def estPi(terms):
    outPut = 0.0
    for i in range (1, (2 * terms), 4):
        outPut = (outPut + (1/i) - (1/(i+2)))
    return 4 * outPut

我考虑了用户想要的术语数量,然后在 for 循环中我将其加倍以仅考虑使用赔率。

at 100 terms I get        3.1315929035585537
at 1000 terms I get       3.140592653839794
at 10000 terms I get      3.1414926535900345
at 100000 terms I get     3.1415826535897198
at 1000000 terms I get    3.1415916535897743
at 10000000 terms I get   3.1415925535897915
at 100000000 terms I get  3.141592643589326
at 1000000000 terms I get 3.1415926525880504
Actual Pi is              3.1415926535897932

不得不爱一个收敛的系列。

于 2018-11-12T18:35:26.297 回答
0
def myPi(iters):
    pi = 0
    sign = 1
    denominator = 1

    for i in range(iters):
        pi = pi + (sign/denominator)
        # alternating between negative and positive
        sign = sign * -1
        denominator = denominator + 2

    pi = pi * 4.0
    return pi

pi_approx = myPi(10000)
print(pi_approx)
于 2019-09-27T07:28:28.490 回答
0

旧线程,但我想解决这个问题,巧合的是,我想出了与 user3220980 几乎相同的东西

# gregory-leibnitz
# pi acurate to 8 dp in around 80 sec
# pi to 5 dp in .06 seconds
import time
start_time = time.time()

pi = 4 # start at 4
times = 100000000

for i in range(3,times,4):
        pi -= (4/i) + (4/(i + 2))
    
print(pi)
print("{} seconds".format(time.time() - start_time))
于 2020-07-04T13:25:19.677 回答