Algorithme de Chudnovski

De testwiki
Aller à la navigation Aller à la recherche

Modèle:Voir homonymes

L' algorithme de Chudnovsky est une méthode rapide pour calculer les chiffres de π, basée sur les formules de π de Ramanujan. Il a été publié par les frères Chudnovsky en 1988.

Il a été utilisé pour le calcul du record mondial de Modèle:Nombre de chiffres de π en décembre 2009, Modèle:Nombre de chiffres en octobre 2011, Modèle:Nombre de chiffres en novembre 2016[1], Modèle:Nombre de chiffres en septembre 2018. – janvier 2019[2]Modèle:Nombre de chiffres le 29 janvier 2020[3]Modèle:Nombre de chiffres le 14 août 2021[4], Modèle:Nombre de chiffres le 21 mars 2022[5], et Modèle:Nombre de chiffres le 14 mars 2024[6].

Algorithme

L'algorithme est basé sur l'opposé du nombre de Heegner d=163, la fonction j j(1+i1632)=6403203, et sur la série hypergéométrique généralisée à convergence rapide ci-dessous: 1π=12k=0(1)k(6k)!(545140134k+13591409)(3k)!(k!)3(640320)3k+3/2Une preuve détaillée de cette formule peut être trouvée ici[7] :

Cette identité est similaire à certaines formules de Ramanujan impliquant π, et est un exemple de série Ramanujan-Sato.

La complexité temporelle de l'algorithme est en O(n(logn)3)[8].

Optimisations

La technique d'optimisation utilisée pour les calculs du record du monde est appelée division binaire.

Fractionnement binaire

Un facteur de 1/6403203/2 peut être retiré de la somme et simplifié en1π=142688010005k=0(1)k(6k)!(545140134k+13591409)(3k)!(k!)3(640320)3k

Soit f(n)=(1)n(6n)!(3n)!(n!)3(640320)3n, et en substituant dans la somme.1π=142688010005k=0f(k)(545140134k+13591409)f(n)f(n1) peut être simplifié en (6n1)(2n1)(6n5)10939058860032000n3, doncf(n)=f(n1)(6n1)(2n1)(6n5)10939058860032000n3f(0)=1 par définition de f, doncf(n)=j=1n(6j1)(2j1)(6j5)10939058860032000j3Cette définition de f n'est pas défini pour n=0, on calcule donc le premier terme de la somme et l'ajoute à la nouvelle définition de f en partant de n=11π=142688010005(13591409+k=1(j=1k(6j1)(2j1)(6j5)10939058860032000j3)(545140134k+13591409))Soit P(a,b)=j=ab1(6j1)(2j1)(6j5) et Q(a,b)=j=ab110939058860032000j3, donc1π=142688010005(13591409+k=1P(1,k+1)Q(1,k+1)(545140134k+13591409))Soit S(a,b)=k=ab1P(a,k+1)Q(a,k+1)(545140134k+13591409) et R(a,b)=Q(a,b)S(a,b)π=4268801000513591409+S(1,)S(1,) est une limite qui ne peut être qu'approché, on calcule à la place S(1,n) et lorsque n se rapproches de , l'approximation de π l'approximation s'améliore.π4268801000513591409+S(1,n)Par définition originale de R, S(a,b)=R(a,b)Q(a,b)π42688010005Q(1,n)13591409Q(1,n)+R(1,n)

Calcul récursif des fonctions

  • P(a,b)=P(a,m)P(m,b)
  • Q(a,b)=Q(a,m)Q(m,b)
  • S(a,b)=S(a,m)+P(a,m)Q(a,m)S(m,b)
  • R(a,b)=Q(m,b)R(a,m)+P(a,m)R(m,b)

Construction de la récursion

Si b=a+1

  • P(a,a+1)=(6a1)(2a1)(6a5)
  • Q(a,a+1)=10939058860032000a3
  • S(a,a+1)=P(a,a+1)Q(a,a+1)(545140134a+13591409)
  • R(a,a+1)=P(a,a+1)(545140134a+13591409)

Code Python

import decimal

def binary_split(a, b):
    if b == a + 1:
        Pab = -(6*a - 5)*(2*a - 1)*(6*a - 1)
        Qab = 10939058860032000 * a**3
        Rab = Pab * (545140134*a + 13591409)
    else:
        m = (a + b) // 2
        Pam, Qam, Ram = binary_split(a, m)
        Pmb, Qmb, Rmb = binary_split(m, b)
        
        Pab = Pam * Pmb
        Qab = Qam * Qmb
        Rab = Qmb * Ram + Pam * Rmb
    return Pab, Qab, Rab

def chudnovsky(n):
    """Chudnovsky algorithm."""
    P1n, Q1n, R1n = binary_split(1, n)
    return (426880 * decimal.Decimal(10005).sqrt() * Q1n) / (13591409*Q1n + R1n)

print(chudnovsky(2))  # 3.141592653589793238462643384

decimal.getcontext().prec = 100
for n in range(2,10):
    print(f"{n=} {chudnovsky(n)}")  # 3.14159265358979323846264338...

Remarques

eπ1636403203+743.99999999999925
6403203/24=10939058860032000
545140134=16312719117322
13591409=131045493

Voir aussi

Références

Modèle:Traduction/Référence Modèle:Références

Modèle:Portail