Skip to content

Commit

Permalink
Merge pull request #1261 from ness01/summation
Browse files Browse the repository at this point in the history
Summation improvements.
  • Loading branch information
ness01 committed Apr 25, 2012
2 parents e1a79e8 + 340b130 commit dafbe16
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 5 deletions.
14 changes: 12 additions & 2 deletions sympy/concrete/summations.py
Expand Up @@ -479,13 +479,15 @@ def eval_sum_symbolic(f, limits):
def _eval_sum_hyper(f, i, a):
""" Returns (res, cond). Sums from a to oo. """
from sympy.functions import hyper
from sympy.simplify import hyperexpand, hypersimp, fraction
from sympy.simplify import hyperexpand, hypersimp, fraction, simplify
from sympy.polys.polytools import Poly, factor

if a != 0:
return _eval_sum_hyper(f.subs(i, i + a), i, 0)

if f.subs(i, 0) == 0:
if simplify(f.subs(i, Dummy('i', integer=True, positive=True))) == 0:
return S(0), True
return _eval_sum_hyper(f.subs(i, i + 1), i, 0)

hs = hypersimp(f, i)
Expand Down Expand Up @@ -532,7 +534,15 @@ def eval_sum_hyper(f, (i, a, b)):
if res is not None:
return Piecewise(res, (Sum(f, (i, a, b)), True))
else:
return None
res1 = _eval_sum_hyper(f, i, a)
res2 = _eval_sum_hyper(f, i, b + 1)
if res1 is None or res2 is None:
return None
(res1, cond1), (res2, cond2) = res1, res2
cond = And(cond1, cond2)
if cond is False:
return None
return Piecewise((res1 - res2, cond), (Sum(f, (i, a, b)), True))

if a == -oo:
res1 = _eval_sum_hyper(f.subs(i, -i), i, 1)
Expand Down
3 changes: 3 additions & 0 deletions sympy/concrete/tests/test_sums_products.py
Expand Up @@ -289,6 +289,9 @@ def test_hypersum():
assert s.args[0].args[0] == -1/(x*(1 - 1/x)**2)
assert s.args[0].args[1] == (abs(1/x) < 1)

m = Symbol('n', integer=True, positive=True)
assert summation(binomial(m, k), (k, 0, m)) == 2**m

def test_issue_1071():
assert summation(1/factorial(k), (k, 0, oo)) == E

Expand Down
2 changes: 2 additions & 0 deletions sympy/functions/combinatorial/factorials.py
Expand Up @@ -463,6 +463,8 @@ def eval(cls, n, k):
return result
elif k.is_negative:
return S.Zero
elif (n - k).simplify().is_negative:
return S.Zero
else:
d = n - k

Expand Down
Expand Up @@ -120,6 +120,7 @@ def test_binomial():
assert binomial(n, u) == 0
assert binomial(n, v).func == binomial
assert binomial(n, k).func == binomial
assert binomial(n, n + v) == 0

def test_binomial_diff():
n = Symbol('n', integer=True)
Expand Down
5 changes: 2 additions & 3 deletions sympy/simplify/hyperexpand.py
Expand Up @@ -1932,7 +1932,7 @@ def _hyperexpand(ip, z, ops0=[], z0=Dummy('z0'), premult=1, prem=0,
is multiplied by premult. Then ops0 is applied.
premult must be a*z**prem for some a independent of z.
"""
from sympy.simplify import powdenest, simplify, polarify
from sympy.simplify import powdenest, simplify, polarify, unpolarify
z = polarify(z, subs=False)
if rewrite == 'default':
rewrite = 'nonrepsmall'
Expand Down Expand Up @@ -1977,7 +1977,7 @@ def carryout_plan(f, ops):
debug(' Recognised polynomial.')
p = apply_operators(res, ops, lambda f: z0*f.diff(z0))
p = apply_operators(p*premult, ops0, lambda f: z0*f.diff(z0))
return simplify(p).subs(z0, z)
return unpolarify(simplify(p).subs(z0, z))

# Try to recognise a shifted sum.
p = S(0)
Expand All @@ -1993,7 +1993,6 @@ def carryout_plan(f, ops):
p = simplify(p).subs(z0, z)

# Try special expansions early.
from sympy import unpolarify
if unpolarify(z) in [1, -1] and (len(nip.ap), len(nip.bq)) == (2, 1):
f = build_hypergeometric_formula(nip)
r = carryout_plan(f, ops).replace(hyper, hyperexpand_special)
Expand Down
4 changes: 4 additions & 0 deletions sympy/simplify/tests/test_hyperexpand.py
Expand Up @@ -934,3 +934,7 @@ def test_prudnikov_fail_other():

# XXX this does not *evaluate* right??
assert can_do([], [a, a + S.Half, 2*a-1])

def test_bug():
h = hyper([-1, 1], [z], -1)
assert hyperexpand(h) == (z + 1)/z

0 comments on commit dafbe16

Please sign in to comment.