1

n=迭代

由于某种原因,这段代码需要更多的迭代才能从其他代码中获得更准确的结果,谁能解释为什么会这样?谢谢。

    n,s,x=1000,1,0
    for i in range(0,n,2):
            x+=s*(1/(1+i))*4
            s=-s
    print(x)
4

2 回答 2

3

正如我在评论中提到的,加快此速度的唯一方法是转换序列。这是一个非常简单的方法,与欧拉变换有关(参见roippi 的链接):对于交替序列的总和,创建一个由每对连续部分和的平均值组成的新序列。例如,给定交替序列

a0 -a1 +a2 -a3 +a4 ...

其中所有as 都是正数,部分和的序列是:

s0=a0  s1=a0-a1  s2=a0-a1+a2  s3=a0-a1+a2-a3  s4=a0-a1+a2-a3+a4 ...

然后新的派生序列是:

(s0+s1)/2  (s1+s2)/2  (s2+s3)/2  (s3+s4)/2 ...

这通常可以更快地收敛——同样的想法也可以应用于这个序列。也就是说,创建另一个新序列,平均该序列的项。这可以无限期地进行。在这里,我将更上一层楼:

from math import pi

def leibniz():
    from itertools import count
    s, x = 1.0, 0.0
    for i in count(1, 2):
        x += 4.0*s/i
        s = -s
        yield x

def avg(seq):
    a = next(seq)
    while True:
        b = next(seq)
        yield (a + b) / 2.0
        a = b

base = leibniz()
d1 = avg(base)
d2 = avg(d1)
d3 = avg(d2)

for i in range(20):
    x = next(d3)
    print("{:.6f} {:8.4%}".format(x, (x - pi)/pi))

输出:

3.161905  0.6466%
3.136508 -0.1619%
3.143434  0.0586%
3.140770 -0.0262%
3.142014  0.0134%
3.141355 -0.0076%
3.141736  0.0046%
3.141501 -0.0029%
3.141654  0.0020%
3.141550 -0.0014%
3.141623  0.0010%
3.141570 -0.0007%
3.141610  0.0005%
3.141580 -0.0004%
3.141603  0.0003%
3.141585 -0.0003%
3.141599  0.0002%
3.141587 -0.0002%
3.141597  0.0001%
3.141589 -0.0001%

因此,仅在 20 个术语之后,我们已经将 pi 提高到大约 6 个有效数字。基本的莱布尼茨序列仍然是正确的大约 2 位数字:

>>> next(base)
3.099944032373808

这是一个巨大的进步。这里的一个关键点是基本莱布尼茨序列的部分和给出了在“太大”和“太小”之间交替的近似值。这就是为什么平均它们更接近真相。同样的(在“太大”和“太小”之间交替)也适用于派生序列,因此平均它们的项也有帮助。

当然,这一切都是徒劳的。严格的理由可能不是你感兴趣的东西;-)

于 2013-10-24T02:42:52.797 回答
2

那是因为您使用的是莱布尼茨级数,并且众所周知它会非常(非常)缓慢地收敛。

于 2013-10-23T19:12:12.987 回答