K i% :dZddlmZddlmZddlmZdZddZy) aB Convergence acceleration / extrapolation methods for series and sequences. References: Carl M. Bender & Steven A. Orszag, "Advanced Mathematical Methods for Scientists and Engineers: Asymptotic Methods and Perturbation Theory", Springer 1999. (Shanks transformation: pp. 368-375, Richardson extrapolation: pp. 375-377.) )Integer)S) factorialc "tj}td|dzD]l}||j|t ||zj ||z|zztj ||zzzt|t||z zz z }n|S)a Calculate an approximation for lim k->oo A(k) using Richardson extrapolation with the terms A(n), A(n+1), ..., A(n+N+1). Choosing N ~= 2*n often gives good results. Examples ======== A simple example is to calculate exp(1) using the limit definition. This limit converges slowly; n = 100 only produces two accurate digits: >>> from sympy.abc import n >>> e = (1 + 1/n)**n >>> print(round(e.subs(n, 100).evalf(), 10)) 2.7048138294 Richardson extrapolation with 11 appropriately chosen terms gives a value that is accurate to the indicated precision: >>> from sympy import E >>> from sympy.series.acceleration import richardson >>> print(round(richardson(e, n, 10, 20).evalf(), 10)) 2.7182818285 >>> print(round(E.evalf(), 10)) 2.7182818285 Another useful application is to speed up convergence of series. Computing 100 terms of the zeta(2) series 1/k**2 yields only two accurate digits: >>> from sympy.abc import k, n >>> from sympy import Sum >>> A = Sum(k**-2, (k, 1, n)) >>> print(round(A.subs(n, 100).evalf(), 10)) 1.6349839002 Richardson extrapolation performs much better: >>> from sympy import pi >>> print(round(richardson(A, n, 10, 20).evalf(), 10)) 1.6449340668 >>> print(round(((pi**2)/6).evalf(), 10)) # Exact value 1.6449340668 r)rZerorangesubsrdoit NegativeOner)AknNsjs _/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/series/acceleration.py richardsonrs^ A 1a!e_J affQA',,.!a%!;mma!e$%(1! yQ7G(GI JJ Hc t||zdzDcgc]+}|j|t|j-}}|j }td|dzD]X}t|||zdzD]1}||dz ||||dz} } }| |z| dzz | |zd| zz z ||<3|j }Z||Scc}w)a7 Calculate an approximation for lim k->oo A(k) using the n-term Shanks transformation S(A)(n). With m > 1, calculate the m-fold recursive Shanks transformation S(S(...S(A)...))(n). The Shanks transformation is useful for summing Taylor series that converge slowly near a pole or singularity, e.g. for log(2): >>> from sympy.abc import k, n >>> from sympy import Sum, Integer >>> from sympy.series.acceleration import shanks >>> A = Sum(Integer(-1)**(k+1) / k, (k, 1, n)) >>> print(round(A.subs(n, 100).doit().evalf(), 10)) 0.6881721793 >>> print(round(shanks(A, n, 25).evalf(), 10)) 0.6931396564 >>> print(round(shanks(A, n, 25, 5).evalf(), 10)) 0.6931471806 The correct value is 0.6931471805599453094172321215. r)r r rr copy) r rrmrtabletable2ixyzs rshanksr Gs,49Q3C DaQVVAwqz " ' ' ) DE D ZZ\F 1a!e_q!a%!)$ 5AAElE!HeAEl!qA1q!tA! 4F1I 5   8O Es0CN)r) __doc__sympy.core.numbersrsympy.core.singletonr(sympy.functions.combinatorial.factorialsrrr rrr&s  '">3 lr