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

1from sympy.core.singleton import S 

2from sympy.core.symbol import Symbol 

3from sympy.polys.polytools import lcm 

4from sympy.utilities import public 

5 

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). 

13 

14 Explanation 

15 =========== 

16 

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. 

20 

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. 

24 

25 Examples 

26 ======== 

27 

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)] 

33 

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)] 

37 

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 

45 

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 

51 

52 See Also 

53 ======== 

54 

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 

90 

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