formal.py 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869
  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 = []
  420. for cond, res in sol_dict.items():
  421. sol.append((res, cond))
  422. sol.append((S.Zero, True))
  423. sol = Piecewise(*sol)
  424. if mp is -oo:
  425. s = S.Zero
  426. elif mp.is_integer is False:
  427. s = ceiling(mp)
  428. else:
  429. s = mp + 1
  430. # save all the terms of
  431. # form 1/x**k in ind
  432. if s < 0:
  433. ind += sum(sequence(sol * x**k, (k, s, -1)))
  434. s = S.Zero
  435. return (sol, ind, s)
  436. def _solve_hyper_RE(f, x, RE, g, k):
  437. """See docstring of :func:`rsolve_hypergeometric` for details."""
  438. terms = Add.make_args(RE)
  439. if len(terms) == 2:
  440. gs = list(RE.atoms(Function))
  441. P, Q = map(RE.coeff, gs)
  442. m = gs[1].args[0] - gs[0].args[0]
  443. if m < 0:
  444. P, Q = Q, P
  445. m = abs(m)
  446. return rsolve_hypergeometric(f, x, P, Q, k, m)
  447. def _solve_explike_DE(f, x, DE, g, k):
  448. """Solves DE with constant coefficients."""
  449. from sympy.solvers import rsolve
  450. for t in Add.make_args(DE):
  451. coeff, d = t.as_independent(g)
  452. if coeff.free_symbols:
  453. return
  454. RE = exp_re(DE, g, k)
  455. init = {}
  456. for i in range(len(Add.make_args(RE))):
  457. if i:
  458. f = f.diff(x)
  459. init[g(k).subs(k, i)] = f.limit(x, 0)
  460. sol = rsolve(RE, g(k), init)
  461. if sol:
  462. return (sol / factorial(k), S.Zero, S.Zero)
  463. def _solve_simple(f, x, DE, g, k):
  464. """Converts DE into RE and solves using :func:`rsolve`."""
  465. from sympy.solvers import rsolve
  466. RE = hyper_re(DE, g, k)
  467. init = {}
  468. for i in range(len(Add.make_args(RE))):
  469. if i:
  470. f = f.diff(x)
  471. init[g(k).subs(k, i)] = f.limit(x, 0) / factorial(i)
  472. sol = rsolve(RE, g(k), init)
  473. if sol:
  474. return (sol, S.Zero, S.Zero)
  475. def _transform_explike_DE(DE, g, x, order, syms):
  476. """Converts DE with free parameters into DE with constant coefficients."""
  477. from sympy.solvers.solveset import linsolve
  478. eq = []
  479. highest_coeff = DE.coeff(Derivative(g(x), x, order))
  480. for i in range(order):
  481. coeff = DE.coeff(Derivative(g(x), x, i))
  482. coeff = (coeff / highest_coeff).expand().collect(x)
  483. for t in Add.make_args(coeff):
  484. eq.append(t)
  485. temp = []
  486. for e in eq:
  487. if e.has(x):
  488. break
  489. elif e.has(Symbol):
  490. temp.append(e)
  491. else:
  492. eq = temp
  493. if eq:
  494. sol = dict(zip(syms, (i for s in linsolve(eq, list(syms)) for i in s)))
  495. if sol:
  496. DE = DE.subs(sol)
  497. DE = DE.factor().as_coeff_mul(Derivative)[1][0]
  498. DE = DE.collect(Derivative(g(x)))
  499. return DE
  500. def _transform_DE_RE(DE, g, k, order, syms):
  501. """Converts DE with free parameters into RE of hypergeometric type."""
  502. from sympy.solvers.solveset import linsolve
  503. RE = hyper_re(DE, g, k)
  504. eq = []
  505. for i in range(1, order):
  506. coeff = RE.coeff(g(k + i))
  507. eq.append(coeff)
  508. sol = dict(zip(syms, (i for s in linsolve(eq, list(syms)) for i in s)))
  509. if sol:
  510. m = Wild('m')
  511. RE = RE.subs(sol)
  512. RE = RE.factor().as_numer_denom()[0].collect(g(k + m))
  513. RE = RE.as_coeff_mul(g)[1][0]
  514. for i in range(order): # smallest order should be g(k)
  515. if RE.coeff(g(k + i)) and i:
  516. RE = RE.subs(k, k - i)
  517. break
  518. return RE
  519. def solve_de(f, x, DE, order, g, k):
  520. """
  521. Solves the DE.
  522. Explanation
  523. ===========
  524. Tries to solve DE by either converting into a RE containing two terms or
  525. converting into a DE having constant coefficients.
  526. Returns
  527. =======
  528. formula : Expr
  529. ind : Expr
  530. Independent terms.
  531. order : int
  532. Examples
  533. ========
  534. >>> from sympy import Derivative as D, Function
  535. >>> from sympy import exp, ln
  536. >>> from sympy.series.formal import solve_de
  537. >>> from sympy.abc import x, k
  538. >>> f = Function('f')
  539. >>> solve_de(exp(x), x, D(f(x), x) - f(x), 1, f, k)
  540. (Piecewise((1/factorial(k), Eq(Mod(k, 1), 0)), (0, True)), 1, 1)
  541. >>> solve_de(ln(1 + x), x, (x + 1)*D(f(x), x, 2) + D(f(x)), 2, f, k)
  542. (Piecewise(((-1)**(k - 1)*factorial(k - 1)/RisingFactorial(2, k - 1),
  543. Eq(Mod(k, 1), 0)), (0, True)), x, 2)
  544. """
  545. sol = None
  546. syms = DE.free_symbols.difference({g, x})
  547. if syms:
  548. RE = _transform_DE_RE(DE, g, k, order, syms)
  549. else:
  550. RE = hyper_re(DE, g, k)
  551. if not RE.free_symbols.difference({k}):
  552. sol = _solve_hyper_RE(f, x, RE, g, k)
  553. if sol:
  554. return sol
  555. if syms:
  556. DE = _transform_explike_DE(DE, g, x, order, syms)
  557. if not DE.free_symbols.difference({x}):
  558. sol = _solve_explike_DE(f, x, DE, g, k)
  559. if sol:
  560. return sol
  561. def hyper_algorithm(f, x, k, order=4):
  562. """
  563. Hypergeometric algorithm for computing Formal Power Series.
  564. Explanation
  565. ===========
  566. Steps:
  567. * Generates DE
  568. * Convert the DE into RE
  569. * Solves the RE
  570. Examples
  571. ========
  572. >>> from sympy import exp, ln
  573. >>> from sympy.series.formal import hyper_algorithm
  574. >>> from sympy.abc import x, k
  575. >>> hyper_algorithm(exp(x), x, k)
  576. (Piecewise((1/factorial(k), Eq(Mod(k, 1), 0)), (0, True)), 1, 1)
  577. >>> hyper_algorithm(ln(1 + x), x, k)
  578. (Piecewise(((-1)**(k - 1)*factorial(k - 1)/RisingFactorial(2, k - 1),
  579. Eq(Mod(k, 1), 0)), (0, True)), x, 2)
  580. See Also
  581. ========
  582. sympy.series.formal.simpleDE
  583. sympy.series.formal.solve_de
  584. """
  585. g = Function('g')
  586. des = [] # list of DE's
  587. sol = None
  588. for DE, i in simpleDE(f, x, g, order):
  589. if DE is not None:
  590. sol = solve_de(f, x, DE, i, g, k)
  591. if sol:
  592. return sol
  593. if not DE.free_symbols.difference({x}):
  594. des.append(DE)
  595. # If nothing works
  596. # Try plain rsolve
  597. for DE in des:
  598. sol = _solve_simple(f, x, DE, g, k)
  599. if sol:
  600. return sol
  601. def _compute_fps(f, x, x0, dir, hyper, order, rational, full):
  602. """Recursive wrapper to compute fps.
  603. See :func:`compute_fps` for details.
  604. """
  605. if x0 in [S.Infinity, S.NegativeInfinity]:
  606. dir = S.One if x0 is S.Infinity else -S.One
  607. temp = f.subs(x, 1/x)
  608. result = _compute_fps(temp, x, 0, dir, hyper, order, rational, full)
  609. if result is None:
  610. return None
  611. return (result[0], result[1].subs(x, 1/x), result[2].subs(x, 1/x))
  612. elif x0 or dir == -S.One:
  613. if dir == -S.One:
  614. rep = -x + x0
  615. rep2 = -x
  616. rep2b = x0
  617. else:
  618. rep = x + x0
  619. rep2 = x
  620. rep2b = -x0
  621. temp = f.subs(x, rep)
  622. result = _compute_fps(temp, x, 0, S.One, hyper, order, rational, full)
  623. if result is None:
  624. return None
  625. return (result[0], result[1].subs(x, rep2 + rep2b),
  626. result[2].subs(x, rep2 + rep2b))
  627. if f.is_polynomial(x):
  628. k = Dummy('k')
  629. ak = sequence(Coeff(f, x, k), (k, 1, oo))
  630. xk = sequence(x**k, (k, 0, oo))
  631. ind = f.coeff(x, 0)
  632. return ak, xk, ind
  633. # Break instances of Add
  634. # this allows application of different
  635. # algorithms on different terms increasing the
  636. # range of admissible functions.
  637. if isinstance(f, Add):
  638. result = False
  639. ak = sequence(S.Zero, (0, oo))
  640. ind, xk = S.Zero, None
  641. for t in Add.make_args(f):
  642. res = _compute_fps(t, x, 0, S.One, hyper, order, rational, full)
  643. if res:
  644. if not result:
  645. result = True
  646. xk = res[1]
  647. if res[0].start > ak.start:
  648. seq = ak
  649. s, f = ak.start, res[0].start
  650. else:
  651. seq = res[0]
  652. s, f = res[0].start, ak.start
  653. save = Add(*[z[0]*z[1] for z in zip(seq[0:(f - s)], xk[s:f])])
  654. ak += res[0]
  655. ind += res[2] + save
  656. else:
  657. ind += t
  658. if result:
  659. return ak, xk, ind
  660. return None
  661. # The symbolic term - symb, if present, is being separated from the function
  662. # Otherwise symb is being set to S.One
  663. syms = f.free_symbols.difference({x})
  664. (f, symb) = expand(f).as_independent(*syms)
  665. result = None
  666. # from here on it's x0=0 and dir=1 handling
  667. k = Dummy('k')
  668. if rational:
  669. result = rational_algorithm(f, x, k, order, full)
  670. if result is None and hyper:
  671. result = hyper_algorithm(f, x, k, order)
  672. if result is None:
  673. return None
  674. from sympy.simplify.powsimp import powsimp
  675. if symb.is_zero:
  676. symb = S.One
  677. else:
  678. symb = powsimp(symb)
  679. ak = sequence(result[0], (k, result[2], oo))
  680. xk_formula = powsimp(x**k * symb)
  681. xk = sequence(xk_formula, (k, 0, oo))
  682. ind = powsimp(result[1] * symb)
  683. return ak, xk, ind
  684. def compute_fps(f, x, x0=0, dir=1, hyper=True, order=4, rational=True,
  685. full=False):
  686. """
  687. Computes the formula for Formal Power Series of a function.
  688. Explanation
  689. ===========
  690. Tries to compute the formula by applying the following techniques
  691. (in order):
  692. * rational_algorithm
  693. * Hypergeometric algorithm
  694. Parameters
  695. ==========
  696. x : Symbol
  697. x0 : number, optional
  698. Point to perform series expansion about. Default is 0.
  699. dir : {1, -1, '+', '-'}, optional
  700. If dir is 1 or '+' the series is calculated from the right and
  701. for -1 or '-' the series is calculated from the left. For smooth
  702. functions this flag will not alter the results. Default is 1.
  703. hyper : {True, False}, optional
  704. Set hyper to False to skip the hypergeometric algorithm.
  705. By default it is set to False.
  706. order : int, optional
  707. Order of the derivative of ``f``, Default is 4.
  708. rational : {True, False}, optional
  709. Set rational to False to skip rational algorithm. By default it is set
  710. to True.
  711. full : {True, False}, optional
  712. Set full to True to increase the range of rational algorithm.
  713. See :func:`rational_algorithm` for details. By default it is set to
  714. False.
  715. Returns
  716. =======
  717. ak : sequence
  718. Sequence of coefficients.
  719. xk : sequence
  720. Sequence of powers of x.
  721. ind : Expr
  722. Independent terms.
  723. mul : Pow
  724. Common terms.
  725. See Also
  726. ========
  727. sympy.series.formal.rational_algorithm
  728. sympy.series.formal.hyper_algorithm
  729. """
  730. f = sympify(f)
  731. x = sympify(x)
  732. if not f.has(x):
  733. return None
  734. x0 = sympify(x0)
  735. if dir == '+':
  736. dir = S.One
  737. elif dir == '-':
  738. dir = -S.One
  739. elif dir not in [S.One, -S.One]:
  740. raise ValueError("Dir must be '+' or '-'")
  741. else:
  742. dir = sympify(dir)
  743. return _compute_fps(f, x, x0, dir, hyper, order, rational, full)
  744. class Coeff(Function):
  745. """
  746. Coeff(p, x, n) represents the nth coefficient of the polynomial p in x
  747. """
  748. @classmethod
  749. def eval(cls, p, x, n):
  750. if p.is_polynomial(x) and n.is_integer:
  751. return p.coeff(x, n)
  752. class FormalPowerSeries(SeriesBase):
  753. """
  754. Represents Formal Power Series of a function.
  755. Explanation
  756. ===========
  757. No computation is performed. This class should only to be used to represent
  758. a series. No checks are performed.
  759. For computing a series use :func:`fps`.
  760. See Also
  761. ========
  762. sympy.series.formal.fps
  763. """
  764. def __new__(cls, *args):
  765. args = map(sympify, args)
  766. return Expr.__new__(cls, *args)
  767. def __init__(self, *args):
  768. ak = args[4][0]
  769. k = ak.variables[0]
  770. self.ak_seq = sequence(ak.formula, (k, 1, oo))
  771. self.fact_seq = sequence(factorial(k), (k, 1, oo))
  772. self.bell_coeff_seq = self.ak_seq * self.fact_seq
  773. self.sign_seq = sequence((-1, 1), (k, 1, oo))
  774. @property
  775. def function(self):
  776. return self.args[0]
  777. @property
  778. def x(self):
  779. return self.args[1]
  780. @property
  781. def x0(self):
  782. return self.args[2]
  783. @property
  784. def dir(self):
  785. return self.args[3]
  786. @property
  787. def ak(self):
  788. return self.args[4][0]
  789. @property
  790. def xk(self):
  791. return self.args[4][1]
  792. @property
  793. def ind(self):
  794. return self.args[4][2]
  795. @property
  796. def interval(self):
  797. return Interval(0, oo)
  798. @property
  799. def start(self):
  800. return self.interval.inf
  801. @property
  802. def stop(self):
  803. return self.interval.sup
  804. @property
  805. def length(self):
  806. return oo
  807. @property
  808. def infinite(self):
  809. """Returns an infinite representation of the series"""
  810. from sympy.concrete import Sum
  811. ak, xk = self.ak, self.xk
  812. k = ak.variables[0]
  813. inf_sum = Sum(ak.formula * xk.formula, (k, ak.start, ak.stop))
  814. return self.ind + inf_sum
  815. def _get_pow_x(self, term):
  816. """Returns the power of x in a term."""
  817. xterm, pow_x = term.as_independent(self.x)[1].as_base_exp()
  818. if not xterm.has(self.x):
  819. return S.Zero
  820. return pow_x
  821. def polynomial(self, n=6):
  822. """
  823. Truncated series as polynomial.
  824. Explanation
  825. ===========
  826. Returns series expansion of ``f`` upto order ``O(x**n)``
  827. as a polynomial(without ``O`` term).
  828. """
  829. terms = []
  830. sym = self.free_symbols
  831. for i, t in enumerate(self):
  832. xp = self._get_pow_x(t)
  833. if xp.has(*sym):
  834. xp = xp.as_coeff_add(*sym)[0]
  835. if xp >= n:
  836. break
  837. elif xp.is_integer is True and i == n + 1:
  838. break
  839. elif t is not S.Zero:
  840. terms.append(t)
  841. return Add(*terms)
  842. def truncate(self, n=6):
  843. """
  844. Truncated series.
  845. Explanation
  846. ===========
  847. Returns truncated series expansion of f upto
  848. order ``O(x**n)``.
  849. If n is ``None``, returns an infinite iterator.
  850. """
  851. if n is None:
  852. return iter(self)
  853. x, x0 = self.x, self.x0
  854. pt_xk = self.xk.coeff(n)
  855. if x0 is S.NegativeInfinity:
  856. x0 = S.Infinity
  857. return self.polynomial(n) + Order(pt_xk, (x, x0))
  858. def zero_coeff(self):
  859. return self._eval_term(0)
  860. def _eval_term(self, pt):
  861. try:
  862. pt_xk = self.xk.coeff(pt)
  863. pt_ak = self.ak.coeff(pt).simplify() # Simplify the coefficients
  864. except IndexError:
  865. term = S.Zero
  866. else:
  867. term = (pt_ak * pt_xk)
  868. if self.ind:
  869. ind = S.Zero
  870. sym = self.free_symbols
  871. for t in Add.make_args(self.ind):
  872. pow_x = self._get_pow_x(t)
  873. if pow_x.has(*sym):
  874. pow_x = pow_x.as_coeff_add(*sym)[0]
  875. if pt == 0 and pow_x < 1:
  876. ind += t
  877. elif pow_x >= pt and pow_x < pt + 1:
  878. ind += t
  879. term += ind
  880. return term.collect(self.x)
  881. def _eval_subs(self, old, new):
  882. x = self.x
  883. if old.has(x):
  884. return self
  885. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  886. for t in self:
  887. if t is not S.Zero:
  888. return t
  889. def _eval_derivative(self, x):
  890. f = self.function.diff(x)
  891. ind = self.ind.diff(x)
  892. pow_xk = self._get_pow_x(self.xk.formula)
  893. ak = self.ak
  894. k = ak.variables[0]
  895. if ak.formula.has(x):
  896. form = []
  897. for e, c in ak.formula.args:
  898. temp = S.Zero
  899. for t in Add.make_args(e):
  900. pow_x = self._get_pow_x(t)
  901. temp += t * (pow_xk + pow_x)
  902. form.append((temp, c))
  903. form = Piecewise(*form)
  904. ak = sequence(form.subs(k, k + 1), (k, ak.start - 1, ak.stop))
  905. else:
  906. ak = sequence((ak.formula * pow_xk).subs(k, k + 1),
  907. (k, ak.start - 1, ak.stop))
  908. return self.func(f, self.x, self.x0, self.dir, (ak, self.xk, ind))
  909. def integrate(self, x=None, **kwargs):
  910. """
  911. Integrate Formal Power Series.
  912. Examples
  913. ========
  914. >>> from sympy import fps, sin, integrate
  915. >>> from sympy.abc import x
  916. >>> f = fps(sin(x))
  917. >>> f.integrate(x).truncate()
  918. -1 + x**2/2 - x**4/24 + O(x**6)
  919. >>> integrate(f, (x, 0, 1))
  920. 1 - cos(1)
  921. """
  922. from sympy.integrals import integrate
  923. if x is None:
  924. x = self.x
  925. elif iterable(x):
  926. return integrate(self.function, x)
  927. f = integrate(self.function, x)
  928. ind = integrate(self.ind, x)
  929. ind += (f - ind).limit(x, 0) # constant of integration
  930. pow_xk = self._get_pow_x(self.xk.formula)
  931. ak = self.ak
  932. k = ak.variables[0]
  933. if ak.formula.has(x):
  934. form = []
  935. for e, c in ak.formula.args:
  936. temp = S.Zero
  937. for t in Add.make_args(e):
  938. pow_x = self._get_pow_x(t)
  939. temp += t / (pow_xk + pow_x + 1)
  940. form.append((temp, c))
  941. form = Piecewise(*form)
  942. ak = sequence(form.subs(k, k - 1), (k, ak.start + 1, ak.stop))
  943. else:
  944. ak = sequence((ak.formula / (pow_xk + 1)).subs(k, k - 1),
  945. (k, ak.start + 1, ak.stop))
  946. return self.func(f, self.x, self.x0, self.dir, (ak, self.xk, ind))
  947. def product(self, other, x=None, n=6):
  948. """
  949. Multiplies two Formal Power Series, using discrete convolution and
  950. return the truncated terms upto specified order.
  951. Parameters
  952. ==========
  953. n : Number, optional
  954. Specifies the order of the term up to which the polynomial should
  955. be truncated.
  956. Examples
  957. ========
  958. >>> from sympy import fps, sin, exp
  959. >>> from sympy.abc import x
  960. >>> f1 = fps(sin(x))
  961. >>> f2 = fps(exp(x))
  962. >>> f1.product(f2, x).truncate(4)
  963. x + x**2 + x**3/3 + O(x**4)
  964. See Also
  965. ========
  966. sympy.discrete.convolutions
  967. sympy.series.formal.FormalPowerSeriesProduct
  968. """
  969. if n is None:
  970. return iter(self)
  971. other = sympify(other)
  972. if not isinstance(other, FormalPowerSeries):
  973. raise ValueError("Both series should be an instance of FormalPowerSeries"
  974. " class.")
  975. if self.dir != other.dir:
  976. raise ValueError("Both series should be calculated from the"
  977. " same direction.")
  978. elif self.x0 != other.x0:
  979. raise ValueError("Both series should be calculated about the"
  980. " same point.")
  981. elif self.x != other.x:
  982. raise ValueError("Both series should have the same symbol.")
  983. return FormalPowerSeriesProduct(self, other)
  984. def coeff_bell(self, n):
  985. r"""
  986. self.coeff_bell(n) returns a sequence of Bell polynomials of the second kind.
  987. Note that ``n`` should be a integer.
  988. The second kind of Bell polynomials (are sometimes called "partial" Bell
  989. polynomials or incomplete Bell polynomials) are defined as
  990. .. math::
  991. B_{n,k}(x_1, x_2,\dotsc x_{n-k+1}) =
  992. \sum_{j_1+j_2+j_2+\dotsb=k \atop j_1+2j_2+3j_2+\dotsb=n}
  993. \frac{n!}{j_1!j_2!\dotsb j_{n-k+1}!}
  994. \left(\frac{x_1}{1!} \right)^{j_1}
  995. \left(\frac{x_2}{2!} \right)^{j_2} \dotsb
  996. \left(\frac{x_{n-k+1}}{(n-k+1)!} \right) ^{j_{n-k+1}}.
  997. * ``bell(n, k, (x1, x2, ...))`` gives Bell polynomials of the second kind,
  998. `B_{n,k}(x_1, x_2, \dotsc, x_{n-k+1})`.
  999. See Also
  1000. ========
  1001. sympy.functions.combinatorial.numbers.bell
  1002. """
  1003. inner_coeffs = [bell(n, j, tuple(self.bell_coeff_seq[:n-j+1])) for j in range(1, n+1)]
  1004. k = Dummy('k')
  1005. return sequence(tuple(inner_coeffs), (k, 1, oo))
  1006. def compose(self, other, x=None, n=6):
  1007. r"""
  1008. Returns the truncated terms of the formal power series of the composed function,
  1009. up to specified ``n``.
  1010. Explanation
  1011. ===========
  1012. If ``f`` and ``g`` are two formal power series of two different functions,
  1013. then the coefficient sequence ``ak`` of the composed formal power series `fp`
  1014. will be as follows.
  1015. .. math::
  1016. \sum\limits_{k=0}^{n} b_k B_{n,k}(x_1, x_2, \dotsc, x_{n-k+1})
  1017. Parameters
  1018. ==========
  1019. n : Number, optional
  1020. Specifies the order of the term up to which the polynomial should
  1021. be truncated.
  1022. Examples
  1023. ========
  1024. >>> from sympy import fps, sin, exp
  1025. >>> from sympy.abc import x
  1026. >>> f1 = fps(exp(x))
  1027. >>> f2 = fps(sin(x))
  1028. >>> f1.compose(f2, x).truncate()
  1029. 1 + x + x**2/2 - x**4/8 - x**5/15 + O(x**6)
  1030. >>> f1.compose(f2, x).truncate(8)
  1031. 1 + x + x**2/2 - x**4/8 - x**5/15 - x**6/240 + x**7/90 + O(x**8)
  1032. See Also
  1033. ========
  1034. sympy.functions.combinatorial.numbers.bell
  1035. sympy.series.formal.FormalPowerSeriesCompose
  1036. References
  1037. ==========
  1038. .. [1] Comtet, Louis: Advanced combinatorics; the art of finite and infinite expansions. Reidel, 1974.
  1039. """
  1040. if n is None:
  1041. return iter(self)
  1042. other = sympify(other)
  1043. if not isinstance(other, FormalPowerSeries):
  1044. raise ValueError("Both series should be an instance of FormalPowerSeries"
  1045. " class.")
  1046. if self.dir != other.dir:
  1047. raise ValueError("Both series should be calculated from the"
  1048. " same direction.")
  1049. elif self.x0 != other.x0:
  1050. raise ValueError("Both series should be calculated about the"
  1051. " same point.")
  1052. elif self.x != other.x:
  1053. raise ValueError("Both series should have the same symbol.")
  1054. if other._eval_term(0).as_coeff_mul(other.x)[0] is not S.Zero:
  1055. raise ValueError("The formal power series of the inner function should not have any "
  1056. "constant coefficient term.")
  1057. return FormalPowerSeriesCompose(self, other)
  1058. def inverse(self, x=None, n=6):
  1059. r"""
  1060. Returns the truncated terms of the inverse of the formal power series,
  1061. up to specified ``n``.
  1062. Explanation
  1063. ===========
  1064. If ``f`` and ``g`` are two formal power series of two different functions,
  1065. then the coefficient sequence ``ak`` of the composed formal power series ``fp``
  1066. will be as follows.
  1067. .. math::
  1068. \sum\limits_{k=0}^{n} (-1)^{k} x_0^{-k-1} B_{n,k}(x_1, x_2, \dotsc, x_{n-k+1})
  1069. Parameters
  1070. ==========
  1071. n : Number, optional
  1072. Specifies the order of the term up to which the polynomial should
  1073. be truncated.
  1074. Examples
  1075. ========
  1076. >>> from sympy import fps, exp, cos
  1077. >>> from sympy.abc import x
  1078. >>> f1 = fps(exp(x))
  1079. >>> f2 = fps(cos(x))
  1080. >>> f1.inverse(x).truncate()
  1081. 1 - x + x**2/2 - x**3/6 + x**4/24 - x**5/120 + O(x**6)
  1082. >>> f2.inverse(x).truncate(8)
  1083. 1 + x**2/2 + 5*x**4/24 + 61*x**6/720 + O(x**8)
  1084. See Also
  1085. ========
  1086. sympy.functions.combinatorial.numbers.bell
  1087. sympy.series.formal.FormalPowerSeriesInverse
  1088. References
  1089. ==========
  1090. .. [1] Comtet, Louis: Advanced combinatorics; the art of finite and infinite expansions. Reidel, 1974.
  1091. """
  1092. if n is None:
  1093. return iter(self)
  1094. if self._eval_term(0).is_zero:
  1095. raise ValueError("Constant coefficient should exist for an inverse of a formal"
  1096. " power series to exist.")
  1097. return FormalPowerSeriesInverse(self)
  1098. def __add__(self, other):
  1099. other = sympify(other)
  1100. if isinstance(other, FormalPowerSeries):
  1101. if self.dir != other.dir:
  1102. raise ValueError("Both series should be calculated from the"
  1103. " same direction.")
  1104. elif self.x0 != other.x0:
  1105. raise ValueError("Both series should be calculated about the"
  1106. " same point.")
  1107. x, y = self.x, other.x
  1108. f = self.function + other.function.subs(y, x)
  1109. if self.x not in f.free_symbols:
  1110. return f
  1111. ak = self.ak + other.ak
  1112. if self.ak.start > other.ak.start:
  1113. seq = other.ak
  1114. s, e = other.ak.start, self.ak.start
  1115. else:
  1116. seq = self.ak
  1117. s, e = self.ak.start, other.ak.start
  1118. save = Add(*[z[0]*z[1] for z in zip(seq[0:(e - s)], self.xk[s:e])])
  1119. ind = self.ind + other.ind + save
  1120. return self.func(f, x, self.x0, self.dir, (ak, self.xk, ind))
  1121. elif not other.has(self.x):
  1122. f = self.function + other
  1123. ind = self.ind + other
  1124. return self.func(f, self.x, self.x0, self.dir,
  1125. (self.ak, self.xk, ind))
  1126. return Add(self, other)
  1127. def __radd__(self, other):
  1128. return self.__add__(other)
  1129. def __neg__(self):
  1130. return self.func(-self.function, self.x, self.x0, self.dir,
  1131. (-self.ak, self.xk, -self.ind))
  1132. def __sub__(self, other):
  1133. return self.__add__(-other)
  1134. def __rsub__(self, other):
  1135. return (-self).__add__(other)
  1136. def __mul__(self, other):
  1137. other = sympify(other)
  1138. if other.has(self.x):
  1139. return Mul(self, other)
  1140. f = self.function * other
  1141. ak = self.ak.coeff_mul(other)
  1142. ind = self.ind * other
  1143. return self.func(f, self.x, self.x0, self.dir, (ak, self.xk, ind))
  1144. def __rmul__(self, other):
  1145. return self.__mul__(other)
  1146. class FiniteFormalPowerSeries(FormalPowerSeries):
  1147. """Base Class for Product, Compose and Inverse classes"""
  1148. def __init__(self, *args):
  1149. pass
  1150. @property
  1151. def ffps(self):
  1152. return self.args[0]
  1153. @property
  1154. def gfps(self):
  1155. return self.args[1]
  1156. @property
  1157. def f(self):
  1158. return self.ffps.function
  1159. @property
  1160. def g(self):
  1161. return self.gfps.function
  1162. @property
  1163. def infinite(self):
  1164. raise NotImplementedError("No infinite version for an object of"
  1165. " FiniteFormalPowerSeries class.")
  1166. def _eval_terms(self, n):
  1167. raise NotImplementedError("(%s)._eval_terms()" % self)
  1168. def _eval_term(self, pt):
  1169. raise NotImplementedError("By the current logic, one can get terms"
  1170. "upto a certain order, instead of getting term by term.")
  1171. def polynomial(self, n):
  1172. return self._eval_terms(n)
  1173. def truncate(self, n=6):
  1174. ffps = self.ffps
  1175. pt_xk = ffps.xk.coeff(n)
  1176. x, x0 = ffps.x, ffps.x0
  1177. return self.polynomial(n) + Order(pt_xk, (x, x0))
  1178. def _eval_derivative(self, x):
  1179. raise NotImplementedError
  1180. def integrate(self, x):
  1181. raise NotImplementedError
  1182. class FormalPowerSeriesProduct(FiniteFormalPowerSeries):
  1183. """Represents the product of two formal power series of two functions.
  1184. Explanation
  1185. ===========
  1186. No computation is performed. Terms are calculated using a term by term logic,
  1187. instead of a point by point logic.
  1188. There are two differences between a :obj:`FormalPowerSeries` object and a
  1189. :obj:`FormalPowerSeriesProduct` object. The first argument contains the two
  1190. functions involved in the product. Also, the coefficient sequence contains
  1191. both the coefficient sequence of the formal power series of the involved functions.
  1192. See Also
  1193. ========
  1194. sympy.series.formal.FormalPowerSeries
  1195. sympy.series.formal.FiniteFormalPowerSeries
  1196. """
  1197. def __init__(self, *args):
  1198. ffps, gfps = self.ffps, self.gfps
  1199. k = ffps.ak.variables[0]
  1200. self.coeff1 = sequence(ffps.ak.formula, (k, 0, oo))
  1201. k = gfps.ak.variables[0]
  1202. self.coeff2 = sequence(gfps.ak.formula, (k, 0, oo))
  1203. @property
  1204. def function(self):
  1205. """Function of the product of two formal power series."""
  1206. return self.f * self.g
  1207. def _eval_terms(self, n):
  1208. """
  1209. Returns the first ``n`` terms of the product formal power series.
  1210. Term by term logic is implemented here.
  1211. Examples
  1212. ========
  1213. >>> from sympy import fps, sin, exp
  1214. >>> from sympy.abc import x
  1215. >>> f1 = fps(sin(x))
  1216. >>> f2 = fps(exp(x))
  1217. >>> fprod = f1.product(f2, x)
  1218. >>> fprod._eval_terms(4)
  1219. x**3/3 + x**2 + x
  1220. See Also
  1221. ========
  1222. sympy.series.formal.FormalPowerSeries.product
  1223. """
  1224. coeff1, coeff2 = self.coeff1, self.coeff2
  1225. aks = convolution(coeff1[:n], coeff2[:n])
  1226. terms = []
  1227. for i in range(0, n):
  1228. terms.append(aks[i] * self.ffps.xk.coeff(i))
  1229. return Add(*terms)
  1230. class FormalPowerSeriesCompose(FiniteFormalPowerSeries):
  1231. """
  1232. Represents the composed formal power series of two functions.
  1233. Explanation
  1234. ===========
  1235. No computation is performed. Terms are calculated using a term by term logic,
  1236. instead of a point by point logic.
  1237. There are two differences between a :obj:`FormalPowerSeries` object and a
  1238. :obj:`FormalPowerSeriesCompose` object. The first argument contains the outer
  1239. function and the inner function involved in the omposition. Also, the
  1240. coefficient sequence contains the generic sequence which is to be multiplied
  1241. by a custom ``bell_seq`` finite sequence. The finite terms will then be added up to
  1242. get the final terms.
  1243. See Also
  1244. ========
  1245. sympy.series.formal.FormalPowerSeries
  1246. sympy.series.formal.FiniteFormalPowerSeries
  1247. """
  1248. @property
  1249. def function(self):
  1250. """Function for the composed formal power series."""
  1251. f, g, x = self.f, self.g, self.ffps.x
  1252. return f.subs(x, g)
  1253. def _eval_terms(self, n):
  1254. """
  1255. Returns the first `n` terms of the composed formal power series.
  1256. Term by term logic is implemented here.
  1257. Explanation
  1258. ===========
  1259. The coefficient sequence of the :obj:`FormalPowerSeriesCompose` object is the generic sequence.
  1260. It is multiplied by ``bell_seq`` to get a sequence, whose terms are added up to get
  1261. the final terms for the polynomial.
  1262. Examples
  1263. ========
  1264. >>> from sympy import fps, sin, exp
  1265. >>> from sympy.abc import x
  1266. >>> f1 = fps(exp(x))
  1267. >>> f2 = fps(sin(x))
  1268. >>> fcomp = f1.compose(f2, x)
  1269. >>> fcomp._eval_terms(6)
  1270. -x**5/15 - x**4/8 + x**2/2 + x + 1
  1271. >>> fcomp._eval_terms(8)
  1272. x**7/90 - x**6/240 - x**5/15 - x**4/8 + x**2/2 + x + 1
  1273. See Also
  1274. ========
  1275. sympy.series.formal.FormalPowerSeries.compose
  1276. sympy.series.formal.FormalPowerSeries.coeff_bell
  1277. """
  1278. ffps, gfps = self.ffps, self.gfps
  1279. terms = [ffps.zero_coeff()]
  1280. for i in range(1, n):
  1281. bell_seq = gfps.coeff_bell(i)
  1282. seq = (ffps.bell_coeff_seq * bell_seq)
  1283. terms.append(Add(*(seq[:i])) / ffps.fact_seq[i-1] * ffps.xk.coeff(i))
  1284. return Add(*terms)
  1285. class FormalPowerSeriesInverse(FiniteFormalPowerSeries):
  1286. """
  1287. Represents the Inverse of a formal power series.
  1288. Explanation
  1289. ===========
  1290. No computation is performed. Terms are calculated using a term by term logic,
  1291. instead of a point by point logic.
  1292. There is a single difference between a :obj:`FormalPowerSeries` object and a
  1293. :obj:`FormalPowerSeriesInverse` object. The coefficient sequence contains the
  1294. generic sequence which is to be multiplied by a custom ``bell_seq`` finite sequence.
  1295. The finite terms will then be added up to get the final terms.
  1296. See Also
  1297. ========
  1298. sympy.series.formal.FormalPowerSeries
  1299. sympy.series.formal.FiniteFormalPowerSeries
  1300. """
  1301. def __init__(self, *args):
  1302. ffps = self.ffps
  1303. k = ffps.xk.variables[0]
  1304. inv = ffps.zero_coeff()
  1305. inv_seq = sequence(inv ** (-(k + 1)), (k, 1, oo))
  1306. self.aux_seq = ffps.sign_seq * ffps.fact_seq * inv_seq
  1307. @property
  1308. def function(self):
  1309. """Function for the inverse of a formal power series."""
  1310. f = self.f
  1311. return 1 / f
  1312. @property
  1313. def g(self):
  1314. raise ValueError("Only one function is considered while performing"
  1315. "inverse of a formal power series.")
  1316. @property
  1317. def gfps(self):
  1318. raise ValueError("Only one function is considered while performing"
  1319. "inverse of a formal power series.")
  1320. def _eval_terms(self, n):
  1321. """
  1322. Returns the first ``n`` terms of the composed formal power series.
  1323. Term by term logic is implemented here.
  1324. Explanation
  1325. ===========
  1326. The coefficient sequence of the `FormalPowerSeriesInverse` object is the generic sequence.
  1327. It is multiplied by ``bell_seq`` to get a sequence, whose terms are added up to get
  1328. the final terms for the polynomial.
  1329. Examples
  1330. ========
  1331. >>> from sympy import fps, exp, cos
  1332. >>> from sympy.abc import x
  1333. >>> f1 = fps(exp(x))
  1334. >>> f2 = fps(cos(x))
  1335. >>> finv1, finv2 = f1.inverse(), f2.inverse()
  1336. >>> finv1._eval_terms(6)
  1337. -x**5/120 + x**4/24 - x**3/6 + x**2/2 - x + 1
  1338. >>> finv2._eval_terms(8)
  1339. 61*x**6/720 + 5*x**4/24 + x**2/2 + 1
  1340. See Also
  1341. ========
  1342. sympy.series.formal.FormalPowerSeries.inverse
  1343. sympy.series.formal.FormalPowerSeries.coeff_bell
  1344. """
  1345. ffps = self.ffps
  1346. terms = [ffps.zero_coeff()]
  1347. for i in range(1, n):
  1348. bell_seq = ffps.coeff_bell(i)
  1349. seq = (self.aux_seq * bell_seq)
  1350. terms.append(Add(*(seq[:i])) / ffps.fact_seq[i-1] * ffps.xk.coeff(i))
  1351. return Add(*terms)
  1352. def fps(f, x=None, x0=0, dir=1, hyper=True, order=4, rational=True, full=False):
  1353. """
  1354. Generates Formal Power Series of ``f``.
  1355. Explanation
  1356. ===========
  1357. Returns the formal series expansion of ``f`` around ``x = x0``
  1358. with respect to ``x`` in the form of a ``FormalPowerSeries`` object.
  1359. Formal Power Series is represented using an explicit formula
  1360. computed using different algorithms.
  1361. See :func:`compute_fps` for the more details regarding the computation
  1362. of formula.
  1363. Parameters
  1364. ==========
  1365. x : Symbol, optional
  1366. If x is None and ``f`` is univariate, the univariate symbols will be
  1367. supplied, otherwise an error will be raised.
  1368. x0 : number, optional
  1369. Point to perform series expansion about. Default is 0.
  1370. dir : {1, -1, '+', '-'}, optional
  1371. If dir is 1 or '+' the series is calculated from the right and
  1372. for -1 or '-' the series is calculated from the left. For smooth
  1373. functions this flag will not alter the results. Default is 1.
  1374. hyper : {True, False}, optional
  1375. Set hyper to False to skip the hypergeometric algorithm.
  1376. By default it is set to False.
  1377. order : int, optional
  1378. Order of the derivative of ``f``, Default is 4.
  1379. rational : {True, False}, optional
  1380. Set rational to False to skip rational algorithm. By default it is set
  1381. to True.
  1382. full : {True, False}, optional
  1383. Set full to True to increase the range of rational algorithm.
  1384. See :func:`rational_algorithm` for details. By default it is set to
  1385. False.
  1386. Examples
  1387. ========
  1388. >>> from sympy import fps, ln, atan, sin
  1389. >>> from sympy.abc import x, n
  1390. Rational Functions
  1391. >>> fps(ln(1 + x)).truncate()
  1392. x - x**2/2 + x**3/3 - x**4/4 + x**5/5 + O(x**6)
  1393. >>> fps(atan(x), full=True).truncate()
  1394. x - x**3/3 + x**5/5 + O(x**6)
  1395. Symbolic Functions
  1396. >>> fps(x**n*sin(x**2), x).truncate(8)
  1397. -x**(n + 6)/6 + x**(n + 2) + O(x**(n + 8))
  1398. See Also
  1399. ========
  1400. sympy.series.formal.FormalPowerSeries
  1401. sympy.series.formal.compute_fps
  1402. """
  1403. f = sympify(f)
  1404. if x is None:
  1405. free = f.free_symbols
  1406. if len(free) == 1:
  1407. x = free.pop()
  1408. elif not free:
  1409. return f
  1410. else:
  1411. raise NotImplementedError("multivariate formal power series")
  1412. result = compute_fps(f, x, x0, dir, hyper, order, rational, full)
  1413. if result is None:
  1414. return f
  1415. return FormalPowerSeries(f, x, x0, dir, result)