summations.py 54 KB

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