summations.py 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659
  1. from __future__ import annotations
  2. from sympy.calculus.singularities import is_decreasing
  3. from sympy.calculus.accumulationbounds import AccumulationBounds
  4. from .expr_with_intlimits import ExprWithIntLimits
  5. from .expr_with_limits import AddWithLimits
  6. from .gosper import gosper_sum
  7. from sympy.core.expr import Expr
  8. from sympy.core.add import Add
  9. from sympy.core.containers import Tuple
  10. from sympy.core.function import Derivative, expand
  11. from sympy.core.mul import Mul
  12. from sympy.core.numbers import Float, _illegal
  13. from sympy.core.relational import Eq
  14. from sympy.core.singleton import S
  15. from sympy.core.sorting import ordered
  16. from sympy.core.symbol import Dummy, Wild, Symbol, symbols
  17. from sympy.functions.combinatorial.factorials import factorial
  18. from sympy.functions.combinatorial.numbers import bernoulli, harmonic
  19. from sympy.functions.elementary.complexes import re
  20. from sympy.functions.elementary.exponential import exp, log
  21. from sympy.functions.elementary.piecewise import Piecewise
  22. from sympy.functions.elementary.trigonometric import cot, csc
  23. from sympy.functions.special.hyper import hyper
  24. from sympy.functions.special.tensor_functions import KroneckerDelta
  25. from sympy.functions.special.zeta_functions import zeta
  26. from sympy.integrals.integrals import Integral
  27. from sympy.logic.boolalg import And, Not
  28. from sympy.polys.partfrac import apart
  29. from sympy.polys.polyerrors import PolynomialError, PolificationFailed
  30. from sympy.polys.polytools import parallel_poly_from_expr, Poly, factor
  31. from sympy.polys.rationaltools import together
  32. from sympy.series.limitseq import limit_seq
  33. from sympy.series.order import O
  34. from sympy.series.residues import residue
  35. from sympy.sets.contains import Contains
  36. from sympy.sets.sets import FiniteSet, Interval
  37. from sympy.utilities.iterables import sift
  38. import itertools
  39. class Sum(AddWithLimits, ExprWithIntLimits):
  40. r"""
  41. Represents unevaluated summation.
  42. Explanation
  43. ===========
  44. ``Sum`` represents a finite or infinite series, with the first argument
  45. being the general form of terms in the series, and the second argument
  46. being ``(dummy_variable, start, end)``, with ``dummy_variable`` taking
  47. all integer values from ``start`` through ``end``. In accordance with
  48. long-standing mathematical convention, the end term is included in the
  49. summation.
  50. Finite sums
  51. ===========
  52. For finite sums (and sums with symbolic limits assumed to be finite) we
  53. follow the summation convention described by Karr [1], especially
  54. definition 3 of section 1.4. The sum:
  55. .. math::
  56. \sum_{m \leq i < n} f(i)
  57. has *the obvious meaning* for `m < n`, namely:
  58. .. math::
  59. \sum_{m \leq i < n} f(i) = f(m) + f(m+1) + \ldots + f(n-2) + f(n-1)
  60. with the upper limit value `f(n)` excluded. The sum over an empty set is
  61. zero if and only if `m = n`:
  62. .. math::
  63. \sum_{m \leq i < n} f(i) = 0 \quad \mathrm{for} \quad m = n
  64. Finally, for all other sums over empty sets we assume the following
  65. definition:
  66. .. math::
  67. \sum_{m \leq i < n} f(i) = - \sum_{n \leq i < m} f(i) \quad \mathrm{for} \quad m > n
  68. It is important to note that Karr defines all sums with the upper
  69. limit being exclusive. This is in contrast to the usual mathematical notation,
  70. but does not affect the summation convention. Indeed we have:
  71. .. math::
  72. \sum_{m \leq i < n} f(i) = \sum_{i = m}^{n - 1} f(i)
  73. where the difference in notation is intentional to emphasize the meaning,
  74. with limits typeset on the top being inclusive.
  75. Examples
  76. ========
  77. >>> from sympy.abc import i, k, m, n, x
  78. >>> from sympy import Sum, factorial, oo, IndexedBase, Function
  79. >>> Sum(k, (k, 1, m))
  80. Sum(k, (k, 1, m))
  81. >>> Sum(k, (k, 1, m)).doit()
  82. m**2/2 + m/2
  83. >>> Sum(k**2, (k, 1, m))
  84. Sum(k**2, (k, 1, m))
  85. >>> Sum(k**2, (k, 1, m)).doit()
  86. m**3/3 + m**2/2 + m/6
  87. >>> Sum(x**k, (k, 0, oo))
  88. Sum(x**k, (k, 0, oo))
  89. >>> Sum(x**k, (k, 0, oo)).doit()
  90. Piecewise((1/(1 - x), Abs(x) < 1), (Sum(x**k, (k, 0, oo)), True))
  91. >>> Sum(x**k/factorial(k), (k, 0, oo)).doit()
  92. exp(x)
  93. Here are examples to do summation with symbolic indices. You
  94. can use either Function of IndexedBase classes:
  95. >>> f = Function('f')
  96. >>> Sum(f(n), (n, 0, 3)).doit()
  97. f(0) + f(1) + f(2) + f(3)
  98. >>> Sum(f(n), (n, 0, oo)).doit()
  99. Sum(f(n), (n, 0, oo))
  100. >>> f = IndexedBase('f')
  101. >>> Sum(f[n]**2, (n, 0, 3)).doit()
  102. f[0]**2 + f[1]**2 + f[2]**2 + f[3]**2
  103. An example showing that the symbolic result of a summation is still
  104. valid for seemingly nonsensical values of the limits. Then the Karr
  105. convention allows us to give a perfectly valid interpretation to
  106. those sums by interchanging the limits according to the above rules:
  107. >>> S = Sum(i, (i, 1, n)).doit()
  108. >>> S
  109. n**2/2 + n/2
  110. >>> S.subs(n, -4)
  111. 6
  112. >>> Sum(i, (i, 1, -4)).doit()
  113. 6
  114. >>> Sum(-i, (i, -3, 0)).doit()
  115. 6
  116. An explicit example of the Karr summation convention:
  117. >>> S1 = Sum(i**2, (i, m, m+n-1)).doit()
  118. >>> S1
  119. m**2*n + m*n**2 - m*n + n**3/3 - n**2/2 + n/6
  120. >>> S2 = Sum(i**2, (i, m+n, m-1)).doit()
  121. >>> S2
  122. -m**2*n - m*n**2 + m*n - n**3/3 + n**2/2 - n/6
  123. >>> S1 + S2
  124. 0
  125. >>> S3 = Sum(i, (i, m, m-1)).doit()
  126. >>> S3
  127. 0
  128. See Also
  129. ========
  130. summation
  131. Product, sympy.concrete.products.product
  132. References
  133. ==========
  134. .. [1] Michael Karr, "Summation in Finite Terms", Journal of the ACM,
  135. Volume 28 Issue 2, April 1981, Pages 305-350
  136. https://dl.acm.org/doi/10.1145/322248.322255
  137. .. [2] https://en.wikipedia.org/wiki/Summation#Capital-sigma_notation
  138. .. [3] https://en.wikipedia.org/wiki/Empty_sum
  139. """
  140. __slots__ = ()
  141. limits: tuple[tuple[Symbol, Expr, Expr]]
  142. def __new__(cls, function, *symbols, **assumptions):
  143. obj = AddWithLimits.__new__(cls, function, *symbols, **assumptions)
  144. if not hasattr(obj, 'limits'):
  145. return obj
  146. if any(len(l) != 3 or None in l for l in obj.limits):
  147. raise ValueError('Sum requires values for lower and upper bounds.')
  148. return obj
  149. def _eval_is_zero(self):
  150. # a Sum is only zero if its function is zero or if all terms
  151. # cancel out. This only answers whether the summand is zero; if
  152. # not then None is returned since we don't analyze whether all
  153. # terms cancel out.
  154. if self.function.is_zero or self.has_empty_sequence:
  155. return True
  156. def _eval_is_extended_real(self):
  157. if self.has_empty_sequence:
  158. return True
  159. return self.function.is_extended_real
  160. def _eval_is_positive(self):
  161. if self.has_finite_limits and self.has_reversed_limits is False:
  162. return self.function.is_positive
  163. def _eval_is_negative(self):
  164. if self.has_finite_limits and self.has_reversed_limits is False:
  165. return self.function.is_negative
  166. def _eval_is_finite(self):
  167. if self.has_finite_limits and self.function.is_finite:
  168. return True
  169. def doit(self, **hints):
  170. if hints.get('deep', True):
  171. f = self.function.doit(**hints)
  172. else:
  173. f = self.function
  174. # first make sure any definite limits have summation
  175. # variables with matching assumptions
  176. reps = {}
  177. for xab in self.limits:
  178. d = _dummy_with_inherited_properties_concrete(xab)
  179. if d:
  180. reps[xab[0]] = d
  181. if reps:
  182. undo = {v: k for k, v in reps.items()}
  183. did = self.xreplace(reps).doit(**hints)
  184. if isinstance(did, tuple): # when separate=True
  185. did = tuple([i.xreplace(undo) for i in did])
  186. elif did is not None:
  187. did = did.xreplace(undo)
  188. else:
  189. did = self
  190. return did
  191. if self.function.is_Matrix:
  192. expanded = self.expand()
  193. if self != expanded:
  194. return expanded.doit()
  195. return _eval_matrix_sum(self)
  196. for n, limit in enumerate(self.limits):
  197. i, a, b = limit
  198. dif = b - a
  199. if dif == -1:
  200. # Any summation over an empty set is zero
  201. return S.Zero
  202. if dif.is_integer and dif.is_negative:
  203. a, b = b + 1, a - 1
  204. f = -f
  205. newf = eval_sum(f, (i, a, b))
  206. if newf is None:
  207. if f == self.function:
  208. zeta_function = self.eval_zeta_function(f, (i, a, b))
  209. if zeta_function is not None:
  210. return zeta_function
  211. return self
  212. else:
  213. return self.func(f, *self.limits[n:])
  214. f = newf
  215. if hints.get('deep', True):
  216. # eval_sum could return partially unevaluated
  217. # result with Piecewise. In this case we won't
  218. # doit() recursively.
  219. if not isinstance(f, Piecewise):
  220. return f.doit(**hints)
  221. return f
  222. def eval_zeta_function(self, f, limits):
  223. """
  224. Check whether the function matches with the zeta function.
  225. If it matches, then return a `Piecewise` expression because
  226. zeta function does not converge unless `s > 1` and `q > 0`
  227. """
  228. i, a, b = limits
  229. if a.is_comparable and b.is_comparable and a > b:
  230. return self.eval_zeta_function(f, (i, b + S.One, a - S.One))
  231. if b is not S.Infinity:
  232. return
  233. w, y, z = Wild('w', exclude=[i]), Wild('y', exclude=[i]), Wild('z', exclude=[i])
  234. if result := f.match((w * i + y) ** (-z)):
  235. coeff = 1 / result[w] ** result[z]
  236. s = result[z]
  237. q = result[y] / result[w] + a
  238. return Piecewise((coeff * zeta(s, q),
  239. And(Not(Contains(-q, S.Naturals0)), re(s) > S.One)),
  240. (self, True))
  241. def _eval_derivative(self, x):
  242. """
  243. Differentiate wrt x as long as x is not in the free symbols of any of
  244. the upper or lower limits.
  245. Explanation
  246. ===========
  247. Sum(a*b*x, (x, 1, a)) can be differentiated wrt x or b but not `a`
  248. since the value of the sum is discontinuous in `a`. In a case
  249. involving a limit variable, the unevaluated derivative is returned.
  250. """
  251. # diff already confirmed that x is in the free symbols of self, but we
  252. # don't want to differentiate wrt any free symbol in the upper or lower
  253. # limits
  254. # XXX remove this test for free_symbols when the default _eval_derivative is in
  255. if isinstance(x, Symbol) and x not in self.free_symbols:
  256. return S.Zero
  257. # get limits and the function
  258. f, limits = self.function, list(self.limits)
  259. limit = limits.pop(-1)
  260. if limits: # f is the argument to a Sum
  261. f = self.func(f, *limits)
  262. _, a, b = limit
  263. if x in a.free_symbols or x in b.free_symbols:
  264. return None
  265. df = Derivative(f, x, evaluate=True)
  266. rv = self.func(df, limit)
  267. return rv
  268. def _eval_difference_delta(self, n, step):
  269. k, _, upper = self.args[-1]
  270. new_upper = upper.subs(n, n + step)
  271. if len(self.args) == 2:
  272. f = self.args[0]
  273. else:
  274. f = self.func(*self.args[:-1])
  275. return Sum(f, (k, upper + 1, new_upper)).doit()
  276. def _eval_simplify(self, **kwargs):
  277. function = self.function
  278. if kwargs.get('deep', True):
  279. function = function.simplify(**kwargs)
  280. # split the function into adds
  281. terms = Add.make_args(expand(function))
  282. s_t = [] # Sum Terms
  283. o_t = [] # Other Terms
  284. for term in terms:
  285. if term.has(Sum):
  286. # if there is an embedded sum here
  287. # it is of the form x * (Sum(whatever))
  288. # hence we make a Mul out of it, and simplify all interior sum terms
  289. subterms = Mul.make_args(expand(term))
  290. out_terms = []
  291. for subterm in subterms:
  292. # go through each term
  293. if isinstance(subterm, Sum):
  294. # if it's a sum, simplify it
  295. out_terms.append(subterm._eval_simplify(**kwargs))
  296. else:
  297. # otherwise, add it as is
  298. out_terms.append(subterm)
  299. # turn it back into a Mul
  300. s_t.append(Mul(*out_terms))
  301. else:
  302. o_t.append(term)
  303. # next try to combine any interior sums for further simplification
  304. from sympy.simplify.simplify import factor_sum, sum_combine
  305. result = Add(sum_combine(s_t), *o_t)
  306. return factor_sum(result, limits=self.limits)
  307. def is_convergent(self):
  308. r"""
  309. Checks for the convergence of a Sum.
  310. Explanation
  311. ===========
  312. We divide the study of convergence of infinite sums and products in
  313. two parts.
  314. First Part:
  315. One part is the question whether all the terms are well defined, i.e.,
  316. they are finite in a sum and also non-zero in a product. Zero
  317. is the analogy of (minus) infinity in products as
  318. :math:`e^{-\infty} = 0`.
  319. Second Part:
  320. The second part is the question of convergence after infinities,
  321. and zeros in products, have been omitted assuming that their number
  322. is finite. This means that we only consider the tail of the sum or
  323. product, starting from some point after which all terms are well
  324. defined.
  325. For example, in a sum of the form:
  326. .. math::
  327. \sum_{1 \leq i < \infty} \frac{1}{n^2 + an + b}
  328. where a and b are numbers. The routine will return true, even if there
  329. are infinities in the term sequence (at most two). An analogous
  330. product would be:
  331. .. math::
  332. \prod_{1 \leq i < \infty} e^{\frac{1}{n^2 + an + b}}
  333. This is how convergence is interpreted. It is concerned with what
  334. happens at the limit. Finding the bad terms is another independent
  335. matter.
  336. Note: It is responsibility of user to see that the sum or product
  337. is well defined.
  338. There are various tests employed to check the convergence like
  339. divergence test, root test, integral test, alternating series test,
  340. comparison tests, Dirichlet tests. It returns true if Sum is convergent
  341. and false if divergent and NotImplementedError if it cannot be checked.
  342. References
  343. ==========
  344. .. [1] https://en.wikipedia.org/wiki/Convergence_tests
  345. Examples
  346. ========
  347. >>> from sympy import factorial, S, Sum, Symbol, oo
  348. >>> n = Symbol('n', integer=True)
  349. >>> Sum(n/(n - 1), (n, 4, 7)).is_convergent()
  350. True
  351. >>> Sum(n/(2*n + 1), (n, 1, oo)).is_convergent()
  352. False
  353. >>> Sum(factorial(n)/5**n, (n, 1, oo)).is_convergent()
  354. False
  355. >>> Sum(1/n**(S(6)/5), (n, 1, oo)).is_convergent()
  356. True
  357. See Also
  358. ========
  359. Sum.is_absolutely_convergent
  360. sympy.concrete.products.Product.is_convergent
  361. """
  362. p, q, r = symbols('p q r', cls=Wild)
  363. sym = self.limits[0][0]
  364. lower_limit = self.limits[0][1]
  365. upper_limit = self.limits[0][2]
  366. sequence_term = self.function.simplify()
  367. if len(sequence_term.free_symbols) > 1:
  368. raise NotImplementedError("convergence checking for more than one symbol "
  369. "containing series is not handled")
  370. if lower_limit.is_finite and upper_limit.is_finite:
  371. return S.true
  372. # transform sym -> -sym and swap the upper_limit = S.Infinity
  373. # and lower_limit = - upper_limit
  374. if lower_limit is S.NegativeInfinity:
  375. if upper_limit is S.Infinity:
  376. return Sum(sequence_term, (sym, 0, S.Infinity)).is_convergent() and \
  377. Sum(sequence_term, (sym, S.NegativeInfinity, 0)).is_convergent()
  378. from sympy.simplify.simplify import simplify
  379. sequence_term = simplify(sequence_term.xreplace({sym: -sym}))
  380. lower_limit = -upper_limit
  381. upper_limit = S.Infinity
  382. sym_ = Dummy(sym.name, integer=True, positive=True)
  383. sequence_term = sequence_term.xreplace({sym: sym_})
  384. sym = sym_
  385. interval = Interval(lower_limit, upper_limit)
  386. # Piecewise function handle
  387. if sequence_term.is_Piecewise:
  388. for func, cond in sequence_term.args:
  389. # see if it represents something going to oo
  390. if cond == True or cond.as_set().sup is S.Infinity:
  391. s = Sum(func, (sym, lower_limit, upper_limit))
  392. return s.is_convergent()
  393. return S.true
  394. ### -------- Divergence test ----------- ###
  395. try:
  396. lim_val = limit_seq(sequence_term, sym)
  397. if lim_val is not None and lim_val.is_zero is False:
  398. return S.false
  399. except NotImplementedError:
  400. pass
  401. try:
  402. lim_val_abs = limit_seq(abs(sequence_term), sym)
  403. if lim_val_abs is not None and lim_val_abs.is_zero is False:
  404. return S.false
  405. except NotImplementedError:
  406. pass
  407. order = O(sequence_term, (sym, S.Infinity))
  408. ### --------- p-series test (1/n**p) ---------- ###
  409. p_series_test = order.expr.match(sym**p)
  410. if p_series_test is not None:
  411. if p_series_test[p] < -1:
  412. return S.true
  413. if p_series_test[p] >= -1:
  414. return S.false
  415. ### ------------- comparison test ------------- ###
  416. # 1/(n**p*log(n)**q*log(log(n))**r) comparison
  417. n_log_test = (order.expr.match(1/(sym**p*log(1/sym)**q*log(-log(1/sym))**r)) or
  418. order.expr.match(1/(sym**p*(-log(1/sym))**q*log(-log(1/sym))**r)))
  419. if n_log_test is not None:
  420. if (n_log_test[p] > 1 or
  421. (n_log_test[p] == 1 and n_log_test[q] > 1) or
  422. (n_log_test[p] == n_log_test[q] == 1 and n_log_test[r] > 1)):
  423. return S.true
  424. return S.false
  425. ### ------------- Limit comparison test -----------###
  426. # (1/n) comparison
  427. try:
  428. lim_comp = limit_seq(sym*sequence_term, sym)
  429. if lim_comp is not None and lim_comp.is_number and lim_comp > 0:
  430. return S.false
  431. except NotImplementedError:
  432. pass
  433. ### ----------- ratio test ---------------- ###
  434. next_sequence_term = sequence_term.xreplace({sym: sym + 1})
  435. from sympy.simplify.combsimp import combsimp
  436. from sympy.simplify.powsimp import powsimp
  437. ratio = combsimp(powsimp(next_sequence_term/sequence_term))
  438. try:
  439. lim_ratio = limit_seq(ratio, sym)
  440. if lim_ratio is not None and lim_ratio.is_number and lim_ratio is not S.NaN:
  441. if abs(lim_ratio) > 1:
  442. return S.false
  443. if abs(lim_ratio) < 1:
  444. return S.true
  445. except NotImplementedError:
  446. lim_ratio = None
  447. ### ---------- Raabe's test -------------- ###
  448. if lim_ratio == 1: # ratio test inconclusive
  449. test_val = sym*(sequence_term/
  450. sequence_term.subs(sym, sym + 1) - 1)
  451. test_val = test_val.gammasimp()
  452. try:
  453. lim_val = limit_seq(test_val, sym)
  454. if lim_val is not None and lim_val.is_number:
  455. if lim_val > 1:
  456. return S.true
  457. if lim_val < 1:
  458. return S.false
  459. except NotImplementedError:
  460. pass
  461. ### ----------- root test ---------------- ###
  462. # lim = Limit(abs(sequence_term)**(1/sym), sym, S.Infinity)
  463. try:
  464. lim_evaluated = limit_seq(abs(sequence_term)**(1/sym), sym)
  465. if lim_evaluated is not None and lim_evaluated.is_number:
  466. if lim_evaluated < 1:
  467. return S.true
  468. if lim_evaluated > 1:
  469. return S.false
  470. except NotImplementedError:
  471. pass
  472. ### ------------- alternating series test ----------- ###
  473. dict_val = sequence_term.match(S.NegativeOne**(sym + p)*q)
  474. if not dict_val[p].has(sym) and is_decreasing(dict_val[q], interval):
  475. return S.true
  476. ### ------------- integral test -------------- ###
  477. check_interval = None
  478. from sympy.solvers.solveset import solveset
  479. maxima = solveset(sequence_term.diff(sym), sym, interval)
  480. if not maxima:
  481. check_interval = interval
  482. elif isinstance(maxima, FiniteSet) and maxima.sup.is_number:
  483. check_interval = Interval(maxima.sup, interval.sup)
  484. if (check_interval is not None and
  485. (is_decreasing(sequence_term, check_interval) or
  486. is_decreasing(-sequence_term, check_interval))):
  487. integral_val = Integral(
  488. sequence_term, (sym, lower_limit, upper_limit))
  489. try:
  490. integral_val_evaluated = integral_val.doit()
  491. if integral_val_evaluated.is_number:
  492. return S(integral_val_evaluated.is_finite)
  493. except NotImplementedError:
  494. pass
  495. ### ----- Dirichlet and bounded times convergent tests ----- ###
  496. # TODO
  497. #
  498. # Dirichlet_test
  499. # https://en.wikipedia.org/wiki/Dirichlet%27s_test
  500. #
  501. # Bounded times convergent test
  502. # It is based on comparison theorems for series.
  503. # In particular, if the general term of a series can
  504. # be written as a product of two terms a_n and b_n
  505. # and if a_n is bounded and if Sum(b_n) is absolutely
  506. # convergent, then the original series Sum(a_n * b_n)
  507. # is absolutely convergent and so convergent.
  508. #
  509. # The following code can grows like 2**n where n is the
  510. # number of args in order.expr
  511. # Possibly combined with the potentially slow checks
  512. # inside the loop, could make this test extremely slow
  513. # for larger summation expressions.
  514. if order.expr.is_Mul:
  515. args = order.expr.args
  516. argset = set(args)
  517. ### -------------- Dirichlet tests -------------- ###
  518. m = Dummy('m', integer=True)
  519. def _dirichlet_test(g_n):
  520. try:
  521. ing_val = limit_seq(Sum(g_n, (sym, interval.inf, m)).doit(), m)
  522. if ing_val is not None and ing_val.is_finite:
  523. return S.true
  524. except NotImplementedError:
  525. pass
  526. ### -------- bounded times convergent test ---------###
  527. def _bounded_convergent_test(g1_n, g2_n):
  528. try:
  529. lim_val = limit_seq(g1_n, sym)
  530. if lim_val is not None and (lim_val.is_finite or (
  531. isinstance(lim_val, AccumulationBounds)
  532. and (lim_val.max - lim_val.min).is_finite)):
  533. if Sum(g2_n, (sym, lower_limit, upper_limit)).is_absolutely_convergent():
  534. return S.true
  535. except NotImplementedError:
  536. pass
  537. for n in range(1, len(argset)):
  538. for a_tuple in itertools.combinations(args, n):
  539. b_set = argset - set(a_tuple)
  540. a_n = Mul(*a_tuple)
  541. b_n = Mul(*b_set)
  542. if is_decreasing(a_n, interval):
  543. dirich = _dirichlet_test(b_n)
  544. if dirich is not None:
  545. return dirich
  546. bc_test = _bounded_convergent_test(a_n, b_n)
  547. if bc_test is not None:
  548. return bc_test
  549. _sym = self.limits[0][0]
  550. sequence_term = sequence_term.xreplace({sym: _sym})
  551. raise NotImplementedError("The algorithm to find the Sum convergence of %s "
  552. "is not yet implemented" % (sequence_term))
  553. def is_absolutely_convergent(self):
  554. """
  555. Checks for the absolute convergence of an infinite series.
  556. Same as checking convergence of absolute value of sequence_term of
  557. an infinite series.
  558. References
  559. ==========
  560. .. [1] https://en.wikipedia.org/wiki/Absolute_convergence
  561. Examples
  562. ========
  563. >>> from sympy import Sum, Symbol, oo
  564. >>> n = Symbol('n', integer=True)
  565. >>> Sum((-1)**n, (n, 1, oo)).is_absolutely_convergent()
  566. False
  567. >>> Sum((-1)**n/n**2, (n, 1, oo)).is_absolutely_convergent()
  568. True
  569. See Also
  570. ========
  571. Sum.is_convergent
  572. """
  573. return Sum(abs(self.function), self.limits).is_convergent()
  574. def euler_maclaurin(self, m=0, n=0, eps=0, eval_integral=True):
  575. """
  576. Return an Euler-Maclaurin approximation of self, where m is the
  577. number of leading terms to sum directly and n is the number of
  578. terms in the tail.
  579. With m = n = 0, this is simply the corresponding integral
  580. plus a first-order endpoint correction.
  581. Returns (s, e) where s is the Euler-Maclaurin approximation
  582. and e is the estimated error (taken to be the magnitude of
  583. the first omitted term in the tail):
  584. >>> from sympy.abc import k, a, b
  585. >>> from sympy import Sum
  586. >>> Sum(1/k, (k, 2, 5)).doit().evalf()
  587. 1.28333333333333
  588. >>> s, e = Sum(1/k, (k, 2, 5)).euler_maclaurin()
  589. >>> s
  590. -log(2) + 7/20 + log(5)
  591. >>> from sympy import sstr
  592. >>> print(sstr((s.evalf(), e.evalf()), full_prec=True))
  593. (1.26629073187415, 0.0175000000000000)
  594. The endpoints may be symbolic:
  595. >>> s, e = Sum(1/k, (k, a, b)).euler_maclaurin()
  596. >>> s
  597. -log(a) + log(b) + 1/(2*b) + 1/(2*a)
  598. >>> e
  599. Abs(1/(12*b**2) - 1/(12*a**2))
  600. If the function is a polynomial of degree at most 2n+1, the
  601. Euler-Maclaurin formula becomes exact (and e = 0 is returned):
  602. >>> Sum(k, (k, 2, b)).euler_maclaurin()
  603. (b**2/2 + b/2 - 1, 0)
  604. >>> Sum(k, (k, 2, b)).doit()
  605. b**2/2 + b/2 - 1
  606. With a nonzero eps specified, the summation is ended
  607. as soon as the remainder term is less than the epsilon.
  608. """
  609. m = int(m)
  610. n = int(n)
  611. f = self.function
  612. if len(self.limits) != 1:
  613. raise ValueError("More than 1 limit")
  614. i, a, b = self.limits[0]
  615. if (a > b) == True:
  616. if a - b == 1:
  617. return S.Zero, S.Zero
  618. a, b = b + 1, a - 1
  619. f = -f
  620. s = S.Zero
  621. if m:
  622. if b.is_Integer and a.is_Integer:
  623. m = min(m, b - a + 1)
  624. if not eps or f.is_polynomial(i):
  625. s = Add(*[f.subs(i, a + k) for k in range(m)])
  626. else:
  627. term = f.subs(i, a)
  628. if term:
  629. test = abs(term.evalf(3)) < eps
  630. if test == True:
  631. return s, abs(term)
  632. elif not (test == False):
  633. # a symbolic Relational class, can't go further
  634. return term, S.Zero
  635. s = term
  636. for k in range(1, m):
  637. term = f.subs(i, a + k)
  638. if abs(term.evalf(3)) < eps and term != 0:
  639. return s, abs(term)
  640. s += term
  641. if b - a + 1 == m:
  642. return s, S.Zero
  643. a += m
  644. x = Dummy('x')
  645. I = Integral(f.subs(i, x), (x, a, b))
  646. if eval_integral:
  647. I = I.doit()
  648. s += I
  649. def fpoint(expr):
  650. if b is S.Infinity:
  651. return expr.subs(i, a), 0
  652. return expr.subs(i, a), expr.subs(i, b)
  653. fa, fb = fpoint(f)
  654. iterm = (fa + fb)/2
  655. g = f.diff(i)
  656. for k in range(1, n + 2):
  657. ga, gb = fpoint(g)
  658. term = bernoulli(2*k)/factorial(2*k)*(gb - ga)
  659. if k > n:
  660. break
  661. if eps and term:
  662. term_evalf = term.evalf(3)
  663. if term_evalf is S.NaN:
  664. return S.NaN, S.NaN
  665. if abs(term_evalf) < eps:
  666. break
  667. s += term
  668. g = g.diff(i, 2, simplify=False)
  669. return s + iterm, abs(term)
  670. def reverse_order(self, *indices):
  671. """
  672. Reverse the order of a limit in a Sum.
  673. Explanation
  674. ===========
  675. ``reverse_order(self, *indices)`` reverses some limits in the expression
  676. ``self`` which can be either a ``Sum`` or a ``Product``. The selectors in
  677. the argument ``indices`` specify some indices whose limits get reversed.
  678. These selectors are either variable names or numerical indices counted
  679. starting from the inner-most limit tuple.
  680. Examples
  681. ========
  682. >>> from sympy import Sum
  683. >>> from sympy.abc import x, y, a, b, c, d
  684. >>> Sum(x, (x, 0, 3)).reverse_order(x)
  685. Sum(-x, (x, 4, -1))
  686. >>> Sum(x*y, (x, 1, 5), (y, 0, 6)).reverse_order(x, y)
  687. Sum(x*y, (x, 6, 0), (y, 7, -1))
  688. >>> Sum(x, (x, a, b)).reverse_order(x)
  689. Sum(-x, (x, b + 1, a - 1))
  690. >>> Sum(x, (x, a, b)).reverse_order(0)
  691. Sum(-x, (x, b + 1, a - 1))
  692. While one should prefer variable names when specifying which limits
  693. to reverse, the index counting notation comes in handy in case there
  694. are several symbols with the same name.
  695. >>> S = Sum(x**2, (x, a, b), (x, c, d))
  696. >>> S
  697. Sum(x**2, (x, a, b), (x, c, d))
  698. >>> S0 = S.reverse_order(0)
  699. >>> S0
  700. Sum(-x**2, (x, b + 1, a - 1), (x, c, d))
  701. >>> S1 = S0.reverse_order(1)
  702. >>> S1
  703. Sum(x**2, (x, b + 1, a - 1), (x, d + 1, c - 1))
  704. Of course we can mix both notations:
  705. >>> Sum(x*y, (x, a, b), (y, 2, 5)).reverse_order(x, 1)
  706. Sum(x*y, (x, b + 1, a - 1), (y, 6, 1))
  707. >>> Sum(x*y, (x, a, b), (y, 2, 5)).reverse_order(y, x)
  708. Sum(x*y, (x, b + 1, a - 1), (y, 6, 1))
  709. See Also
  710. ========
  711. sympy.concrete.expr_with_intlimits.ExprWithIntLimits.index, reorder_limit,
  712. sympy.concrete.expr_with_intlimits.ExprWithIntLimits.reorder
  713. References
  714. ==========
  715. .. [1] Michael Karr, "Summation in Finite Terms", Journal of the ACM,
  716. Volume 28 Issue 2, April 1981, Pages 305-350
  717. https://dl.acm.org/doi/10.1145/322248.322255
  718. """
  719. l_indices = list(indices)
  720. for i, indx in enumerate(l_indices):
  721. if not isinstance(indx, int):
  722. l_indices[i] = self.index(indx)
  723. e = 1
  724. limits = []
  725. for i, limit in enumerate(self.limits):
  726. l = limit
  727. if i in l_indices:
  728. e = -e
  729. l = (limit[0], limit[2] + 1, limit[1] - 1)
  730. limits.append(l)
  731. return Sum(e * self.function, *limits)
  732. def _eval_rewrite_as_Product(self, *args, **kwargs):
  733. from sympy.concrete.products import Product
  734. if self.function.is_extended_real:
  735. return log(Product(exp(self.function), *self.limits))
  736. def summation(f, *symbols, **kwargs):
  737. r"""
  738. Compute the summation of f with respect to symbols.
  739. Explanation
  740. ===========
  741. The notation for symbols is similar to the notation used in Integral.
  742. summation(f, (i, a, b)) computes the sum of f with respect to i from a to b,
  743. i.e.,
  744. ::
  745. b
  746. ____
  747. \ `
  748. summation(f, (i, a, b)) = ) f
  749. /___,
  750. i = a
  751. If it cannot compute the sum, it returns an unevaluated Sum object.
  752. Repeated sums can be computed by introducing additional symbols tuples::
  753. Examples
  754. ========
  755. >>> from sympy import summation, oo, symbols, log
  756. >>> i, n, m = symbols('i n m', integer=True)
  757. >>> summation(2*i - 1, (i, 1, n))
  758. n**2
  759. >>> summation(1/2**i, (i, 0, oo))
  760. 2
  761. >>> summation(1/log(n)**n, (n, 2, oo))
  762. Sum(log(n)**(-n), (n, 2, oo))
  763. >>> summation(i, (i, 0, n), (n, 0, m))
  764. m**3/6 + m**2/2 + m/3
  765. >>> from sympy.abc import x
  766. >>> from sympy import factorial
  767. >>> summation(x**n/factorial(n), (n, 0, oo))
  768. exp(x)
  769. See Also
  770. ========
  771. Sum
  772. Product, sympy.concrete.products.product
  773. """
  774. return Sum(f, *symbols, **kwargs).doit(deep=False)
  775. def telescopic_direct(L, R, n, limits):
  776. """
  777. Returns the direct summation of the terms of a telescopic sum
  778. Explanation
  779. ===========
  780. L is the term with lower index
  781. R is the term with higher index
  782. n difference between the indexes of L and R
  783. Examples
  784. ========
  785. >>> from sympy.concrete.summations import telescopic_direct
  786. >>> from sympy.abc import k, a, b
  787. >>> telescopic_direct(1/k, -1/(k+2), 2, (k, a, b))
  788. -1/(b + 2) - 1/(b + 1) + 1/(a + 1) + 1/a
  789. """
  790. (i, a, b) = limits
  791. return Add(*[L.subs(i, a + m) + R.subs(i, b - m) for m in range(n)])
  792. def telescopic(L, R, limits):
  793. '''
  794. Tries to perform the summation using the telescopic property.
  795. Return None if not possible.
  796. '''
  797. (i, a, b) = limits
  798. if L.is_Add or R.is_Add:
  799. return None
  800. # We want to solve(L.subs(i, i + m) + R, m)
  801. # First we try a simple match since this does things that
  802. # solve doesn't do, e.g. solve(cos(k+m)-cos(k), m) gives
  803. # a more complicated solution than m == 0.
  804. k = Wild("k")
  805. sol = (-R).match(L.subs(i, i + k))
  806. s = None
  807. if sol and k in sol:
  808. s = sol[k]
  809. if not (s.is_Integer and L.subs(i, i + s) + R == 0):
  810. # invalid match or match didn't work
  811. s = None
  812. # But there are things that match doesn't do that solve
  813. # can do, e.g. determine that 1/(x + m) = 1/(1 - x) when m = 1
  814. if s is None:
  815. m = Dummy('m')
  816. try:
  817. from sympy.solvers.solvers import solve
  818. sol = solve(L.subs(i, i + m) + R, m) or []
  819. except NotImplementedError:
  820. return None
  821. sol = [si for si in sol if si.is_Integer and
  822. (L.subs(i, i + si) + R).expand().is_zero]
  823. if len(sol) != 1:
  824. return None
  825. s = sol[0]
  826. if s < 0:
  827. return telescopic_direct(R, L, abs(s), (i, a, b))
  828. elif s > 0:
  829. return telescopic_direct(L, R, s, (i, a, b))
  830. def eval_sum(f, limits):
  831. (i, a, b) = limits
  832. if f.is_zero:
  833. return S.Zero
  834. if i not in f.free_symbols:
  835. return f*(b - a + 1)
  836. if a == b:
  837. return f.subs(i, a)
  838. if a.is_comparable and b.is_comparable and a > b:
  839. return eval_sum(f, (i, b + S.One, a - S.One))
  840. if isinstance(f, Piecewise):
  841. if not any(i in arg.args[1].free_symbols for arg in f.args):
  842. # Piecewise conditions do not depend on the dummy summation variable,
  843. # therefore we can fold: Sum(Piecewise((e, c), ...), limits)
  844. # --> Piecewise((Sum(e, limits), c), ...)
  845. newargs = []
  846. for arg in f.args:
  847. newexpr = eval_sum(arg.expr, limits)
  848. if newexpr is None:
  849. return None
  850. newargs.append((newexpr, arg.cond))
  851. return f.func(*newargs)
  852. if f.has(KroneckerDelta):
  853. from .delta import deltasummation, _has_simple_delta
  854. f = f.replace(
  855. lambda x: isinstance(x, Sum),
  856. lambda x: x.factor()
  857. )
  858. if _has_simple_delta(f, limits[0]):
  859. return deltasummation(f, limits)
  860. dif = b - a
  861. definite = dif.is_Integer
  862. # Doing it directly may be faster if there are very few terms.
  863. if definite and (dif < 100):
  864. return eval_sum_direct(f, (i, a, b))
  865. if isinstance(f, Piecewise):
  866. return None
  867. # Try to do it symbolically. Even when the number of terms is
  868. # known, this can save time when b-a is big.
  869. value = eval_sum_symbolic(f.expand(), (i, a, b))
  870. if value is not None:
  871. return value
  872. # Do it directly
  873. if definite:
  874. return eval_sum_direct(f, (i, a, b))
  875. def eval_sum_direct(expr, limits):
  876. """
  877. Evaluate expression directly, but perform some simple checks first
  878. to possibly result in a smaller expression and faster execution.
  879. """
  880. (i, a, b) = limits
  881. dif = b - a
  882. # Linearity
  883. if expr.is_Mul:
  884. # Try factor out everything not including i
  885. without_i, with_i = expr.as_independent(i)
  886. if without_i != 1:
  887. s = eval_sum_direct(with_i, (i, a, b))
  888. if s:
  889. r = without_i*s
  890. if r is not S.NaN:
  891. return r
  892. else:
  893. # Try term by term
  894. L, R = expr.as_two_terms()
  895. if not L.has(i):
  896. sR = eval_sum_direct(R, (i, a, b))
  897. if sR:
  898. return L*sR
  899. if not R.has(i):
  900. sL = eval_sum_direct(L, (i, a, b))
  901. if sL:
  902. return sL*R
  903. # do this whether its an Add or Mul
  904. # e.g. apart(1/(25*i**2 + 45*i + 14)) and
  905. # apart(1/((5*i + 2)*(5*i + 7))) ->
  906. # -1/(5*(5*i + 7)) + 1/(5*(5*i + 2))
  907. try:
  908. expr = apart(expr, i) # see if it becomes an Add
  909. except PolynomialError:
  910. pass
  911. if expr.is_Add:
  912. # Try factor out everything not including i
  913. without_i, with_i = expr.as_independent(i)
  914. if without_i != 0:
  915. s = eval_sum_direct(with_i, (i, a, b))
  916. if s:
  917. r = without_i*(dif + 1) + s
  918. if r is not S.NaN:
  919. return r
  920. else:
  921. # Try term by term
  922. L, R = expr.as_two_terms()
  923. lsum = eval_sum_direct(L, (i, a, b))
  924. rsum = eval_sum_direct(R, (i, a, b))
  925. if None not in (lsum, rsum):
  926. r = lsum + rsum
  927. if r is not S.NaN:
  928. return r
  929. return Add(*[expr.subs(i, a + j) for j in range(dif + 1)])
  930. def eval_sum_symbolic(f, limits):
  931. f_orig = f
  932. (i, a, b) = limits
  933. if not f.has(i):
  934. return f*(b - a + 1)
  935. # Linearity
  936. if f.is_Mul:
  937. # Try factor out everything not including i
  938. without_i, with_i = f.as_independent(i)
  939. if without_i != 1:
  940. s = eval_sum_symbolic(with_i, (i, a, b))
  941. if s:
  942. r = without_i*s
  943. if r is not S.NaN:
  944. return r
  945. else:
  946. # Try term by term
  947. L, R = f.as_two_terms()
  948. if not L.has(i):
  949. sR = eval_sum_symbolic(R, (i, a, b))
  950. if sR:
  951. return L*sR
  952. if not R.has(i):
  953. sL = eval_sum_symbolic(L, (i, a, b))
  954. if sL:
  955. return sL*R
  956. # do this whether its an Add or Mul
  957. # e.g. apart(1/(25*i**2 + 45*i + 14)) and
  958. # apart(1/((5*i + 2)*(5*i + 7))) ->
  959. # -1/(5*(5*i + 7)) + 1/(5*(5*i + 2))
  960. try:
  961. f = apart(f, i)
  962. except PolynomialError:
  963. pass
  964. if f.is_Add:
  965. L, R = f.as_two_terms()
  966. lrsum = telescopic(L, R, (i, a, b))
  967. if lrsum:
  968. return lrsum
  969. # Try factor out everything not including i
  970. without_i, with_i = f.as_independent(i)
  971. if without_i != 0:
  972. s = eval_sum_symbolic(with_i, (i, a, b))
  973. if s:
  974. r = without_i*(b - a + 1) + s
  975. if r is not S.NaN:
  976. return r
  977. else:
  978. # Try term by term
  979. lsum = eval_sum_symbolic(L, (i, a, b))
  980. rsum = eval_sum_symbolic(R, (i, a, b))
  981. if None not in (lsum, rsum):
  982. r = lsum + rsum
  983. if r is not S.NaN:
  984. return r
  985. # Polynomial terms with Faulhaber's formula
  986. n = Wild('n')
  987. result = f.match(i**n)
  988. if result is not None:
  989. n = result[n]
  990. if n.is_Integer:
  991. if n >= 0:
  992. if (b is S.Infinity and a is not S.NegativeInfinity) or \
  993. (a is S.NegativeInfinity and b is not S.Infinity):
  994. return S.Infinity
  995. return ((bernoulli(n + 1, b + 1) - bernoulli(n + 1, a))/(n + 1)).expand()
  996. elif a.is_Integer and a >= 1:
  997. if n == -1:
  998. return harmonic(b) - harmonic(a - 1)
  999. else:
  1000. return harmonic(b, abs(n)) - harmonic(a - 1, abs(n))
  1001. if not (a.has(S.Infinity, S.NegativeInfinity) or
  1002. b.has(S.Infinity, S.NegativeInfinity)):
  1003. # Geometric terms
  1004. c1 = Wild('c1', exclude=[i])
  1005. c2 = Wild('c2', exclude=[i])
  1006. c3 = Wild('c3', exclude=[i])
  1007. wexp = Wild('wexp')
  1008. # Here we first attempt powsimp on f for easier matching with the
  1009. # exponential pattern, and attempt expansion on the exponent for easier
  1010. # matching with the linear pattern.
  1011. e = f.powsimp().match(c1 ** wexp)
  1012. if e is not None:
  1013. e_exp = e.pop(wexp).expand().match(c2*i + c3)
  1014. if e_exp is not None:
  1015. e.update(e_exp)
  1016. p = (c1**c3).subs(e)
  1017. q = (c1**c2).subs(e)
  1018. r = p*(q**a - q**(b + 1))/(1 - q)
  1019. l = p*(b - a + 1)
  1020. return Piecewise((l, Eq(q, S.One)), (r, True))
  1021. r = gosper_sum(f, (i, a, b))
  1022. if isinstance(r, (Mul,Add)):
  1023. from sympy.simplify.radsimp import denom
  1024. from sympy.solvers.solvers import solve
  1025. non_limit = r.free_symbols - Tuple(*limits[1:]).free_symbols
  1026. den = denom(together(r))
  1027. den_sym = non_limit & den.free_symbols
  1028. args = []
  1029. for v in ordered(den_sym):
  1030. try:
  1031. s = solve(den, v)
  1032. m = Eq(v, s[0]) if s else S.false
  1033. if m != False:
  1034. args.append((Sum(f_orig.subs(*m.args), limits).doit(), m))
  1035. break
  1036. except NotImplementedError:
  1037. continue
  1038. args.append((r, True))
  1039. return Piecewise(*args)
  1040. if r not in (None, S.NaN):
  1041. return r
  1042. h = eval_sum_hyper(f_orig, (i, a, b))
  1043. if h is not None:
  1044. return h
  1045. r = eval_sum_residue(f_orig, (i, a, b))
  1046. if r is not None:
  1047. return r
  1048. factored = f_orig.factor()
  1049. if factored != f_orig:
  1050. return eval_sum_symbolic(factored, (i, a, b))
  1051. def _eval_sum_hyper(f, i, a):
  1052. """ Returns (res, cond). Sums from a to oo. """
  1053. if a != 0:
  1054. return _eval_sum_hyper(f.subs(i, i + a), i, 0)
  1055. if f.subs(i, 0) == 0:
  1056. from sympy.simplify.simplify import simplify
  1057. if simplify(f.subs(i, Dummy('i', integer=True, positive=True))) == 0:
  1058. return S.Zero, True
  1059. return _eval_sum_hyper(f.subs(i, i + 1), i, 0)
  1060. from sympy.simplify.simplify import hypersimp
  1061. hs = hypersimp(f, i)
  1062. if hs is None:
  1063. return None
  1064. if isinstance(hs, Float):
  1065. from sympy.simplify.simplify import nsimplify
  1066. hs = nsimplify(hs)
  1067. from sympy.simplify.combsimp import combsimp
  1068. from sympy.simplify.hyperexpand import hyperexpand
  1069. from sympy.simplify.radsimp import fraction
  1070. numer, denom = fraction(factor(hs))
  1071. top, topl = numer.as_coeff_mul(i)
  1072. bot, botl = denom.as_coeff_mul(i)
  1073. ab = [top, bot]
  1074. factors = [topl, botl]
  1075. params = [[], []]
  1076. for k in range(2):
  1077. for fac in factors[k]:
  1078. mul = 1
  1079. if fac.is_Pow:
  1080. mul = fac.exp
  1081. fac = fac.base
  1082. if not mul.is_Integer:
  1083. return None
  1084. p = Poly(fac, i)
  1085. if p.degree() != 1:
  1086. return None
  1087. m, n = p.all_coeffs()
  1088. ab[k] *= m**mul
  1089. params[k] += [n/m]*mul
  1090. # Add "1" to numerator parameters, to account for implicit n! in
  1091. # hypergeometric series.
  1092. ap = params[0] + [1]
  1093. bq = params[1]
  1094. x = ab[0]/ab[1]
  1095. h = hyper(ap, bq, x)
  1096. f = combsimp(f)
  1097. return f.subs(i, 0)*hyperexpand(h), h.convergence_statement
  1098. def eval_sum_hyper(f, i_a_b):
  1099. i, a, b = i_a_b
  1100. if f.is_hypergeometric(i) is False:
  1101. return
  1102. if (b - a).is_Integer:
  1103. # We are never going to do better than doing the sum in the obvious way
  1104. return None
  1105. old_sum = Sum(f, (i, a, b))
  1106. if b != S.Infinity:
  1107. if a is S.NegativeInfinity:
  1108. res = _eval_sum_hyper(f.subs(i, -i), i, -b)
  1109. if res is not None:
  1110. return Piecewise(res, (old_sum, True))
  1111. else:
  1112. n_illegal = lambda x: sum(x.count(_) for _ in _illegal)
  1113. had = n_illegal(f)
  1114. # check that no extra illegals are introduced
  1115. res1 = _eval_sum_hyper(f, i, a)
  1116. if res1 is None or n_illegal(res1) > had:
  1117. return
  1118. res2 = _eval_sum_hyper(f, i, b + 1)
  1119. if res2 is None or n_illegal(res2) > had:
  1120. return
  1121. (res1, cond1), (res2, cond2) = res1, res2
  1122. cond = And(cond1, cond2)
  1123. if cond == False:
  1124. return None
  1125. return Piecewise((res1 - res2, cond), (old_sum, True))
  1126. if a is S.NegativeInfinity:
  1127. res1 = _eval_sum_hyper(f.subs(i, -i), i, 1)
  1128. res2 = _eval_sum_hyper(f, i, 0)
  1129. if res1 is None or res2 is None:
  1130. return None
  1131. res1, cond1 = res1
  1132. res2, cond2 = res2
  1133. cond = And(cond1, cond2)
  1134. if cond == False or cond.as_set() == S.EmptySet:
  1135. return None
  1136. return Piecewise((res1 + res2, cond), (old_sum, True))
  1137. # Now b == oo, a != -oo
  1138. res = _eval_sum_hyper(f, i, a)
  1139. if res is not None:
  1140. r, c = res
  1141. if c == False:
  1142. if r.is_number:
  1143. f = f.subs(i, Dummy('i', integer=True, positive=True) + a)
  1144. if f.is_positive or f.is_zero:
  1145. return S.Infinity
  1146. elif f.is_negative:
  1147. return S.NegativeInfinity
  1148. return None
  1149. return Piecewise(res, (old_sum, True))
  1150. def eval_sum_residue(f, i_a_b):
  1151. r"""Compute the infinite summation with residues
  1152. Notes
  1153. =====
  1154. If $f(n), g(n)$ are polynomials with $\deg(g(n)) - \deg(f(n)) \ge 2$,
  1155. some infinite summations can be computed by the following residue
  1156. evaluations.
  1157. .. math::
  1158. \sum_{n=-\infty, g(n) \ne 0}^{\infty} \frac{f(n)}{g(n)} =
  1159. -\pi \sum_{\alpha|g(\alpha)=0}
  1160. \text{Res}(\cot(\pi x) \frac{f(x)}{g(x)}, \alpha)
  1161. .. math::
  1162. \sum_{n=-\infty, g(n) \ne 0}^{\infty} (-1)^n \frac{f(n)}{g(n)} =
  1163. -\pi \sum_{\alpha|g(\alpha)=0}
  1164. \text{Res}(\csc(\pi x) \frac{f(x)}{g(x)}, \alpha)
  1165. Examples
  1166. ========
  1167. >>> from sympy import Sum, oo, Symbol
  1168. >>> x = Symbol('x')
  1169. Doubly infinite series of rational functions.
  1170. >>> Sum(1 / (x**2 + 1), (x, -oo, oo)).doit()
  1171. pi/tanh(pi)
  1172. Doubly infinite alternating series of rational functions.
  1173. >>> Sum((-1)**x / (x**2 + 1), (x, -oo, oo)).doit()
  1174. pi/sinh(pi)
  1175. Infinite series of even rational functions.
  1176. >>> Sum(1 / (x**2 + 1), (x, 0, oo)).doit()
  1177. 1/2 + pi/(2*tanh(pi))
  1178. Infinite series of alternating even rational functions.
  1179. >>> Sum((-1)**x / (x**2 + 1), (x, 0, oo)).doit()
  1180. pi/(2*sinh(pi)) + 1/2
  1181. This also have heuristics to transform arbitrarily shifted summand or
  1182. arbitrarily shifted summation range to the canonical problem the
  1183. formula can handle.
  1184. >>> Sum(1 / (x**2 + 2*x + 2), (x, -1, oo)).doit()
  1185. 1/2 + pi/(2*tanh(pi))
  1186. >>> Sum(1 / (x**2 + 4*x + 5), (x, -2, oo)).doit()
  1187. 1/2 + pi/(2*tanh(pi))
  1188. >>> Sum(1 / (x**2 + 1), (x, 1, oo)).doit()
  1189. -1/2 + pi/(2*tanh(pi))
  1190. >>> Sum(1 / (x**2 + 1), (x, 2, oo)).doit()
  1191. -1 + pi/(2*tanh(pi))
  1192. References
  1193. ==========
  1194. .. [#] http://www.supermath.info/InfiniteSeriesandtheResidueTheorem.pdf
  1195. .. [#] Asmar N.H., Grafakos L. (2018) Residue Theory.
  1196. In: Complex Analysis with Applications.
  1197. Undergraduate Texts in Mathematics. Springer, Cham.
  1198. https://doi.org/10.1007/978-3-319-94063-2_5
  1199. """
  1200. i, a, b = i_a_b
  1201. # If lower limit > upper limit: Karr Summation Convention
  1202. if a.is_comparable and b.is_comparable and a > b:
  1203. return eval_sum_residue(f, (i, b + S.One, a - S.One))
  1204. def is_even_function(numer, denom):
  1205. """Test if the rational function is an even function"""
  1206. numer_even = all(i % 2 == 0 for (i,) in numer.monoms())
  1207. denom_even = all(i % 2 == 0 for (i,) in denom.monoms())
  1208. numer_odd = all(i % 2 == 1 for (i,) in numer.monoms())
  1209. denom_odd = all(i % 2 == 1 for (i,) in denom.monoms())
  1210. return (numer_even and denom_even) or (numer_odd and denom_odd)
  1211. def match_rational(f, i):
  1212. numer, denom = f.as_numer_denom()
  1213. try:
  1214. (numer, denom), opt = parallel_poly_from_expr((numer, denom), i)
  1215. except (PolificationFailed, PolynomialError):
  1216. return None
  1217. return numer, denom
  1218. def get_poles(denom):
  1219. roots = denom.sqf_part().all_roots()
  1220. roots = sift(roots, lambda x: x.is_integer)
  1221. if None in roots:
  1222. return None
  1223. int_roots, nonint_roots = roots[True], roots[False]
  1224. return int_roots, nonint_roots
  1225. def get_shift(denom):
  1226. n = denom.degree(i)
  1227. a = denom.coeff_monomial(i**n)
  1228. b = denom.coeff_monomial(i**(n-1))
  1229. shift = - b / a / n
  1230. return shift
  1231. #Need a dummy symbol with no assumptions set for get_residue_factor
  1232. z = Dummy('z')
  1233. def get_residue_factor(numer, denom, alternating):
  1234. residue_factor = (numer.as_expr() / denom.as_expr()).subs(i, z)
  1235. if not alternating:
  1236. residue_factor *= cot(S.Pi * z)
  1237. else:
  1238. residue_factor *= csc(S.Pi * z)
  1239. return residue_factor
  1240. # We don't know how to deal with symbolic constants in summand
  1241. if f.free_symbols - {i}:
  1242. return None
  1243. if not (a.is_Integer or a in (S.Infinity, S.NegativeInfinity)):
  1244. return None
  1245. if not (b.is_Integer or b in (S.Infinity, S.NegativeInfinity)):
  1246. return None
  1247. # Quick exit heuristic for the sums which doesn't have infinite range
  1248. if a != S.NegativeInfinity and b != S.Infinity:
  1249. return None
  1250. match = match_rational(f, i)
  1251. if match:
  1252. alternating = False
  1253. numer, denom = match
  1254. else:
  1255. match = match_rational(f / S.NegativeOne**i, i)
  1256. if match:
  1257. alternating = True
  1258. numer, denom = match
  1259. else:
  1260. return None
  1261. if denom.degree(i) - numer.degree(i) < 2:
  1262. return None
  1263. if (a, b) == (S.NegativeInfinity, S.Infinity):
  1264. poles = get_poles(denom)
  1265. if poles is None:
  1266. return None
  1267. int_roots, nonint_roots = poles
  1268. if int_roots:
  1269. return None
  1270. residue_factor = get_residue_factor(numer, denom, alternating)
  1271. residues = [residue(residue_factor, z, root) for root in nonint_roots]
  1272. return -S.Pi * sum(residues)
  1273. if not (a.is_finite and b is S.Infinity):
  1274. return None
  1275. if not is_even_function(numer, denom):
  1276. # Try shifting summation and check if the summand can be made
  1277. # and even function from the origin.
  1278. # Sum(f(n), (n, a, b)) => Sum(f(n + s), (n, a - s, b - s))
  1279. shift = get_shift(denom)
  1280. if not shift.is_Integer:
  1281. return None
  1282. if shift == 0:
  1283. return None
  1284. numer = numer.shift(shift)
  1285. denom = denom.shift(shift)
  1286. if not is_even_function(numer, denom):
  1287. return None
  1288. if alternating:
  1289. f = S.NegativeOne**i * (S.NegativeOne**shift * numer.as_expr() / denom.as_expr())
  1290. else:
  1291. f = numer.as_expr() / denom.as_expr()
  1292. return eval_sum_residue(f, (i, a-shift, b-shift))
  1293. poles = get_poles(denom)
  1294. if poles is None:
  1295. return None
  1296. int_roots, nonint_roots = poles
  1297. if int_roots:
  1298. int_roots = [int(root) for root in int_roots]
  1299. int_roots_max = max(int_roots)
  1300. int_roots_min = min(int_roots)
  1301. # Integer valued poles must be next to each other
  1302. # and also symmetric from origin (Because the function is even)
  1303. if not len(int_roots) == int_roots_max - int_roots_min + 1:
  1304. return None
  1305. # Check whether the summation indices contain poles
  1306. if a <= max(int_roots):
  1307. return None
  1308. residue_factor = get_residue_factor(numer, denom, alternating)
  1309. residues = [residue(residue_factor, z, root) for root in int_roots + nonint_roots]
  1310. full_sum = -S.Pi * sum(residues)
  1311. if not int_roots:
  1312. # Compute Sum(f, (i, 0, oo)) by adding a extraneous evaluation
  1313. # at the origin.
  1314. half_sum = (full_sum + f.xreplace({i: 0})) / 2
  1315. # Add and subtract extraneous evaluations
  1316. extraneous_neg = [f.xreplace({i: i0}) for i0 in range(int(a), 0)]
  1317. extraneous_pos = [f.xreplace({i: i0}) for i0 in range(0, int(a))]
  1318. result = half_sum + sum(extraneous_neg) - sum(extraneous_pos)
  1319. return result
  1320. # Compute Sum(f, (i, min(poles) + 1, oo))
  1321. half_sum = full_sum / 2
  1322. # Subtract extraneous evaluations
  1323. extraneous = [f.xreplace({i: i0}) for i0 in range(max(int_roots) + 1, int(a))]
  1324. result = half_sum - sum(extraneous)
  1325. return result
  1326. def _eval_matrix_sum(expression):
  1327. f = expression.function
  1328. for limit in expression.limits:
  1329. i, a, b = limit
  1330. dif = b - a
  1331. if dif.is_Integer:
  1332. if (dif < 0) == True:
  1333. a, b = b + 1, a - 1
  1334. f = -f
  1335. newf = eval_sum_direct(f, (i, a, b))
  1336. if newf is not None:
  1337. return newf.doit()
  1338. def _dummy_with_inherited_properties_concrete(limits):
  1339. """
  1340. Return a Dummy symbol that inherits as many assumptions as possible
  1341. from the provided symbol and limits.
  1342. If the symbol already has all True assumption shared by the limits
  1343. then return None.
  1344. """
  1345. x, a, b = limits
  1346. l = [a, b]
  1347. assumptions_to_consider = ['extended_nonnegative', 'nonnegative',
  1348. 'extended_nonpositive', 'nonpositive',
  1349. 'extended_positive', 'positive',
  1350. 'extended_negative', 'negative',
  1351. 'integer', 'rational', 'finite',
  1352. 'zero', 'real', 'extended_real']
  1353. assumptions_to_keep = {}
  1354. assumptions_to_add = {}
  1355. for assum in assumptions_to_consider:
  1356. assum_true = x._assumptions.get(assum, None)
  1357. if assum_true:
  1358. assumptions_to_keep[assum] = True
  1359. elif all(getattr(i, 'is_' + assum) for i in l):
  1360. assumptions_to_add[assum] = True
  1361. if assumptions_to_add:
  1362. assumptions_to_keep.update(assumptions_to_add)
  1363. return Dummy('d', **assumptions_to_keep)