Skip to content
This repository

2084 #29

Closed
wants to merge 1 commit into from

1 participant

Christopher Smith
Christopher Smith
Collaborator

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

Christopher Smith 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

Showing 1 unique commit by 1 author.

Jan 04, 2011
Christopher Smith 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 page is out of date. Refresh to see the latest.
27  sympy/series/limits.py
@@ -40,18 +40,28 @@ def limit(e, z, z0, dir="+"):
40 40
     if e.is_Rational:
41 41
         return e
42 42
 
43  
-    if e.is_Pow and e.args[0] == z and e.args[1].is_number:
44  
-        if e.args[1] > 0:
45  
-            return z0**e.args[1]
46  
-        if z0 == 0:
47  
-            if dir == "+":
  43
+    if e.is_Pow:
  44
+        b, ex = e.args
  45
+        if b == z and ex.is_number:
  46
+            if z0 == 0 and ex < 0:
  47
+                if dir == '-':
  48
+                    # integer
  49
+                    if ex.is_even:
  50
+                        return S.Infinity
  51
+                    elif ex.is_odd:
  52
+                        return S.NegativeInfinity
  53
+                    # rational
  54
+                    elif ex.is_Rational:
  55
+                        return S.ImaginaryUnit*S.Infinity
  56
+                    else:
  57
+                        return S.ComplexInfinity
48 58
                 return S.Infinity
49  
-            return -S.Infinity
50  
-        return z0**e.args[1]
  59
+            return z0**ex
51 60
 
52 61
     if e.is_Add:
53 62
         if e.is_polynomial() and z0.is_finite:
54 63
             return Add(*[limit(term, z, z0, dir) for term in e.args])
  64
+
55 65
         # this is a case like limit(x*y+x*z, z, 2) == x*y+2*x
56 66
         # but we need to make sure, that the general gruntz() algorithm is
57 67
         # executed for a case like "limit(sqrt(x+1)-sqrt(x),x,oo)==0"
@@ -61,6 +71,9 @@ def limit(e, z, z0, dir="+"):
61 71
             result = term.subs(z, z0)
62 72
             if result.is_unbounded or result is S.NaN:
63 73
                 unbounded.append(term)
  74
+                if result != S.NaN:
  75
+                    # take result from direction given
  76
+                    result = limit(term, z, z0, dir)
64 77
                 unbounded_result.append(result)
65 78
             else:
66 79
                 finite.append(result)
63  sympy/series/tests/test_limits.py
... ...
@@ -1,7 +1,8 @@
1 1
 from sympy import limit, exp, oo, log, sqrt, Limit, sin, floor, cos, ceiling, \
2  
-        atan, gamma, Symbol, S, pi, Integral, cot
  2
+        atan, gamma, Symbol, S, pi, Integral, cot, Rational, I, zoo
3 3
 from sympy.abc import x, y, z
4 4
 from sympy.utilities.pytest import XFAIL
  5
+from sympy.utilities.iterables import cartes
5 6
 
6 7
 def test_basic1():
7 8
     assert limit(x, x, oo) == oo
@@ -10,24 +11,38 @@ def test_basic1():
10 11
     assert limit(x**2, x, -oo) == oo
11 12
     assert limit(-x**2, x, oo) == -oo
12 13
     assert limit(x*log(x), x, 0, dir="+") == 0
13  
-    assert limit(1/x,x,oo) == 0
14  
-    assert limit(exp(x),x,oo) == oo
15  
-    assert limit(-exp(x),x,oo) == -oo
16  
-    assert limit(exp(x)/x,x,oo) == oo
17  
-    assert limit(1/x-exp(-x),x,oo) == 0
18  
-    assert limit(x+1/x,x,oo) == oo
19  
-    assert limit(x-x**2,x,oo) == -oo
20  
-
  14
+    assert limit(1/x, x, oo) == 0
  15
+    assert limit(exp(x), x, oo) == oo
  16
+    assert limit(-exp(x), x, oo) == -oo
  17
+    assert limit(exp(x)/x, x, oo) == oo
  18
+    assert limit(1/x - exp(-x), x, oo) == 0
  19
+    assert limit(x+1/x, x, oo) == oo
  20
+    assert limit(x-x**2, x, oo) == -oo
  21
+
  22
+
  23
+    # approaching 0
  24
+    # from dir="+"
  25
