formal.py 50 KB

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