def limitinf(e, x): """Limit e(x) for x-> oo""" if not e.has(x): return e #e is a constant #this is needed to simplify 1/log(exp(-x**2))*log(exp(x**2)) to 1 if e.has(log): e = e.normal() c0, e0 = mrv_leadterm(e,x) sig=sign(e0,x) if sig==1: return S.Zero # e0>0: lim f = 0 elif sig==-1: #e0<0: lim f = +-oo (the sign depends on the sign of c0) if c0.match(I*C.Wild("a", exclude=[I])): return c0*oo s = sign(c0, x) #the leading term shouldn't be 0: assert s != 0 return s * oo elif sig==0: return limitinf(c0, x) #e0=0: lim f = lim c0
if not L.has(i): sR = eval_sum_symbolic(R, (i, a, b)) if sR: return L * sR if not R.has(i): sL = eval_sum_symbolic(L, (i, a, b)) if sL: return R * sL if f.is_Add: L, R = getab(f) lrsum = telescopic(L, R, (i, a, b)) if lrsum: return lrsum lsum = eval_sum_symbolic(L, (i, a, b)) rsum = eval_sum_symbolic(R, (i, a, b)) if None not in (lsum, rsum): return lsum + rsum # Polynomial terms with Faulhaber's formula p = C.Wild('p') e = f.match(i**p) if e != None: c = p.subs(e) B = C.bernoulli if c.is_integer and c >= 0: s = (B(c + 1, b + 1) - B(c + 1, a)) / (c + 1) return s.expand() # Geometric terms c1 = C.Wild('c1', exclude=[i]) c2 = C.Wild('c2', exclude=[i]) c3 = C.Wild('c3', exclude=[i]) e = f.match(c1**(c2 * i + c3)) if e is not None: c1 = c1.subs(e) c2 = c2.subs(e)
def eval_sum_symbolic(f, limits): (i, a, b) = limits if not f.has(i): return f * (b - a + 1) # Linearity if f.is_Mul: L, R = f.as_two_terms() if not L.has(i): sR = eval_sum_symbolic(R, (i, a, b)) if sR: return L * sR if not R.has(i): sL = eval_sum_symbolic(L, (i, a, b)) if sL: return R * sL try: f = apart(f, i) # see if it becomes an Add except PolynomialError: pass if f.is_Add: L, R = f.as_two_terms() lrsum = telescopic(L, R, (i, a, b)) if lrsum: return lrsum lsum = eval_sum_symbolic(L, (i, a, b)) rsum = eval_sum_symbolic(R, (i, a, b)) if None not in (lsum, rsum): return lsum + rsum # Polynomial terms with Faulhaber's formula n = Wild('n') result = f.match(i**n) if result is not None: n = result[n] if n.is_Integer: if n >= 0: return ((C.bernoulli(n + 1, b + 1) - C.bernoulli(n + 1, a)) / (n + 1)).expand() elif a.is_Integer and a >= 1: if n == -1: return C.harmonic(b) - C.harmonic(a - 1) else: return C.harmonic(b, abs(n)) - C.harmonic(a - 1, abs(n)) # Geometric terms c1 = C.Wild('c1', exclude=[i]) c2 = C.Wild('c2', exclude=[i]) c3 = C.Wild('c3', exclude=[i]) e = f.match(c1**(c2 * i + c3)) if e is not None: c1 = c1.subs(e) c2 = c2.subs(e) c3 = c3.subs(e) # TODO: more general limit handling return c1**c3 * (c1**(a * c2) - c1**(c2 + b * c2)) / (1 - c1**c2) r = gosper_sum(f, (i, a, b)) if not r in (None, S.NaN): return r return eval_sum_hyper(f, (i, a, b))
def eval_sum_symbolic(f, limits): (i, a, b) = limits if not f.has(i): return f * (b - a + 1) # Linearity if f.is_Mul: L, R = f.as_two_terms() if not L.has(i): sR = eval_sum_symbolic(R, (i, a, b)) if sR: return L * sR if not R.has(i): sL = eval_sum_symbolic(L, (i, a, b)) if sL: return R * sL try: f = apart(f, i) # see if it becomes an Add except PolynomialError: pass if f.is_Add: L, R = f.as_two_terms() lrsum = telescopic(L, R, (i, a, b)) if lrsum: return lrsum lsum = eval_sum_symbolic(L, (i, a, b)) rsum = eval_sum_symbolic(R, (i, a, b)) if None not in (lsum, rsum): return lsum + rsum # Polynomial terms with Faulhaber's formula n = Wild('n') result = f.match(i**n) if result is not None: n = result[n] if n.is_Integer: if n >= 0: return ((C.bernoulli(n + 1, b + 1) - C.bernoulli(n + 1, a)) / (n + 1)).expand() elif a.is_Integer and a >= 1: if n == -1: return C.harmonic(b) - C.harmonic(a - 1) else: return C.harmonic(b, abs(n)) - C.harmonic(a - 1, abs(n)) if not (a.has(S.Infinity, S.NegativeInfinity) or b.has(S.Infinity, S.NegativeInfinity)): # Geometric terms c1 = C.Wild('c1', exclude=[i]) c2 = C.Wild('c2', exclude=[i]) c3 = C.Wild('c3', exclude=[i]) e = f.match(c1**(c2 * i + c3)) if e is not None: p = (c1**c3).subs(e) q = (c1**c2).subs(e) r = p * (q**a - q**(b + 1)) / (1 - q) l = p * (b - a + 1) return Piecewise((l, Eq(q, S.One)), (r, True)) r = gosper_sum(f, (i, a, b)) if not r in (None, S.NaN): return r return eval_sum_hyper(f, (i, a, b))