首页 > 解决方案 > 用于计算 Pi 的加速莱布尼茨级数

问题描述

当我学习数学时,我读到了名为 Leibniz Series for Pi 的系列:

所以我为它做了一个程序,总结了这个系列的 n 项:

def leibniz(n):
    pi = 0
    for i in range(1,n+1):
        if(i % 2 == 0):
            pi -= 1 / (2*i - 1)
        else:
            pi += 1/(2*i - 1)
    pi = 4 * pi
    return pi

这段代码有效,但问题是它收敛到 Pi 非常缓慢。

编辑:

我了解了香克斯变换并对其进行了编程

def accelrate(n,depth):
    if depth == 1:
        a = lebniez(n + 1)
        b = lebniez(n)
        c = lebniez(n-1)
        return (a*c - b*b)/(a + c - 2*b) 
    a = accelrate(n + 1,depth - 1)
    b = accelrate(n,depth - 1)
    c = accelrate(n-1,depth - 1)
    return (a*c - b*b)/(a + c - 2*b)

所以 htis 所做的是它递归地应用 Shanks 变换并继续加速系列。但是现在的问题是,由于递归,它非常慢,如果增加深度,精度并没有提高。

这就是香克斯转型的低效吗

标签: pythontrigonometrypiapproximationtaylor-series

解决方案


所以在考虑之后,我想出了在 My this shanks transformation 中减少缓存。

它并没有改善很多,但仍然是一个很好的改进。

这里是:

import functools as ft

@ft.lru_cache(maxsize=32)
def lebniez(n):
    pi = 0
    n = n + 1
    for i in range(1,n):
        if(i % 2 == 1):
            pi -= 1 / (2*i - 1)
        else:
            pi += 1/(2*i - 1)
    pi = abs(4 * pi)
    return pi

@ft.lru_cache(maxsize=128)
def accelrate(n,depth):
    if depth == 1:
        a = lebniez(n + 1)
        b = lebniez(n)
        c = lebniez(n-1)
    else:
        a = accelrate(n + 1,depth - 1)
        b = accelrate(n,depth - 1)
        c = accelrate(n-1,depth - 1)

    return (a*c - b*b)/(a + c - 2*b)

所以这个基础有助于使它更稳定。

接下来关于效率低下,原因是 Shanks 变换仅适用于这样的序列,其中 Error(n + 1) / Error(n) 的比率是一个常数。但是在再次应用 Shanks 变换后,这可能会导致效率低下


推荐阅读