使用 2 种理论计算 pi 以收敛到 pi 的逻辑解决方案

Logical solution for using 2 theories calculating pi, to converge to pi

这是编程课程的任务。我们需要使用 2 个不同的函数来近似 π。 1 使用 Gregory-Leibniz 理论,Sangamagrama 的另一个 Madhava。这两个都没有问题,但是第三个功能给我带来了一些麻烦。 :

检查两个序列中哪个序列收敛最快。用这个序列写一个函数approach_pi。此函数应允许确定 π 的逼近值,精确到 n 小数位。值 n 应作为函数的参数给出。要确定方法的准确性,您应该检查序列中两个连续的 terms 之间的差异是否小于 10^-n-1。当第 (i-1)th 项与第 i-th 项之差小于 10^-n-1 时,第 i- th 部分和形成了 π 精确到 (n) 小数的方法。该函数应给出元组 (i, p) 作为结果,i 是计算项的数量,nπ的逼近值。

以下部分是我的代码:

def GL(n):
    a, pi, flag = 1, 0, True
    while a <= (n*2-1):
        if flag:
            pi += (4/a)
        else:
            pi -= (4/a)
        flag = not flag
        a += 2
    return pi


def MvS(n):
    flag, a, parentheses, i = True, 3, 1, 1
    while a <= (n*2-1):
        if flag:
            parentheses -= (1/(a*3**i))
        else:
            parentheses += (1/(a*3**i))
        i += 1
        a += 2
        flag = not flag
    return math.sqrt(12)*parentheses


def approach_pi(n):
    counter_GL, counter_MvS, i = 0, 0, 2
    while 10**(-n-1) > GL(i-1) - GL(i) > (-10**(-n-1)):
        counter_GL += 1
        i += 1
    i = 2
    while 10**(-n-1) > MvS(i-1) - MvS(i) > (-10**(-n-1)):
        counter_MvS += 1
        i += 1

    return counter_GL, counter_MvS, GL(i)


x = int(input("give n : "))
print(approach_pi(x))

我知道最后一个函数根本不正确,但我没有想法。有人可以向我解释这个问题的正确原因吗?

一些示例解决方案是: approach_pi(3): (10, 3.14159051093808) approach_pi(2): (8, 3.141568715941784) approach_pi(6): (16, 3.1415926517339976)

如果您将函数构建为生成器,这将变得更加高效,因此您不必每次都重新运行整个序列。

计算接近度只是 if abs(this - lastthis) < epsilon.

的问题

这似乎行得通,它显示了 Gregory-Leibniz 方法有多么糟糕:

import math

def GL():
    a, pi, flag = 1, 0, True
    while True:
        if flag:
            pi += (4/a)
        else:
            pi -= (4/a)
        flag = not flag
        a += 2
        yield pi

def MvS():
    flag, a, parentheses, i = True, 3, 1, 1
    yield 3
    while True:
        if flag:
            parentheses -= (1/(a*3**i))
        else:
            parentheses += (1/(a*3**i))
        i += 1
        a += 2
        flag = not flag
        yield math.sqrt(12)*parentheses


def approach_pi(n):
    epsilon = 10**(-n)
    oldg = 0
    oldm = 0
    for i,gm in enumerate(zip(GL(), MvS())):
        g,m = gm
        print(i,g,m)
        if abs(g-oldg) < epsilon:
            print( "GL converges at step", i )
            return i+1,g
        if abs(m-oldm) < epsilon:
            print( "MvS converges at step", i )
            return i+1,m
        oldg,oldm = g,m


approach_pi(6)

您可以通过展开循环来消除“旗帜”:

import math

def GL():
    a, pi = 1, 0
    while True:
        pi += (4/a)
        a += 2
        yield pi
        pi -= (4/a)
        a += 2
        yield pi

def MvS():
    parentheses, a, denom = 1, 3, 3
    yield 3
    while True:
        parentheses -= (1/(a*denom))
        a += 2
        denom *= -3
        yield math.sqrt(12)*parentheses


def approach_pi(n):
    epsilon = 10**(-n)
    oldg = 0
    oldm = 0
    for i,gm in enumerate(zip(GL(), MvS())):
        g,m = gm
        print(i,g,m)
        if abs(g-oldg) < epsilon:
            print( "GL converges at step", i )
            return i+1,g
        if abs(m-oldm) < epsilon:
            print( "MvS converges at step", i )
            return i+1,m
        oldg,oldm = g,m


approach_pi(6)