2 Convergence acceleration / extrapolation methods for series and
6 Carl M. Bender & Steven A. Orszag, "Advanced Mathematical Methods for
7 Scientists and Engineers: Asymptotic Methods and Perturbation Theory",
8 Springer 1999. (Shanks transformation: pp. 368-375, Richardson
9 extrapolation: pp. 375-377.)
12 from sympy
import Symbol
, factorial
, pi
, Integer
, E
, Sum2
15 def richardson(A
, k
, n
, N
):
17 Calculate an approximation for lim k->oo A(k) using Richardson
18 extrapolation with the terms A(n), A(n+1), ..., A(n+N+1).
19 Choosing N ~= 2*n often gives good results.
21 A simple example is to calculate exp(1) using the limit definition.
22 This limit converges slowly; n = 100 only produces two accurate
27 >>> print round(e.subs(n, 100).evalf(), 10)
30 Richardson extrapolation with 11 appropriately chosen terms gives
31 a value that is accurate to the indicated precision:
33 >>> print round(richardson(e, n, 10, 20).evalf(), 10)
35 >>> print round(E.evalf(), 10)
38 Another useful application is to speed up convergence of series.
39 Computing 100 terms of the zeta(2) series 1/k**2 yields only
42 >>> k = Symbol('k'); n = Symbol('n')
43 >>> A = Sum2(k**-2, (k, 1, n))
44 >>> print round(A.subs(n, 100).evalf(), 10)
47 Richardson extrapolation performs much better:
49 >>> print round(richardson(A, n, 10, 20).evalf(), 10)
51 >>> print round(((pi**2)/6).evalf(), 10) # Exact value
56 for j
in range(0, N
+1):
57 s
+= A
.subs(k
, Integer(n
+j
)) * (n
+j
)**N
* (-1)**(j
+N
) / \
58 (factorial(j
) * factorial(N
-j
))
62 def shanks(A
, k
, n
, m
=1):
64 Calculate an approximation for lim k->oo A(k) using the n-term Shanks
65 transformation S(A)(n). With m > 1, calculate the m-fold recursive
66 Shanks transformation S(S(...S(A)...))(n).
68 The Shanks transformation is useful for summing Taylor series that
69 converge slowly near a pole or singularity, e.g. for log(2):
73 >>> A = Sum2(Integer(-1)**(k+1) / k, (k, 1, n))
74 >>> print round(A.subs(n, 100).evalf(), 10)
76 >>> print round(shanks(A, n, 25).evalf(), 10)
78 >>> print round(shanks(A, n, 25, 5).evalf(), 10)
81 The correct value is 0.6931471805599453094172321215.
83 table
= [A
.subs(k
, Integer(j
)) for j
in range(n
+m
+2)]
86 for i
in range(1, m
+1):
87 for j
in range(i
, n
+m
+1):
88 x
, y
, z
= table
[j
-1], table
[j
], table
[j
+1]
89 table2
[j
] = (z
*x
- y
**2) / (z
+ x
- 2*y
)