formal.py 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870
  1. """Formal Power Series"""
  2. from collections import defaultdict
  3. from sympy.core.numbers import (nan, oo, zoo)
  4. from sympy.core.add import Add
  5. from sympy.core.expr import Expr
  6. from sympy.core.function import Derivative, Function, expand
  7. from sympy.core.mul import Mul
  8. from sympy.core.numbers import Rational
  9. from sympy.core.relational import Eq
  10. from sympy.sets.sets import Interval
  11. from sympy.core.singleton import S
  12. from sympy.core.symbol import Wild, Dummy, symbols, Symbol
  13. from sympy.core.sympify import sympify
  14. from sympy.discrete.convolutions import convolution
  15. from sympy.functions.combinatorial.factorials import binomial, factorial, rf
  16. from sympy.functions.combinatorial.numbers import bell
  17. from sympy.functions.elementary.integers import floor, frac, ceiling
  18. from sympy.functions.elementary.miscellaneous import Min, Max
  19. from sympy.functions.elementary.piecewise import Piecewise
  20. from sympy.series.limits import Limit
  21. from sympy.series.order import Order
  22. from sympy.simplify.powsimp import powsimp
  23. from sympy.series.sequences import sequence
  24. from sympy.series.series_class import SeriesBase
  25. from sympy.utilities.iterables import iterable
  26. def rational_algorithm(f, x, k, order=4, full=False):
  27. """
  28. Rational algorithm for computing
  29. formula of coefficients of Formal Power Series
  30. of a function.
  31. Explanation
  32. ===========
  33. Applicable when f(x) or some derivative of f(x)
  34. is a rational function in x.
  35. :func:`rational_algorithm` uses :func:`~.apart` function for partial fraction
  36. decomposition. :func:`~.apart` by default uses 'undetermined coefficients
  37. method'. By setting ``full=True``, 'Bronstein's algorithm' can be used
  38. instead.
  39. Looks for derivative of a function up to 4'th order (by default).
  40. This can be overridden using order option.
  41. Parameters
  42. ==========
  43. x : Symbol
  44. order : int, optional
  45. Order of the derivative of ``f``, Default is 4.
  46. full : bool
  47. Returns
  48. =======
  49. formula : Expr
  50. ind : Expr
  51. Independent terms.
  52. order : int
  53. full : bool
  54. Examples
  55. ========
  56. >>> from sympy import log, atan
  57. >>> from sympy.series.formal import rational_algorithm as ra
  58. >>> from sympy.abc import x, k
  59. >>> ra(1 / (1 - x), x, k)
  60. (1, 0, 0)
  61. >>> ra(log(1 + x), x, k)
  62. (-1/((-1)**k*k), 0, 1)
  63. >>> ra(atan(x), x, k, full=True)
  64. ((-I/(2*(-I)**k) + I/(2*I**k))/k, 0, 1)
  65. Notes
  66. =====
  67. By setting ``full=True``, range of admissible functions to be solved using
  68. ``rational_algorithm`` can be increased. This option should be used
  69. carefully as it can significantly slow down the computation as ``doit`` is
  70. performed on the :class:`~.RootSum` object returned by the :func:`~.apart`
  71. function. Use ``full=False`` whenever possible.
  72. See Also
  73. ========
  74. sympy.polys.partfrac.apart
  75. References
  76. ==========
  77. .. [1] Formal Power Series - Dominik Gruntz, Wolfram Koepf
  78. .. [2] Power Series in Computer Algebra - Wolfram Koepf
  79. """
  80. from sympy.polys import RootSum, apart
  81. from sympy.integrals import integrate
  82. diff = f
  83. ds = [] # list of diff
  84. for i in range(order + 1):
  85. if i:
  86. diff = diff.diff(x)
  87. if diff.is_rational_function(x):
  88. coeff, sep = S.Zero, S.Zero
  89. terms = apart(diff, x, full=full)
  90. if terms.has(RootSum):
  91. terms = terms.doit()
  92. for t in Add.make_args(terms):
  93. num, den = t.as_numer_denom()
  94. if not den.has(x):
  95. sep += t
  96. else:
  97. if isinstance(den, Mul):
  98. # m*(n*x - a)**j -> (n*x - a)**j
  99. ind = den.as_independent(x)
  100. den = ind[1]
  101. num /= ind[0]
  102. # (n*x - a)**j -> (x - b)
  103. den, j = den.as_base_exp()
  104. a, xterm = den.as_coeff_add(x)
  105. # term -> m/x**n
  106. if not a:
  107. sep += t
  108. continue
  109. xc = xterm[0].coeff(x)
  110. a /= -xc
  111. num /= xc**j
  112. ak = ((-1)**j * num *
  113. binomial(j + k - 1, k).rewrite(factorial) /
  114. a**(j + k))
  115. coeff += ak
  116. # Hacky, better way?
  117. if coeff.is_zero:
  118. return None
  119. if (coeff.has(x) or coeff.has(zoo) or coeff.has(oo) or
  120. coeff.has(nan)):
  121. return None
  122. for j in range(i):
  123. coeff = (coeff / (k + j + 1))
  124. sep = integrate(sep, x)
  125. sep += (ds.pop() - sep).limit(x, 0) # constant of integration
  126. return (coeff.subs(k, k - i), sep, i)
  127. else:
  128. ds.append(diff)
  129. return None
  130. def rational_independent(terms, x):
  131. """
  132. Returns a list of all the rationally independent terms.
  133. Examples
  134. ========
  135. >>> from sympy import sin, cos
  136. >>> from sympy.series.formal import rational_independent
  137. >>> from sympy.abc import x
  138. >>> rational_independent([cos(x), sin(x)], x)
  139. [cos(x), sin(x)]
  140. >>> rational_independent([x**2, sin(x), x*sin(x), x**3], x)
  141. [x**3 + x**2, x*sin(x) + sin(x)]
  142. """
  143. if not terms:
  144. return []
  145. ind = terms[0:1]
  146. for t in terms[1:]:
  147. n = t.as_independent(x)[1]
  148. for i, term in enumerate(ind):
  149. d = term.as_independent(x)[1]
  150. q = (n / d).cancel()
  151. if q.is_rational_function(x):
  152. ind[i] += t
  153. break
  154. else:
  155. ind.append(t)
  156. return ind
  157. def simpleDE(f, x, g, order=4):
  158. r"""
  159. Generates simple DE.
  160. Explanation
  161. ===========
  162. DE is of the form
  163. .. math::
  164. f^k(x) + \sum\limits_{j=0}^{k-1} A_j f^j(x) = 0
  165. where :math:`A_j` should be rational function in x.
  166. Generates DE's upto order 4 (default). DE's can also have free parameters.
  167. By increasing order, higher order DE's can be found.
  168. Yields a tuple of (DE, order).
  169. """
  170. from sympy.solvers.solveset import linsolve
  171. a = symbols('a:%d' % (order))
  172. def _makeDE(k):
  173. eq = f.diff(x, k) + Add(*[a[i]*f.diff(x, i) for i in range(0, k)])
  174. DE = g(x).diff(x, k) + Add(*[a[i]*g(x).diff(x, i) for i in range(0, k)])
  175. return eq, DE
  176. found = False
  177. for k in range(1, order + 1):
  178. eq, DE = _makeDE(k)
  179. eq = eq.expand()
  180. terms = eq.as_ordered_terms()
  181. ind = rational_independent(terms, x)
  182. if found or len(ind) == k:
  183. sol = dict(zip(a, (i for s in linsolve(ind, a[:k]) for i in s)))
  184. if sol:
  185. found = True
  186. DE = DE.subs(sol)
  187. DE = DE.as_numer_denom()[0]
  188. DE = DE.factor().as_coeff_mul(Derivative)[1][0]
  189. yield DE.collect(Derivative(g(x))), k
  190. def exp_re(DE, r, k):
  191. """Converts a DE with constant coefficients (explike) into a RE.
  192. Explanation
  193. ===========
  194. Performs the substitution:
  195. .. math::
  196. f^j(x) \\to r(k + j)
  197. Normalises the terms so that lowest order of a term is always r(k).
  198. Examples
  199. ========
  200. >>> from sympy import Function, Derivative
  201. >>> from sympy.series.formal import exp_re
  202. >>> from sympy.abc import x, k
  203. >>> f, r = Function('f'), Function('r')
  204. >>> exp_re(-f(x) + Derivative(f(x)), r, k)
  205. -r(k) + r(k + 1)
  206. >>> exp_re(Derivative(f(x), x) + Derivative(f(x), (x, 2)), r, k)
  207. r(k) + r(k + 1)
  208. See Also
  209. ========
  210. sympy.series.formal.hyper_re
  211. """
  212. RE = S.Zero
  213. g = DE.atoms(Function).pop()
  214. mini = None
  215. for t in Add.make_args(DE):
  216. coeff, d = t.as_independent(g)
  217. if isinstance(d, Derivative):
  218. j = d.derivative_count
  219. else:
  220. j = 0
  221. if mini is None or j < mini:
  222. mini = j
  223. RE += coeff * r(k + j)
  224. if mini:
  225. RE = RE.subs(k, k - mini)
  226. return RE
  227. def hyper_re(DE, r, k):
  228. """
  229. Converts a DE into a RE.
  230. Explanation
  231. ===========
  232. Performs the substitution:
  233. .. math::
  234. x^l f^j(x) \\to (k + 1 - l)_j . a_{k + j - l}
  235. Normalises the terms so that lowest order of a term is always r(k).
  236. Examples
  237. ========
  238. >>> from sympy import Function, Derivative
  239. >>> from sympy.series.formal import hyper_re
  240. >>> from sympy.abc import x, k
  241. >>> f, r = Function('f'), Function('r')
  242. >>> hyper_re(-f(x) + Derivative(f(x)), r, k)
  243. (k + 1)*r(k + 1) - r(k)
  244. >>> hyper_re(-x*f(x) + Derivative(f(x), (x, 2)), r, k)
  245. (k + 2)*(k + 3)*r(k + 3) - r(k)
  246. See Also
  247. ========
  248. sympy.series.formal.exp_re
  249. """
  250. RE = S.Zero
  251. g = DE.atoms(Function).pop()
  252. x = g.atoms(Symbol).pop()
  253. mini = None
  254. for t in Add.make_args(DE.expand()):
  255. coeff, d = t.as_independent(g)
  256. c, v = coeff.as_independent(x)
  257. l = v.as_coeff_exponent(x)[1]
  258. if isinstance(d, Derivative):
  259. j = d.derivative_count
  260. else:
  261. j = 0
  262. RE += c * rf(k + 1 - l, j) * r(k + j - l)
  263. if mini is None or j - l < mini:
  264. mini = j - l
  265. RE = RE.subs(k, k - mini)
  266. m = Wild('m')
  267. return RE.collect(r(k + m))
  268. def _transformation_a(f, x, P, Q, k, m, shift):
  269. f *= x**(-shift)
  270. P = P.subs(k, k + shift)
  271. Q = Q.subs(k, k + shift)
  272. return f, P, Q, m
  273. def _transformation_c(f, x, P, Q, k, m, scale):
  274. f = f.subs(x, x**scale)
  275. P = P.subs(k, k / scale)
  276. Q = Q.subs(k, k / scale)
  277. m *= scale
  278. return f, P, Q, m
  279. def _transformation_e(f, x, P, Q, k, m):
  280. f = f.diff(x)
  281. P = P.subs(k, k + 1) * (k + m + 1)
  282. Q = Q.subs(k, k + 1) * (k + 1)
  283. return f, P, Q, m
  284. def _apply_shift(sol, shift):
  285. return [(res, cond + shift) for res, cond in sol]
  286. def _apply_scale(sol, scale):
  287. return [(res, cond / scale) for res, cond in sol]
  288. def _apply_integrate(sol, x, k):
  289. return [(res / ((cond + 1)*(cond.as_coeff_Add()[1].coeff(k))), cond + 1)
  290. for res, cond in sol]
  291. def _compute_formula(f, x, P, Q, k, m, k_max):
  292. """Computes the formula for f."""
  293. from sympy.polys import roots
  294. sol = []
  295. for i in range(k_max + 1, k_max + m + 1):
  296. if (i < 0) == True:
  297. continue
  298. r = f.diff(x, i).limit(x, 0) / factorial(i)
  299. if r.is_zero:
  300. continue
  301. kterm = m*k + i
  302. res = r
  303. p = P.subs(k, kterm)
  304. q = Q.subs(k, kterm)
  305. c1 = p.subs(k, 1/k).leadterm(k)[0]
  306. c2 = q.subs(k, 1/k).leadterm(k)[0]
  307. res *= (-c1 / c2)**k
  308. for r, mul in roots(p, k).items():
  309. res *= rf(-r, k)**mul
  310. for r, mul in roots(q, k).items():
  311. res /= rf(-r, k)**mul
  312. sol.append((res, kterm))
  313. return sol
  314. def _rsolve_hypergeometric(f, x, P, Q, k, m):
  315. """
  316. Recursive wrapper to rsolve_hypergeometric.
  317. Explanation
  318. ===========
  319. Returns a Tuple of (formula, series independent terms,
  320. maximum power of x in independent terms) if successful
  321. otherwise ``None``.
  322. See :func:`rsolve_hypergeometric` for details.
  323. """
  324. from sympy.polys import lcm, roots
  325. from sympy.integrals import integrate
  326. # transformation - c
  327. proots, qroots = roots(P, k), roots(Q, k)
  328. all_roots = dict(proots)
  329. all_roots.update(qroots)
  330. scale = lcm([r.as_numer_denom()[1] for r, t in all_roots.items()
  331. if r.is_rational])
  332. f, P, Q, m = _transformation_c(f, x, P, Q, k, m, scale)
  333. # transformation - a
  334. qroots = roots(Q, k)
  335. if qroots:
  336. k_min = Min(*qroots.keys())
  337. else:
  338. k_min = S.Zero
  339. shift = k_min + m
  340. f, P, Q, m = _transformation_a(f, x, P, Q, k, m, shift)
  341. l = (x*f).limit(x, 0)
  342. if not isinstance(l, Limit) and l != 0: # Ideally should only be l != 0
  343. return None
  344. qroots = roots(Q, k)
  345. if qroots:
  346. k_max = Max(*qroots.keys())
  347. else:
  348. k_max = S.Zero
  349. ind, mp = S.Zero, -oo
  350. for i in range(k_max + m + 1):
  351. r = f.diff(x, i).limit(x, 0) / factorial(i)
  352. if r.is_finite is False:
  353. old_f = f
  354. f, P, Q, m = _transformation_a(f, x, P, Q, k, m, i)
  355. f, P, Q, m = _transformation_e(f, x, P, Q, k, m)
  356. sol, ind, mp = _rsolve_hypergeometric(f, x, P, Q, k, m)
  357. sol = _apply_integrate(sol, x, k)
  358. sol = _apply_shift(sol, i)
  359. ind = integrate(ind, x)
  360. ind += (old_f - ind).limit(x, 0) # constant of integration
  361. mp += 1
  362. return sol, ind, mp
  363. elif r:
  364. ind += r*x**(i + shift)
  365. pow_x = Rational((i + shift), scale)
  366. if pow_x > mp:
  367. mp = pow_x # maximum power of x
  368. ind = ind.subs(x, x**(1/scale))
  369. sol = _compute_formula(f, x, P, Q, k, m, k_max)
  370. sol = _apply_shift(sol, shift)
  371. sol = _apply_scale(sol, scale)
  372. return sol, ind, mp
  373. def rsolve_hypergeometric(f, x, P, Q, k, m):
  374. """
  375. Solves RE of hypergeometric type.
  376. Explanation
  377. ===========
  378. Attempts to solve RE of the form
  379. Q(k)*a(k + m) - P(k)*a(k)
  380. Transformations that preserve Hypergeometric type:
  381. a. x**n*f(x): b(k + m) = R(k - n)*b(k)
  382. b. f(A*x): b(k + m) = A**m*R(k)*b(k)
  383. c. f(x**n): b(k + n*m) = R(k/n)*b(k)
  384. d. f(x**(1/m)): b(k + 1) = R(k*m)*b(k)
  385. e. f'(x): b(k + m) = ((k + m + 1)/(k + 1))*R(k + 1)*b(k)
  386. Some of these transformations have been used to solve the RE.
  387. Returns
  388. =======
  389. formula : Expr
  390. ind : Expr
  391. Independent terms.
  392. order : int
  393. Examples
  394. ========
  395. >>> from sympy import exp, ln, S
  396. >>> from sympy.series.formal import rsolve_hypergeometric as rh
  397. >>> from sympy.abc import x, k
  398. >>> rh(exp(x), x, -S.One, (k + 1), k, 1)
  399. (Piecewise((1/factorial(k), Eq(Mod(k, 1), 0)), (0, True)), 1, 1)
  400. >>> rh(ln(1 + x), x, k**2, k*(k + 1), k, 1)
  401. (Piecewise(((-1)**(k - 1)*factorial(k - 1)/RisingFactorial(2, k - 1),
  402. Eq(Mod(k, 1), 0)), (0, True)), x, 2)
  403. References
  404. ==========
  405. .. [1] Formal Power Series - Dominik Gruntz, Wolfram Koepf
  406. .. [2] Power Series in Computer Algebra - Wolfram Koepf
  407. """
  408. result = _rsolve_hypergeometric(f, x, P, Q, k, m)
  409. if result is None:
  410. return None
  411. sol_list, ind, mp = result
  412. sol_dict = defaultdict(lambda: S.Zero)
  413. for res, cond in sol_list:
  414. j, mk = cond.as_coeff_Add()
  415. c = mk.coeff(k)
  416. if j.is_integer is False:
  417. res *= x**frac(j)
  418. j = floor(j)
  419. res = res.subs(k, (k - j) / c)
  420. cond = Eq(k % c, j % c)
  421. sol_dict[cond] += res # Group together formula for same conditions
  422. sol = []
  423. for cond, res in sol_dict.items():
  424. sol.append((res, cond))
  425. sol.append((S.Zero, True))
  426. sol = Piecewise(*sol)
  427. if mp is -oo:
  428. s = S.Zero
  429. elif mp.is_integer is False:
  430. s = ceiling(mp)
  431. else:
  432. s = mp + 1
  433. # save all the terms of
  434. # form 1/x**k in ind
  435. if s < 0:
  436. ind += sum(sequence(sol * x**k, (k, s, -1)))
  437. s = S.Zero
  438. return (sol, ind, s)
  439. def _solve_hyper_RE(f, x, RE, g, k):
  440. """See docstring of :func:`rsolve_hypergeometric` for details."""
  441. terms = Add.make_args(RE)
  442. if len(terms) == 2:
  443. gs = list(RE.atoms(Function))
  444. P, Q = map(RE.coeff, gs)
  445. m = gs[1].args[0] - gs[0].args[0]
  446. if m < 0:
  447. P, Q = Q, P
  448. m = abs(m)
  449. return rsolve_hypergeometric(f, x, P, Q, k, m)
  450. def _solve_explike_DE(f, x, DE, g, k):
  451. """Solves DE with constant coefficients."""
  452. from sympy.solvers import rsolve
  453. for t in Add.make_args(DE):
  454. coeff, d = t.as_independent(g)
  455. if coeff.free_symbols:
  456. return
  457. RE = exp_re(DE, g, k)
  458. init = {}
  459. for i in range(len(Add.make_args(RE))):
  460. if i:
  461. f = f.diff(x)
  462. init[g(k).subs(k, i)] = f.limit(x, 0)
  463. sol = rsolve(RE, g(k), init)
  464. if sol:
  465. return (sol / factorial(k), S.Zero, S.Zero)
  466. def _solve_simple(f, x, DE, g, k):
  467. """Converts DE into RE and solves using :func:`rsolve`."""
  468. from sympy.solvers import rsolve
  469. RE = hyper_re(DE, g, k)
  470. init = {}
  471. for i in range(len(Add.make_args(RE))):
  472. if i:
  473. f = f.diff(x)
  474. init[g(k).subs(k, i)] = f.limit(x, 0) / factorial(i)
  475. sol = rsolve(RE, g(k), init)
  476. if sol:
  477. return (sol, S.Zero, S.Zero)
  478. def _transform_explike_DE(DE, g, x, order, syms):
  479. """Converts DE with free parameters into DE with constant coefficients."""
  480. from sympy.solvers.solveset import linsolve
  481. eq = []
  482. highest_coeff = DE.coeff(Derivative(g(x), x, order))
  483. for i in range(order):
  484. coeff = DE.coeff(Derivative(g(x), x, i))
  485. coeff = (coeff / highest_coeff).expand().collect(x)
  486. for t in Add.make_args(coeff):
  487. eq.append(t)
  488. temp = []
  489. for e in eq:
  490. if e.has(x):
  491. break
  492. elif e.has(Symbol):
  493. temp.append(e)
  494. else:
  495. eq = temp
  496. if eq:
  497. sol = dict(zip(syms, (i for s in linsolve(eq, list(syms)) for i in s)))
  498. if sol:
  499. DE = DE.subs(sol)
  500. DE = DE.factor().as_coeff_mul(Derivative)[1][0]
  501. DE = DE.collect(Derivative(g(x)))
  502. return DE
  503. def _transform_DE_RE(DE, g, k, order, syms):
  504. """Converts DE with free parameters into RE of hypergeometric type."""
  505. from sympy.solvers.solveset import linsolve
  506. RE = hyper_re(DE, g, k)
  507. eq = []
  508. for i in range(1, order):
  509. coeff = RE.coeff(g(k + i))
  510. eq.append(coeff)
  511. sol = dict(zip(syms, (i for s in linsolve(eq, list(syms)) for i in s)))
  512. if sol:
  513. m = Wild('m')
  514. RE = RE.subs(sol)
  515. RE = RE.factor().as_numer_denom()[0].collect(g(k + m))
  516. RE = RE.as_coeff_mul(g)[1][0]
  517. for i in range(order): # smallest order should be g(k)
  518. if RE.coeff(g(k + i)) and i:
  519. RE = RE.subs(k, k - i)
  520. break
  521. return RE
  522. def solve_de(f, x, DE, order, g, k):
  523. """
  524. Solves the DE.
  525. Explanation
  526. ===========
  527. Tries to solve DE by either converting into a RE containing two terms or
  528. converting into a DE having constant coefficients.
  529. Returns
  530. =======
  531. formula : Expr
  532. ind : Expr
  533. Independent terms.
  534. order : int
  535. Examples
  536. ========
  537. >>> from sympy import Derivative as D, Function
  538. >>> from sympy import exp, ln
  539. >>> from sympy.series.formal import solve_de
  540. >>> from sympy.abc import x, k
  541. >>> f = Function('f')
  542. >>> solve_de(exp(x), x, D(f(x), x) - f(x), 1, f, k)
  543. (Piecewise((1/factorial(k), Eq(Mod(k, 1), 0)), (0, True)), 1, 1)
  544. >>> solve_de(ln(1 + x), x, (x + 1)*D(f(x), x, 2) + D(f(x)), 2, f, k)
  545. (Piecewise(((-1)**(k - 1)*factorial(k - 1)/RisingFactorial(2, k - 1),
  546. Eq(Mod(k, 1), 0)), (0, True)), x, 2)
  547. """
  548. sol = None
  549. syms = DE.free_symbols.difference({g, x})
  550. if syms:
  551. RE = _transform_DE_RE(DE, g, k, order, syms)
  552. else:
  553. RE = hyper_re(DE, g, k)
  554. if not RE.free_symbols.difference({k}):
  555. sol = _solve_hyper_RE(f, x, RE, g, k)
  556. if sol:
  557. return sol
  558. if syms:
  559. DE = _transform_explike_DE(DE, g, x, order, syms)
  560. if not DE.free_symbols.difference({x}):
  561. sol = _solve_explike_DE(f, x, DE, g, k)
  562. if sol:
  563. return sol
  564. def hyper_algorithm(f, x, k, order=4):
  565. """
  566. Hypergeometric algorithm for computing Formal Power Series.
  567. Explanation
  568. ===========
  569. Steps:
  570. * Generates DE
  571. * Convert the DE into RE
  572. * Solves the RE
  573. Examples
  574. ========
  575. >>> from sympy import exp, ln
  576. >>> from sympy.series.formal import hyper_algorithm
  577. >>> from sympy.abc import x, k
  578. >>> hyper_algorithm(exp(x), x, k)
  579. (Piecewise((1/factorial(k), Eq(Mod(k, 1), 0)), (0, True)), 1, 1)
  580. >>> hyper_algorithm(ln(1 + x), x, k)
  581. (Piecewise(((-1)**(k - 1)*factorial(k - 1)/RisingFactorial(2, k - 1),
  582. Eq(Mod(k, 1), 0)), (0, True)), x, 2)
  583. See Also
  584. ========
  585. sympy.series.formal.simpleDE
  586. sympy.series.formal.solve_de
  587. """
  588. g = Function('g')
  589. des = [] # list of DE's
  590. sol = None
  591. for DE, i in simpleDE(f, x, g, order):
  592. if DE is not None:
  593. sol = solve_de(f, x, DE, i, g, k)
  594. if sol:
  595. return sol
  596. if not DE.free_symbols.difference({x}):
  597. des.append(DE)
  598. # If nothing works
  599. # Try plain rsolve
  600. for DE in des:
  601. sol = _solve_simple(f, x, DE, g, k)
  602. if sol:
  603. return sol
  604. def _compute_fps(f, x, x0, dir, hyper, order, rational, full):
  605. """Recursive wrapper to compute fps.
  606. See :func:`compute_fps` for details.
  607. """
  608. if x0 in [S.Infinity, S.NegativeInfinity]:
  609. dir = S.One if x0 is S.Infinity else -S.One
  610. temp = f.subs(x, 1/x)
  611. result = _compute_fps(temp, x, 0, dir, hyper, order, rational, full)
  612. if result is None:
  613. return None
  614. return (result[0], result[1].subs(x, 1/x), result[2].subs(x, 1/x))
  615. elif x0 or dir == -S.One:
  616. if dir == -S.One:
  617. rep = -x + x0
  618. rep2 = -x
  619. rep2b = x0
  620. else:
  621. rep = x + x0
  622. rep2 = x
  623. rep2b = -x0
  624. temp = f.subs(x, rep)
  625. result = _compute_fps(temp, x, 0, S.One, hyper, order, rational, full)
  626. if result is None:
  627. return None
  628. return (result[0], result[1].subs(x, rep2 + rep2b),
  629. result[2].subs(x, rep2 + rep2b))
  630. if f.is_polynomial(x):
  631. k = Dummy('k')
  632. ak = sequence(Coeff(f, x, k), (k, 1, oo))
  633. xk = sequence(x**k, (k, 0, oo))
  634. ind = f.coeff(x, 0)
  635. return ak, xk, ind
  636. # Break instances of Add
  637. # this allows application of different
  638. # algorithms on different terms increasing the
  639. # range of admissible functions.
  640. if isinstance(f, Add):
  641. result = False
  642. ak = sequence(S.Zero, (0, oo))
  643. ind, xk = S.Zero, None
  644. for t in Add.make_args(f):
  645. res = _compute_fps(t, x, 0, S.One, hyper, order, rational, full)
  646. if res:
  647. if not result:
  648. result = True
  649. xk = res[1]
  650. if res[0].start > ak.start:
  651. seq = ak
  652. s, f = ak.start, res[0].start
  653. else:
  654. seq = res[0]
  655. s, f = res[0].start, ak.start
  656. save = Add(*[z[0]*z[1] for z in zip(seq[0:(f - s)], xk[s:f])])
  657. ak += res[0]
  658. ind += res[2] + save
  659. else:
  660. ind += t
  661. if result:
  662. return ak, xk, ind
  663. return None
  664. # The symbolic term - symb, if present, is being separated from the function
  665. # Otherwise symb is being set to S.One
  666. syms = f.free_symbols.difference({x})
  667. (f, symb) = expand(f).as_independent(*syms)
  668. if symb.is_zero:
  669. symb = S.One
  670. symb = powsimp(symb)
  671. result = None
  672. # from here on it's x0=0 and dir=1 handling
  673. k = Dummy('k')
  674. if rational:
  675. result = rational_algorithm(f, x, k, order, full)
  676. if result is None and hyper:
  677. result = hyper_algorithm(f, x, k, order)
  678. if result is None:
  679. return None
  680. ak = sequence(result[0], (k, result[2], oo))
  681. xk_formula = powsimp(x**k * symb)
  682. xk = sequence(xk_formula, (k, 0, oo))
  683. ind = powsimp(result[1] * symb)
  684. return ak, xk, ind
  685. def compute_fps(f, x, x0=0, dir=1, hyper=True, order=4, rational=True,
  686. full=False):
  687. """
  688. Computes the formula for Formal Power Series of a function.
  689. Explanation
  690. ===========
  691. Tries to compute the formula by applying the following techniques
  692. (in order):
  693. * rational_algorithm
  694. * Hypergeometric algorithm
  695. Parameters
  696. ==========
  697. x : Symbol
  698. x0 : number, optional
  699. Point to perform series expansion about. Default is 0.
  700. dir : {1, -1, '+', '-'}, optional
  701. If dir is 1 or '+' the series is calculated from the right and
  702. for -1 or '-' the series is calculated from the left. For smooth
  703. functions this flag will not alter the results. Default is 1.
  704. hyper : {True, False}, optional
  705. Set hyper to False to skip the hypergeometric algorithm.
  706. By default it is set to False.
  707. order : int, optional
  708. Order of the derivative of ``f``, Default is 4.
  709. rational : {True, False}, optional
  710. Set rational to False to skip rational algorithm. By default it is set
  711. to True.
  712. full : {True, False}, optional
  713. Set full to True to increase the range of rational algorithm.
  714. See :func:`rational_algorithm` for details. By default it is set to
  715. False.
  716. Returns
  717. =======
  718. ak : sequence
  719. Sequence of coefficients.
  720. xk : sequence
  721. Sequence of powers of x.
  722. ind : Expr
  723. Independent terms.
  724. mul : Pow
  725. Common terms.
  726. See Also
  727. ========
  728. sympy.series.formal.rational_algorithm
  729. sympy.series.formal.hyper_algorithm
  730. """
  731. f = sympify(f)
  732. x = sympify(x)
  733. if not f.has(x):
  734. return None
  735. x0 = sympify(x0)
  736. if dir == '+':
  737. dir = S.One
  738. elif dir == '-':
  739. dir = -S.One
  740. elif dir not in [S.One, -S.One]:
  741. raise ValueError("Dir must be '+' or '-'")
  742. else:
  743. dir = sympify(dir)
  744. return _compute_fps(f, x, x0, dir, hyper, order, rational, full)
  745. class Coeff(Function):
  746. """
  747. Coeff(p, x, n) represents the nth coefficient of the polynomial p in x
  748. """
  749. @classmethod
  750. def eval(cls, p, x, n):
  751. if p.is_polynomial(x) and n.is_integer:
  752. return p.coeff(x, n)
  753. class FormalPowerSeries(SeriesBase):
  754. """
  755. Represents Formal Power Series of a function.
  756. Explanation
  757. ===========
  758. No computation is performed. This class should only to be used to represent
  759. a series. No checks are performed.
  760. For computing a series use :func:`fps`.
  761. See Also
  762. ========
  763. sympy.series.formal.fps
  764. """
  765. def __new__(cls, *args):
  766. args = map(sympify, args)
  767. return Expr.__new__(cls, *args)
  768. def __init__(self, *args):
  769. ak = args[4][0]
  770. k = ak.variables[0]
  771. self.ak_seq = sequence(ak.formula, (k, 1, oo))
  772. self.fact_seq = sequence(factorial(k), (k, 1, oo))
  773. self.bell_coeff_seq = self.ak_seq * self.fact_seq
  774. self.sign_seq = sequence((-1, 1), (k, 1, oo))
  775. @property
  776. def function(self):
  777. return self.args[0]
  778. @property
  779. def x(self):
  780. return self.args[1]
  781. @property
  782. def x0(self):
  783. return self.args[2]
  784. @property
  785. def dir(self):
  786. return self.args[3]
  787. @property
  788. def ak(self):
  789. return self.args[4][0]
  790. @property
  791. def xk(self):
  792. return self.args[4][1]
  793. @property
  794. def ind(self):
  795. return self.args[4][2]
  796. @property
  797. def interval(self):
  798. return Interval(0, oo)
  799. @property
  800. def start(self):
  801. return self.interval.inf
  802. @property
  803. def stop(self):
  804. return self.interval.sup
  805. @property
  806. def length(self):
  807. return oo
  808. @property
  809. def infinite(self):
  810. """Returns an infinite representation of the series"""
  811. from sympy.concrete import Sum
  812. ak, xk = self.ak, self.xk
  813. k = ak.variables[0]
  814. inf_sum = Sum(ak.formula * xk.formula, (k, ak.start, ak.stop))
  815. return self.ind + inf_sum
  816. def _get_pow_x(self, term):
  817. """Returns the power of x in a term."""
  818. xterm, pow_x = term.as_independent(self.x)[1].as_base_exp()
  819. if not xterm.has(self.x):
  820. return S.Zero
  821. return pow_x
  822. def polynomial(self, n=6):
  823. """
  824. Truncated series as polynomial.
  825. Explanation
  826. ===========
  827. Returns series expansion of ``f`` upto order ``O(x**n)``
  828. as a polynomial(without ``O`` term).
  829. """
  830. terms = []
  831. sym = self.free_symbols
  832. for i, t in enumerate(self):
  833. xp = self._get_pow_x(t)
  834. if xp.has(*sym):
  835. xp = xp.as_coeff_add(*sym)[0]
  836. if xp >= n:
  837. break
  838. elif xp.is_integer is True and i == n + 1:
  839. break
  840. elif t is not S.Zero:
  841. terms.append(t)
  842. return Add(*terms)
  843. def truncate(self, n=6):
  844. """
  845. Truncated series.
  846. Explanation
  847. ===========
  848. Returns truncated series expansion of f upto
  849. order ``O(x**n)``.
  850. If n is ``None``, returns an infinite iterator.
  851. """
  852. if n is None:
  853. return iter(self)
  854. x, x0 = self.x, self.x0
  855. pt_xk = self.xk.coeff(n)
  856. if x0 is S.NegativeInfinity:
  857. x0 = S.Infinity
  858. return self.polynomial(n) + Order(pt_xk, (x, x0))
  859. def zero_coeff(self):
  860. return self._eval_term(0)
  861. def _eval_term(self, pt):
  862. try:
  863. pt_xk = self.xk.coeff(pt)
  864. pt_ak = self.ak.coeff(pt).simplify() # Simplify the coefficients
  865. except IndexError:
  866. term = S.Zero
  867. else:
  868. term = (pt_ak * pt_xk)
  869. if self.ind:
  870. ind = S.Zero
  871. sym = self.free_symbols
  872. for t in Add.make_args(self.ind):
  873. pow_x = self._get_pow_x(t)
  874. if pow_x.has(*sym):
  875. pow_x = pow_x.as_coeff_add(*sym)[0]
  876. if pt == 0 and pow_x < 1:
  877. ind += t
  878. elif pow_x >= pt and pow_x < pt + 1:
  879. ind += t
  880. term += ind
  881. return term.collect(self.x)
  882. def _eval_subs(self, old, new):
  883. x = self.x
  884. if old.has(x):
  885. return self
  886. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  887. for t in self:
  888. if t is not S.Zero:
  889. return t
  890. def _eval_derivative(self, x):
  891. f = self.function.diff(x)
  892. ind = self.ind.diff(x)
  893. pow_xk = self._get_pow_x(self.xk.formula)
  894. ak = self.ak
  895. k = ak.variables[0]
  896. if ak.formula.has(x):
  897. form = []
  898. for e, c in ak.formula.args:
  899. temp = S.Zero
  900. for t in Add.make_args(e):
  901. pow_x = self._get_pow_x(t)
  902. temp += t * (pow_xk + pow_x)
  903. form.append((temp, c))
  904. form = Piecewise(*form)
  905. ak = sequence(form.subs(k, k + 1), (k, ak.start - 1, ak.stop))
  906. else:
  907. ak = sequence((ak.formula * pow_xk).subs(k, k + 1),
  908. (k, ak.start - 1, ak.stop))
  909. return self.func(f, self.x, self.x0, self.dir, (ak, self.xk, ind))
  910. def integrate(self, x=None, **kwargs):
  911. """
  912. Integrate Formal Power Series.
  913. Examples
  914. ========
  915. >>> from sympy import fps, sin, integrate
  916. >>> from sympy.abc import x
  917. >>> f = fps(sin(x))
  918. >>> f.integrate(x).truncate()
  919. -1 + x**2/2 - x**4/24 + O(x**6)
  920. >>> integrate(f, (x, 0, 1))
  921. 1 - cos(1)
  922. """
  923. from sympy.integrals import integrate
  924. if x is None:
  925. x = self.x
  926. elif iterable(x):
  927. return integrate(self.function, x)
  928. f = integrate(self.function, x)
  929. ind = integrate(self.ind, x)
  930. ind += (f - ind).limit(x, 0) # constant of integration
  931. pow_xk = self._get_pow_x(self.xk.formula)
  932. ak = self.ak
  933. k = ak.variables[0]
  934. if ak.formula.has(x):
  935. form = []
  936. for e, c in ak.formula.args:
  937. temp = S.Zero
  938. for t in Add.make_args(e):
  939. pow_x = self._get_pow_x(t)
  940. temp += t / (pow_xk + pow_x + 1)
  941. form.append((temp, c))
  942. form = Piecewise(*form)
  943. ak = sequence(form.subs(k, k - 1), (k, ak.start + 1, ak.stop))
  944. else:
  945. ak = sequence((ak.formula / (pow_xk + 1)).subs(k, k - 1),
  946. (k, ak.start + 1, ak.stop))
  947. return self.func(f, self.x, self.x0, self.dir, (ak, self.xk, ind))
  948. def product(self, other, x=None, n=6):
  949. """
  950. Multiplies two Formal Power Series, using discrete convolution and
  951. return the truncated terms upto specified order.
  952. Parameters
  953. ==========
  954. n : Number, optional
  955. Specifies the order of the term up to which the polynomial should
  956. be truncated.
  957. Examples
  958. ========
  959. >>> from sympy import fps, sin, exp
  960. >>> from sympy.abc import x
  961. >>> f1 = fps(sin(x))
  962. >>> f2 = fps(exp(x))
  963. >>> f1.product(f2, x).truncate(4)
  964. x + x**2 + x**3/3 + O(x**4)
  965. See Also
  966. ========
  967. sympy.discrete.convolutions
  968. sympy.series.formal.FormalPowerSeriesProduct
  969. """
  970. if n is None:
  971. return iter(self)
  972. other = sympify(other)
  973. if not isinstance(other, FormalPowerSeries):
  974. raise ValueError("Both series should be an instance of FormalPowerSeries"
  975. " class.")
  976. if self.dir != other.dir:
  977. raise ValueError("Both series should be calculated from the"
  978. " same direction.")
  979. elif self.x0 != other.x0:
  980. raise ValueError("Both series should be calculated about the"
  981. " same point.")
  982. elif self.x != other.x:
  983. raise ValueError("Both series should have the same symbol.")
  984. return FormalPowerSeriesProduct(self, other)
  985. def coeff_bell(self, n):
  986. r"""
  987. self.coeff_bell(n) returns a sequence of Bell polynomials of the second kind.
  988. Note that ``n`` should be a integer.
  989. The second kind of Bell polynomials (are sometimes called "partial" Bell
  990. polynomials or incomplete Bell polynomials) are defined as
  991. .. math::
  992. B_{n,k}(x_1, x_2,\dotsc x_{n-k+1}) =
  993. \sum_{j_1+j_2+j_2+\dotsb=k \atop j_1+2j_2+3j_2+\dotsb=n}
  994. \frac{n!}{j_1!j_2!\dotsb j_{n-k+1}!}
  995. \left(\frac{x_1}{1!} \right)^{j_1}
  996. \left(\frac{x_2}{2!} \right)^{j_2} \dotsb
  997. \left(\frac{x_{n-k+1}}{(n-k+1)!} \right) ^{j_{n-k+1}}.
  998. * ``bell(n, k, (x1, x2, ...))`` gives Bell polynomials of the second kind,
  999. `B_{n,k}(x_1, x_2, \dotsc, x_{n-k+1})`.
  1000. See Also
  1001. ========
  1002. sympy.functions.combinatorial.numbers.bell
  1003. """
  1004. inner_coeffs = [bell(n, j, tuple(self.bell_coeff_seq[:n-j+1])) for j in range(1, n+1)]
  1005. k = Dummy('k')
  1006. return sequence(tuple(inner_coeffs), (k, 1, oo))
  1007. def compose(self, other, x=None, n=6):
  1008. r"""
  1009. Returns the truncated terms of the formal power series of the composed function,
  1010. up to specified ``n``.
  1011. Explanation
  1012. ===========
  1013. If ``f`` and ``g`` are two formal power series of two different functions,
  1014. then the coefficient sequence ``ak`` of the composed formal power series `fp`
  1015. will be as follows.
  1016. .. math::
  1017. \sum\limits_{k=0}^{n} b_k B_{n,k}(x_1, x_2, \dotsc, x_{n-k+1})
  1018. Parameters
  1019. ==========
  1020. n : Number, optional
  1021. Specifies the order of the term up to which the polynomial should
  1022. be truncated.
  1023. Examples
  1024. ========
  1025. >>> from sympy import fps, sin, exp
  1026. >>> from sympy.abc import x
  1027. >>> f1 = fps(exp(x))
  1028. >>> f2 = fps(sin(x))
  1029. >>> f1.compose(f2, x).truncate()
  1030. 1 + x + x**2/2 - x**4/8 - x**5/15 + O(x**6)
  1031. >>> f1.compose(f2, x).truncate(8)
  1032. 1 + x + x**2/2 - x**4/8 - x**5/15 - x**6/240 + x**7/90 + O(x**8)
  1033. See Also
  1034. ========
  1035. sympy.functions.combinatorial.numbers.bell
  1036. sympy.series.formal.FormalPowerSeriesCompose
  1037. References
  1038. ==========
  1039. .. [1] Comtet, Louis: Advanced combinatorics; the art of finite and infinite expansions. Reidel, 1974.
  1040. """
  1041. if n is None:
  1042. return iter(self)
  1043. other = sympify(other)
  1044. if not isinstance(other, FormalPowerSeries):
  1045. raise ValueError("Both series should be an instance of FormalPowerSeries"
  1046. " class.")
  1047. if self.dir != other.dir:
  1048. raise ValueError("Both series should be calculated from the"
  1049. " same direction.")
  1050. elif self.x0 != other.x0:
  1051. raise ValueError("Both series should be calculated about the"
  1052. " same point.")
  1053. elif self.x != other.x:
  1054. raise ValueError("Both series should have the same symbol.")
  1055. if other._eval_term(0).as_coeff_mul(other.x)[0] is not S.Zero:
  1056. raise ValueError("The formal power series of the inner function should not have any "
  1057. "constant coefficient term.")
  1058. return FormalPowerSeriesCompose(self, other)
  1059. def inverse(self, x=None, n=6):
  1060. r"""
  1061. Returns the truncated terms of the inverse of the formal power series,
  1062. up to specified ``n``.
  1063. Explanation
  1064. ===========
  1065. If ``f`` and ``g`` are two formal power series of two different functions,
  1066. then the coefficient sequence ``ak`` of the composed formal power series ``fp``
  1067. will be as follows.
  1068. .. math::
  1069. \sum\limits_{k=0}^{n} (-1)^{k} x_0^{-k-1} B_{n,k}(x_1, x_2, \dotsc, x_{n-k+1})
  1070. Parameters
  1071. ==========
  1072. n : Number, optional
  1073. Specifies the order of the term up to which the polynomial should
  1074. be truncated.
  1075. Examples
  1076. ========
  1077. >>> from sympy import fps, exp, cos
  1078. >>> from sympy.abc import x
  1079. >>> f1 = fps(exp(x))
  1080. >>> f2 = fps(cos(x))
  1081. >>> f1.inverse(x).truncate()
  1082. 1 - x + x**2/2 - x**3/6 + x**4/24 - x**5/120 + O(x**6)
  1083. >>> f2.inverse(x).truncate(8)
  1084. 1 + x**2/2 + 5*x**4/24 + 61*x**6/720 + O(x**8)
  1085. See Also
  1086. ========
  1087. sympy.functions.combinatorial.numbers.bell
  1088. sympy.series.formal.FormalPowerSeriesInverse
  1089. References
  1090. ==========
  1091. .. [1] Comtet, Louis: Advanced combinatorics; the art of finite and infinite expansions. Reidel, 1974.
  1092. """
  1093. if n is None:
  1094. return iter(self)
  1095. if self._eval_term(0).is_zero:
  1096. raise ValueError("Constant coefficient should exist for an inverse of a formal"
  1097. " power series to exist.")
  1098. return FormalPowerSeriesInverse(self)
  1099. def __add__(self, other):
  1100. other = sympify(other)
  1101. if isinstance(other, FormalPowerSeries):
  1102. if self.dir != other.dir:
  1103. raise ValueError("Both series should be calculated from the"
  1104. " same direction.")
  1105. elif self.x0 != other.x0:
  1106. raise ValueError("Both series should be calculated about the"
  1107. " same point.")
  1108. x, y = self.x, other.x
  1109. f = self.function + other.function.subs(y, x)
  1110. if self.x not in f.free_symbols:
  1111. return f
  1112. ak = self.ak + other.ak
  1113. if self.ak.start > other.ak.start:
  1114. seq = other.ak
  1115. s, e = other.ak.start, self.ak.start
  1116. else:
  1117. seq = self.ak
  1118. s, e = self.ak.start, other.ak.start
  1119. save = Add(*[z[0]*z[1] for z in zip(seq[0:(e - s)], self.xk[s:e])])
  1120. ind = self.ind + other.ind + save
  1121. return self.func(f, x, self.x0, self.dir, (ak, self.xk, ind))
  1122. elif not other.has(self.x):
  1123. f = self.function + other
  1124. ind = self.ind + other
  1125. return self.func(f, self.x, self.x0, self.dir,
  1126. (self.ak, self.xk, ind))
  1127. return Add(self, other)
  1128. def __radd__(self, other):
  1129. return self.__add__(other)
  1130. def __neg__(self):
  1131. return self.func(-self.function, self.x, self.x0, self.dir,
  1132. (-self.ak, self.xk, -self.ind))
  1133. def __sub__(self, other):
  1134. return self.__add__(-other)
  1135. def __rsub__(self, other):
  1136. return (-self).__add__(other)
  1137. def __mul__(self, other):
  1138. other = sympify(other)
  1139. if other.has(self.x):
  1140. return Mul(self, other)
  1141. f = self.function * other
  1142. ak = self.ak.coeff_mul(other)
  1143. ind = self.ind * other
  1144. return self.func(f, self.x, self.x0, self.dir, (ak, self.xk, ind))
  1145. def __rmul__(self, other):
  1146. return self.__mul__(other)
  1147. class FiniteFormalPowerSeries(FormalPowerSeries):
  1148. """Base Class for Product, Compose and Inverse classes"""
  1149. def __init__(self, *args):
  1150. pass
  1151. @property
  1152. def ffps(self):
  1153. return self.args[0]
  1154. @property
  1155. def gfps(self):
  1156. return self.args[1]
  1157. @property
  1158. def f(self):
  1159. return self.ffps.function
  1160. @property
  1161. def g(self):
  1162. return self.gfps.function
  1163. @property
  1164. def infinite(self):
  1165. raise NotImplementedError("No infinite version for an object of"
  1166. " FiniteFormalPowerSeries class.")
  1167. def _eval_terms(self, n):
  1168. raise NotImplementedError("(%s)._eval_terms()" % self)
  1169. def _eval_term(self, pt):
  1170. raise NotImplementedError("By the current logic, one can get terms"
  1171. "upto a certain order, instead of getting term by term.")
  1172. def polynomial(self, n):
  1173. return self._eval_terms(n)
  1174. def truncate(self, n=6):
  1175. ffps = self.ffps
  1176. pt_xk = ffps.xk.coeff(n)
  1177. x, x0 = ffps.x, ffps.x0
  1178. return self.polynomial(n) + Order(pt_xk, (x, x0))
  1179. def _eval_derivative(self, x):
  1180. raise NotImplementedError
  1181. def integrate(self, x):
  1182. raise NotImplementedError
  1183. class FormalPowerSeriesProduct(FiniteFormalPowerSeries):
  1184. """Represents the product of two formal power series of two functions.
  1185. Explanation
  1186. ===========
  1187. No computation is performed. Terms are calculated using a term by term logic,
  1188. instead of a point by point logic.
  1189. There are two differences between a :obj:`FormalPowerSeries` object and a
  1190. :obj:`FormalPowerSeriesProduct` object. The first argument contains the two
  1191. functions involved in the product. Also, the coefficient sequence contains
  1192. both the coefficient sequence of the formal power series of the involved functions.
  1193. See Also
  1194. ========
  1195. sympy.series.formal.FormalPowerSeries
  1196. sympy.series.formal.FiniteFormalPowerSeries
  1197. """
  1198. def __init__(self, *args):
  1199. ffps, gfps = self.ffps, self.gfps
  1200. k = ffps.ak.variables[0]
  1201. self.coeff1 = sequence(ffps.ak.formula, (k, 0, oo))
  1202. k = gfps.ak.variables[0]
  1203. self.coeff2 = sequence(gfps.ak.formula, (k, 0, oo))
  1204. @property
  1205. def function(self):
  1206. """Function of the product of two formal power series."""
  1207. return self.f * self.g
  1208. def _eval_terms(self, n):
  1209. """
  1210. Returns the first ``n`` terms of the product formal power series.
  1211. Term by term logic is implemented here.
  1212. Examples
  1213. ========
  1214. >>> from sympy import fps, sin, exp
  1215. >>> from sympy.abc import x
  1216. >>> f1 = fps(sin(x))
  1217. >>> f2 = fps(exp(x))
  1218. >>> fprod = f1.product(f2, x)
  1219. >>> fprod._eval_terms(4)
  1220. x**3/3 + x**2 + x
  1221. See Also
  1222. ========
  1223. sympy.series.formal.FormalPowerSeries.product
  1224. """
  1225. coeff1, coeff2 = self.coeff1, self.coeff2
  1226. aks = convolution(coeff1[:n], coeff2[:n])
  1227. terms = []
  1228. for i in range(0, n):
  1229. terms.append(aks[i] * self.ffps.xk.coeff(i))
  1230. return Add(*terms)
  1231. class FormalPowerSeriesCompose(FiniteFormalPowerSeries):
  1232. """
  1233. Represents the composed formal power series of two functions.
  1234. Explanation
  1235. ===========
  1236. No computation is performed. Terms are calculated using a term by term logic,
  1237. instead of a point by point logic.
  1238. There are two differences between a :obj:`FormalPowerSeries` object and a
  1239. :obj:`FormalPowerSeriesCompose` object. The first argument contains the outer
  1240. function and the inner function involved in the omposition. Also, the
  1241. coefficient sequence contains the generic sequence which is to be multiplied
  1242. by a custom ``bell_seq`` finite sequence. The finite terms will then be added up to
  1243. get the final terms.
  1244. See Also
  1245. ========
  1246. sympy.series.formal.FormalPowerSeries
  1247. sympy.series.formal.FiniteFormalPowerSeries
  1248. """
  1249. @property
  1250. def function(self):
  1251. """Function for the composed formal power series."""
  1252. f, g, x = self.f, self.g, self.ffps.x
  1253. return f.subs(x, g)
  1254. def _eval_terms(self, n):
  1255. """
  1256. Returns the first `n` terms of the composed formal power series.
  1257. Term by term logic is implemented here.
  1258. Explanation
  1259. ===========
  1260. The coefficient sequence of the :obj:`FormalPowerSeriesCompose` object is the generic sequence.
  1261. It is multiplied by ``bell_seq`` to get a sequence, whose terms are added up to get
  1262. the final terms for the polynomial.
  1263. Examples
  1264. ========
  1265. >>> from sympy import fps, sin, exp
  1266. >>> from sympy.abc import x
  1267. >>> f1 = fps(exp(x))
  1268. >>> f2 = fps(sin(x))
  1269. >>> fcomp = f1.compose(f2, x)
  1270. >>> fcomp._eval_terms(6)
  1271. -x**5/15 - x**4/8 + x**2/2 + x + 1
  1272. >>> fcomp._eval_terms(8)
  1273. x**7/90 - x**6/240 - x**5/15 - x**4/8 + x**2/2 + x + 1
  1274. See Also
  1275. ========
  1276. sympy.series.formal.FormalPowerSeries.compose
  1277. sympy.series.formal.FormalPowerSeries.coeff_bell
  1278. """
  1279. ffps, gfps = self.ffps, self.gfps
  1280. terms = [ffps.zero_coeff()]
  1281. for i in range(1, n):
  1282. bell_seq = gfps.coeff_bell(i)
  1283. seq = (ffps.bell_coeff_seq * bell_seq)
  1284. terms.append(Add(*(seq[:i])) / ffps.fact_seq[i-1] * ffps.xk.coeff(i))
  1285. return Add(*terms)
  1286. class FormalPowerSeriesInverse(FiniteFormalPowerSeries):
  1287. """
  1288. Represents the Inverse of a formal power series.
  1289. Explanation
  1290. ===========
  1291. No computation is performed. Terms are calculated using a term by term logic,
  1292. instead of a point by point logic.
  1293. There is a single difference between a :obj:`FormalPowerSeries` object and a
  1294. :obj:`FormalPowerSeriesInverse` object. The coefficient sequence contains the
  1295. generic sequence which is to be multiplied by a custom ``bell_seq`` finite sequence.
  1296. The finite terms will then be added up to get the final terms.
  1297. See Also
  1298. ========
  1299. sympy.series.formal.FormalPowerSeries
  1300. sympy.series.formal.FiniteFormalPowerSeries
  1301. """
  1302. def __init__(self, *args):
  1303. ffps = self.ffps
  1304. k = ffps.xk.variables[0]
  1305. inv = ffps.zero_coeff()
  1306. inv_seq = sequence(inv ** (-(k + 1)), (k, 1, oo))
  1307. self.aux_seq = ffps.sign_seq * ffps.fact_seq * inv_seq
  1308. @property
  1309. def function(self):
  1310. """Function for the inverse of a formal power series."""
  1311. f = self.f
  1312. return 1 / f
  1313. @property
  1314. def g(self):
  1315. raise ValueError("Only one function is considered while performing"
  1316. "inverse of a formal power series.")
  1317. @property
  1318. def gfps(self):
  1319. raise ValueError("Only one function is considered while performing"
  1320. "inverse of a formal power series.")
  1321. def _eval_terms(self, n):
  1322. """
  1323. Returns the first ``n`` terms of the composed formal power series.
  1324. Term by term logic is implemented here.
  1325. Explanation
  1326. ===========
  1327. The coefficient sequence of the `FormalPowerSeriesInverse` object is the generic sequence.
  1328. It is multiplied by ``bell_seq`` to get a sequence, whose terms are added up to get
  1329. the final terms for the polynomial.
  1330. Examples
  1331. ========
  1332. >>> from sympy import fps, exp, cos
  1333. >>> from sympy.abc import x
  1334. >>> f1 = fps(exp(x))
  1335. >>> f2 = fps(cos(x))
  1336. >>> finv1, finv2 = f1.inverse(), f2.inverse()
  1337. >>> finv1._eval_terms(6)
  1338. -x**5/120 + x**4/24 - x**3/6 + x**2/2 - x + 1
  1339. >>> finv2._eval_terms(8)
  1340. 61*x**6/720 + 5*x**4/24 + x**2/2 + 1
  1341. See Also
  1342. ========
  1343. sympy.series.formal.FormalPowerSeries.inverse
  1344. sympy.series.formal.FormalPowerSeries.coeff_bell
  1345. """
  1346. ffps = self.ffps
  1347. terms = [ffps.zero_coeff()]
  1348. for i in range(1, n):
  1349. bell_seq = ffps.coeff_bell(i)
  1350. seq = (self.aux_seq * bell_seq)
  1351. terms.append(Add(*(seq[:i])) / ffps.fact_seq[i-1] * ffps.xk.coeff(i))
  1352. return Add(*terms)
  1353. def fps(f, x=None, x0=0, dir=1, hyper=True, order=4, rational=True, full=False):
  1354. """
  1355. Generates Formal Power Series of ``f``.
  1356. Explanation
  1357. ===========
  1358. Returns the formal series expansion of ``f`` around ``x = x0``
  1359. with respect to ``x`` in the form of a ``FormalPowerSeries`` object.
  1360. Formal Power Series is represented using an explicit formula
  1361. computed using different algorithms.
  1362. See :func:`compute_fps` for the more details regarding the computation
  1363. of formula.
  1364. Parameters
  1365. ==========
  1366. x : Symbol, optional
  1367. If x is None and ``f`` is univariate, the univariate symbols will be
  1368. supplied, otherwise an error will be raised.
  1369. x0 : number, optional
  1370. Point to perform series expansion about. Default is 0.
  1371. dir : {1, -1, '+', '-'}, optional
  1372. If dir is 1 or '+' the series is calculated from the right and
  1373. for -1 or '-' the series is calculated from the left. For smooth
  1374. functions this flag will not alter the results. Default is 1.
  1375. hyper : {True, False}, optional
  1376. Set hyper to False to skip the hypergeometric algorithm.
  1377. By default it is set to False.
  1378. order : int, optional
  1379. Order of the derivative of ``f``, Default is 4.
  1380. rational : {True, False}, optional
  1381. Set rational to False to skip rational algorithm. By default it is set
  1382. to True.
  1383. full : {True, False}, optional
  1384. Set full to True to increase the range of rational algorithm.
  1385. See :func:`rational_algorithm` for details. By default it is set to
  1386. False.
  1387. Examples
  1388. ========
  1389. >>> from sympy import fps, ln, atan, sin
  1390. >>> from sympy.abc import x, n
  1391. Rational Functions
  1392. >>> fps(ln(1 + x)).truncate()
  1393. x - x**2/2 + x**3/3 - x**4/4 + x**5/5 + O(x**6)
  1394. >>> fps(atan(x), full=True).truncate()
  1395. x - x**3/3 + x**5/5 + O(x**6)
  1396. Symbolic Functions
  1397. >>> fps(x**n*sin(x**2), x).truncate(8)
  1398. -x**(n + 6)/6 + x**(n + 2) + O(x**(n + 8))
  1399. See Also
  1400. ========
  1401. sympy.series.formal.FormalPowerSeries
  1402. sympy.series.formal.compute_fps
  1403. """
  1404. f = sympify(f)
  1405. if x is None:
  1406. free = f.free_symbols
  1407. if len(free) == 1:
  1408. x = free.pop()
  1409. elif not free:
  1410. return f
  1411. else:
  1412. raise NotImplementedError("multivariate formal power series")
  1413. result = compute_fps(f, x, x0, dir, hyper, order, rational, full)
  1414. if result is None:
  1415. return f
  1416. return FormalPowerSeries(f, x, x0, dir, result)