Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

2084 #29

Closed
wants to merge 1 commit into from

1 participant

@smichr
Collaborator

These commits fix errors with evaluating limits from the negative direction (see issue 2084).

@smichr smichr 2084 limit issues from the "-" direction
limit(1 + 1/x, x, 0, '-') was giving oo because it takes as the
unbounded result the value obtained when substituting x with 0
into the 1/x term. Instead, having quickly determined that the
term is unbounded (and not nan) it should then recalculate the
value from the desired direction.

In addition, limits involving powers evaluated from the negative
direction were added, i.e. 1/x**a with dir="-"

tests were added
cc01f82
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 4, 2011
  1. @smichr

    2084 limit issues from the "-" direction

    smichr authored
    limit(1 + 1/x, x, 0, '-') was giving oo because it takes as the
    unbounded result the value obtained when substituting x with 0
    into the 1/x term. Instead, having quickly determined that the
    term is unbounded (and not nan) it should then recalculate the
    value from the desired direction.
    
    In addition, limits involving powers evaluated from the negative
    direction were added, i.e. 1/x**a with dir="-"
    
    tests were added
This page is out of date. Refresh to see the latest.
Showing with 64 additions and 26 deletions.
  1. +20 −7 sympy/series/limits.py
  2. +44 −19 sympy/series/tests/test_limits.py