+    assert limit(1 + 1/x, x, 0) == oo
  26
+    # from dir='-'
  27
+    # Add
  28
+    assert limit(1 + 1/x, x, 0, dir='-') == -oo
  29
+    # Pow
  30
+    assert limit(x**(-2), x, 0, dir='-') == oo
  31
+    assert limit(x**(-3), x, 0, dir='-') == -oo
  32
+    assert limit(x**(-Rational(1, 2)), x, 0, dir='-') == (oo)*I
  33
+    assert limit(x**2, x, 0, dir='-') == 0
  34
+    assert limit(x**(Rational(1, 2)), x, 0, dir='-') == 0
  35
+    assert limit(x**-pi, x, 0, dir='-') == zoo
21 36
 
22 37
 def test_basic2():
23 38
     assert limit(x**x, x, 0, dir="+") == 1
24 39
     assert limit((exp(x)-1)/x, x, 0) == 1
25  
-    assert limit(1+1/x,x,oo) == 1
26  
-    assert limit(-exp(1/x),x,oo) == -1
27  
-    assert limit(x+exp(-x),x,oo) == oo
28  
-    assert limit(x+exp(-x**2),x,oo) == oo
29  
-    assert limit(x+exp(-exp(x)),x,oo) == oo
30  
-    assert limit(13+1/x-exp(-x),x,oo) == 13
  40
+    assert limit(1 + 1/x, x, oo) == 1
  41
+    assert limit(-exp(1/x), x, oo) == -1
  42
+    assert limit(x + exp(-x), x, oo) == oo
  43
+    assert limit(x + exp(-x**2), x, oo) == oo
  44
+    assert limit(x + exp(-exp(x)), x, oo) == oo
  45
+    assert limit(13 + 1/x - exp(-x), x, oo) == 13
31 46
 
32 47
 def test_basic3():
33 48
     assert limit(1/x, x, 0, dir="+") == oo
@@ -36,11 +51,11 @@ def test_basic3():
36 51
 def test_basic4():
37 52
     assert limit(2*x + y*x, x, 0) == 0
38 53
     assert limit(2*x + y*x, x, 1) == 2+y
39  
-    assert limit(2*x**8 + y*x**(-3), x, -2) == 512-y/8
40  
-    assert limit(sqrt(x+1)-sqrt(x),x,oo)==0
  54
+    assert limit(2*x**8 + y*x**(-3), x, -2) == 512 - y/8
  55
+    assert limit(sqrt(x + 1) - sqrt(x), x, oo)==0
41 56
 
42 57
 def test_issue786():
43  
-    assert limit(x*y+x*z, z, 2) == x*y+2*x
  58
+    assert limit(x*y + x*z, z, 2) == x*y+2*x
44 59
 
45 60
 def test_Limit():
46 61
     assert Limit(sin(x)/x, x, 0) != 1
@@ -174,6 +189,16 @@ def test_issue2065():
174 189
     assert limit(x**(-0.5), x, oo) == 0
175 190
     assert limit(x**(-0.5), x, 4) == S(4)**(-0.5)
176 191
 
  192
+def test_issue2084():
  193
+    tests = list(cartes([-1, 1], [2, 3, Rational(1, 2), Rational(2, 3)],
  194
+                ['-', '+'])) # using list() so py.test can recalculate values
  195
+    results = (oo, oo, -oo, oo, oo*I, oo, oo*I, oo, 0, 0, 0, 0, 0, 0, 0, 0)
  196
+    assert len(tests) == len(results)
  197
+    for args, res in zip(tests, results):
  198
+        s, e, d = args
  199
+        eq=x**(s*e)
  200
+        assert limit(eq, x, 0, dir=d) == res
  201
+
177 202
 def test_issue2085():
178 203
     assert limit(sin(x)/x, x, oo) == 0
179 204
     assert limit(atan(x), x, oo) == pi/2
@@ -182,4 +207,4 @@ def test_issue2085():
182 207
 @XFAIL
183 208
 def test_issue2085_unresolved():
184 209
     assert limit(cos(x)/x, x, oo) == 0 # Raises ZeroDivisionError
185  
-    assert limit(gamma(x), x, 1/2) == sqrt(pi) # Raises AssertionError
  210
+    assert limit(gamma(x), x, Rational(1, 2)) == sqrt(pi) # Raises AssertionError
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.