Coverage for /usr/lib/python3/dist-packages/sympy/series/approximants.py: 12%
48 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1from sympy.core.singleton import S
2from sympy.core.symbol import Symbol
3from sympy.polys.polytools import lcm
4from sympy.utilities import public
6@public
7def approximants(l, X=Symbol('x'), simplify=False):
8 """
9 Return a generator for consecutive Pade approximants for a series.
10 It can also be used for computing the rational generating function of a
11 series when possible, since the last approximant returned by the generator
12 will be the generating function (if any).
14 Explanation
15 ===========
17 The input list can contain more complex expressions than integer or rational
18 numbers; symbols may also be involved in the computation. An example below
19 show how to compute the generating function of the whole Pascal triangle.
21 The generator can be asked to apply the sympy.simplify function on each
22 generated term, which will make the computation slower; however it may be
23 useful when symbols are involved in the expressions.
25 Examples
26 ========
28 >>> from sympy.series import approximants
29 >>> from sympy import lucas, fibonacci, symbols, binomial
30 >>> g = [lucas(k) for k in range(16)]
31 >>> [e for e in approximants(g)]
32 [2, -4/(x - 2), (5*x - 2)/(3*x - 1), (x - 2)/(x**2 + x - 1)]
34 >>> h = [fibonacci(k) for k in range(16)]
35 >>> [e for e in approximants(h)]
36 [x, -x/(x - 1), (x**2 - x)/(2*x - 1), -x/(x**2 + x - 1)]
38 >>> x, t = symbols("x,t")
39 >>> p=[sum(binomial(k,i)*x**i for i in range(k+1)) for k in range(16)]
40 >>> y = approximants(p, t)
41 >>> for k in range(3): print(next(y))
42 1
43 (x + 1)/((-x - 1)*(t*(x + 1) + (x + 1)/(-x - 1)))
44 nan
46 >>> y = approximants(p, t, simplify=True)
47 >>> for k in range(3): print(next(y))
48 1
49 -1/(t*(x + 1) - 1)
50 nan
52 See Also
53 ========
55 sympy.concrete.guess.guess_generating_function_rational
56 mpmath.pade
57 """
58 from sympy.simplify import simplify as simp
59 from sympy.simplify.radsimp import denom
60 p1, q1 = [S.One], [S.Zero]
61 p2, q2 = [S.Zero], [S.One]
62 while len(l):
63 b = 0
64 while l[b]==0:
65 b += 1
66 if b == len(l):
67 return
68 m = [S.One/l[b]]
69 for k in range(b+1, len(l)):
70 s = 0
71 for j in range(b, k):
72 s -= l[j+1] * m[b-j-1]
73 m.append(s/l[b])
74 l = m
75 a, l[0] = l[0], 0
76 p = [0] * max(len(p2), b+len(p1))
77 q = [0] * max(len(q2), b+len(q1))
78 for k in range(len(p2)):
79 p[k] = a*p2[k]
80 for k in range(b, b+len(p1)):
81 p[k] += p1[k-b]
82 for k in range(len(q2)):
83 q[k] = a*q2[k]
84 for k in range(b, b+len(q1)):
85 q[k] += q1[k-b]
86 while p[-1]==0: p.pop()
87 while q[-1]==0: q.pop()
88 p1, p2 = p2, p
89 q1, q2 = q2, q
91 # yield result
92 c = 1
93 for x in p:
94 c = lcm(c, denom(x))
95 for x in q:
96 c = lcm(c, denom(x))
97 out = ( sum(c*e*X**k for k, e in enumerate(p))
98 / sum(c*e*X**k for k, e in enumerate(q)) )
99 if simplify:
100 yield(simp(out))
101 else:
102 yield out
103 return