View
27 sympy/series/limits.py
@@ -40,18 +40,28 @@ def limit(e, z, z0, dir="+"):
if e.is_Rational:
return e
- if e.is_Pow and e.args[0] == z and e.args[1].is_number:
- if e.args[1] > 0:
- return z0**e.args[1]
- if z0 == 0:
- if dir == "+":
+ if e.is_Pow:
+ b, ex = e.args
+ if b == z and ex.is_number:
+ if z0 == 0 and ex < 0:
+ if dir == '-':
+ # integer
+ if ex.is_even:
+ return S.Infinity
+ elif ex.is_odd:
+ return S.NegativeInfinity
+ # rational
+ elif ex.is_Rational:
+ return S.ImaginaryUnit*S.Infinity
+ else:
+ return S.ComplexInfinity
return S.Infinity
- return -S.Infinity
- return z0**e.args[1]
+ return z0**ex
if e.is_Add:
if e.is_polynomial() and z0.is_finite:
return Add(*[limit(term, z, z0, dir) for term in e.args])
+
# this is a case like limit(x*y+x*z, z, 2) == x*y+2*x
# but we need to make sure, that the general gruntz() algorithm is
# executed for a case like "limit(sqrt(x+1)-sqrt(x),x,oo)==0"
@@ -61,6 +71,9 @@ def limit(e, z, z0, dir="+"):
result = term.subs(z, z0)
if result.is_unbounded or result is S.NaN:
unbounded.append(term)
+ if result != S.NaN:
+ # take result from direction given
+ result = limit(term, z, z0, dir)
unbounded_result.append(result)
else:
finite.append(result)
View
63 sympy/series/tests/test_limits.py
@@ -1,7 +1,8 @@
from sympy import limit, exp, oo, log, sqrt, Limit, sin, floor, cos, ceiling, \
- atan, gamma, Symbol, S, pi, Integral, cot
+ atan, gamma, Symbol, S, pi, Integral, cot, Rational, I, zoo
from sympy.abc import x, y, z
from sympy.utilities.pytest import XFAIL
+from sympy.utilities.iterables import cartes
def test_basic1():
assert limit(x, x, oo) == oo
@@ -10,24 +11,38 @@ def test_basic1():
assert limit(x**2, x, -oo) == oo
assert limit(-x**2, x, oo) == -oo
assert limit(x*log(x), x, 0, dir="+") == 0
- assert limit(1/x,x,oo) == 0
- assert limit(exp(x),x,oo) == oo
- assert limit(-exp(x),x,oo) == -oo
- assert limit(exp(x)/x,x,oo) == oo
- assert limit(1/x-exp(-x),x,oo) == 0
- assert limit(x+1/x,x,oo) == oo
- assert limit(x-x**2,x,oo) == -oo
-
+ assert limit(1/x, x, oo) == 0
+ assert limit(exp(x), x, oo) == oo
+ assert limit(-exp(x), x, oo) == -oo
+ assert limit(exp(x)/x, x, oo) == oo
+ assert limit(1/x - exp(-x), x, oo) == 0
+ assert limit(x+1/x, x, oo) == oo
+ assert limit(x-x**2, x, oo) == -oo
+
+
+ # approaching 0
+ # from dir="+"
+ assert limit(1 + 1/x, x, 0) == oo
+ # from dir='-'
+ # Add
+ assert limit(1 + 1/x, x, 0, dir='-') == -oo
+ # Pow
+ assert limit(x**(-2), x, 0, dir='-') == oo
+ assert limit(x**(-3), x, 0, dir='-') == -oo
+ assert limit(x**(-Rational(1, 2)), x, 0, dir='-') == (oo)*I
+ assert limit(x**2, x, 0, dir='-') == 0
+ assert limit(x**(Rational(1, 2)), x, 0, dir='-') == 0
+ assert limit(x**-pi, x, 0, dir='-') == zoo
def test_basic2():
assert limit(x**x, x, 0, dir="+") == 1
assert limit((exp(x)-1)/x, x, 0) == 1
- assert limit(1+1/x,x,oo) == 1
- assert limit(-exp(1/x),x,oo) == -1
- assert limit(x+exp(-x),x,oo) == oo
- assert limit(x+exp(-x**2),x,oo) == oo
- assert limit(x+exp(-exp(x)),x,oo) == oo
- assert limit(13+1/x-exp(-x),x,oo) == 13
+ assert limit(1 + 1/x, x, oo) == 1
+ assert limit(-exp(1/x), x, oo) == -1
+ assert limit(x + exp(-x), x, oo) == oo
+ assert limit(x + exp(-x**2), x, oo) == oo
+ assert limit(x + exp(-exp(x)), x, oo) == oo
+ assert limit(13 + 1/x - exp(-x), x, oo) == 13
def test_basic3():
assert limit(1/x, x, 0, dir="+") == oo
@@ -36,11 +51,11 @@ def test_basic3():
def test_basic4():
assert limit(2*x + y*x, x, 0) == 0
assert limit(2*x + y*x, x, 1) == 2+y
- assert limit(2*x**8 + y*x**(-3), x, -2) == 512-y/8
- assert limit(sqrt(x+1)-sqrt(x),x,oo)==0
+ assert limit(2*x**8 + y*x**(-3), x, -2) == 512 - y/8
+ assert limit(sqrt(x + 1) - sqrt(x), x, oo)==0
def test_issue786():
- assert limit(x*y+x*z, z, 2) == x*y+2*x
+ assert limit(x*y + x*z, z, 2) == x*y+2*x
def test_Limit():
assert Limit(sin(x)/x, x, 0) != 1
@@ -174,6 +189,16 @@ def test_issue2065():
assert limit(x**(-0.5), x, oo) == 0
assert limit(x**(-0.5), x, 4) == S(4)**(-0.5)
+def test_issue2084():
+ tests = list(cartes([-1, 1], [2, 3, Rational(1, 2), Rational(2, 3)],
+ ['-', '+'])) # using list() so py.test can recalculate values
+ results = (oo, oo, -oo, oo, oo*I, oo, oo*I, oo, 0, 0, 0, 0, 0, 0, 0, 0)
+ assert len(tests) == len(results)
+ for args, res in zip(tests, results):
+ s, e, d = args
+ eq=x**(s*e)
+ assert limit(eq, x, 0, dir=d) == res
+
def test_issue2085():
assert limit(sin(x)/x, x, oo) == 0
assert limit(atan(x), x, oo) == pi/2
@@ -182,4 +207,4 @@ def test_issue2085():
@XFAIL
def test_issue2085_unresolved():
assert limit(cos(x)/x, x, oo) == 0 # Raises ZeroDivisionError
- assert limit(gamma(x), x, 1/2) == sqrt(pi) # Raises AssertionError
+ assert limit(gamma(x), x, Rational(1, 2)) == sqrt(pi) # Raises AssertionError
Something went wrong with that request. Please try again.