You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速Leibniz级数收敛以高效计算π?

基于Leibniz级数的π计算加速探索

背景

Leibniz级数是用于近似π的无穷级数,虽能收敛到π,但收敛速度极慢。我曾实现多种π计算函数,其中Ramanujan公式收敛效率最高,仅3次迭代就能得到15位正确小数。

之后尝试通过添加修正项加速Leibniz级数:

  • 1个修正项:2048次迭代时得到10位正确小数
  • 2个修正项:638次迭代时得到15位正确小数
  • 3个修正项:仅需131次迭代即可得到15位正确小数,但4个修正项会导致收敛变慢,154次迭代时出现下溢

我还实现了Euler变换、Aitken加速等收敛加速算法,但这些算法虽减少了所需项数,单步计算开销却大幅增加,导致总执行时间更长。

问题

寻求基于Leibniz级数维基页面的收敛加速方法及编程技巧,实现Leibniz级数计算π的加速,同时减少所需级数项数并降低执行时间。允许使用编译库,但禁止缓存等作弊手段。

相关代码及性能测试

import math
from itertools import cycle
from math import factorial


def Ramanujan(n):
    def term(k): return factorial(4 * k) * (1103 + 26390 * k) / \
        (factorial(k) ** 4 * 396 ** (4 * k))
    s = sum(term(i) for i in range(n))
    return 1 / (2 * 2 ** 0.5 * s / 9801)


sign = [1, -1]


def Leibniz_Series(n):
    return [1/i*s for i, s in zip(range(1, 2*n+1, 2), cycle(sign))]


def Leibniz_0(n):
    return 4 * sum(Leibniz_Series(n))


def Leibniz_1(n):
    correction = 1 / n*sign[n % 2]
    return Leibniz_0(n) + correction


def Leibniz_2(n):
    correction = 1 / (
        n + 1 / (
            4 * n
        )
    )*sign[n % 2]
    return Leibniz_0(n) + correction


def Leibniz_3(n):
    correction = 1 / (
        n + 1 / (
            4 * n + 4 / n
        )
    )*sign[n % 2]
    return Leibniz_0(n) + correction


def Leibniz_4(n):
    correction = 1 / (
        n + 1 / (
            4 * n + 4 / (
                n + 9 / n
            )
        )
    )*sign[n % 2]
    return Leibniz_0(n) + correction


def bincoeff(n, k):
    r = 1
    if (k > n):
        return 0
    for d in range(1, k + 1):
        r = r * n / d
        n -= 1
    return r


def abs(n):
    return n * (-1) ** (n < 0)


def Euler(arr):
    out = []

    for i in range(len(arr)):
        delta = 0
        for j in range(i + 1):
            coeff = bincoeff(i, j)
            delta += (-1) ** j * coeff * abs(arr[j])

        out.append(0.5 ** (i + 1) * delta)
    return out


def Leibniz_Euler(n):
    return 4 * sum(Euler(Leibniz_Series(n)))


def Leibniz_Aitken(n):
    series = Leibniz_Series(n)
    s0, s1, s2 = (sum(series[:n-i]) for i in (2, 1, 0))
    return 4 * (s2 * s0 - s1 * s1) / (s2 - 2*s1 + s0)


def LCP(s1, s2):
    i = 0
    for a, b in zip(s1, s2):
        if a != b:
            break
        i += 1
    return i


for func in (Ramanujan, Leibniz_Euler, Leibniz_Aitken, Leibniz_4, Leibniz_3, Leibniz_2, Leibniz_1, Leibniz_0):
    i = 12
    last = 0
    while (pi := func(i)) != math.pi:
        i += 1
        if i == 2048:
            if abs(pi - math.pi) <= 1e-6:
                print('计算结果接近π')
            else:
                print('方法收敛过慢')
            break
        if pi == last:
            print('浮点下溢')
            break
        last = pi
    print(
        f'函数: {func.__name__}, 迭代次数: {i}, 正确位数: {LCP(str(pi), str(math.pi))}')

性能测试输出

函数: Ramanujan, 迭代次数: 12, 正确位数: 17
浮点下溢
函数: Leibniz_Euler, 迭代次数: 52, 正确位数: 16
计算结果接近π
函数: Leibniz_Aitken, 迭代次数: 2048, 正确位数: 11
函数: Leibniz_4, 迭代次数: 154, 正确位数: 17
函数: Leibniz_3, 迭代次数: 131, 正确位数: 17
函数: Leibniz_2, 迭代次数: 638, 正确位数: 17
计算结果接近π
函数: Leibniz_1, 迭代次数: 2048, 正确位数: 12
方法收敛过慢
函数: Leibniz_0, 迭代次数: 2048, 正确位数: 4

执行时间测试

In [2]: %timeit Ramanujan(3)
每次循环3.7微秒 ± 229纳秒(7次运行,每次100000循环的均值±标准差)

In [3]: %timeit Leibniz_3(131)
每次循环17.4微秒 ± 123纳秒(7次运行,每次100000循环的均值±标准差)

In [4]: %timeit Leibniz_Aitken(2048)
每次循环295微秒 ± 10.8微秒(7次运行,每次1000循环的均值±标准差)

In [5]: %timeit Leibniz_Euler(52)
每次循环3.81毫秒 ± 430微秒(7次运行,每次100循环的均值±标准差)

内容的提问来源于stack exchange,提问作者Ξένη Γήινος

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:59:53