# publicsympy/sympy

### Subversion checkout URL

You can clone with HTTPS or Subversion.

# 2084#29

Closed
wants to merge 1 commit into from
 +64 26

### 1 participant

Collaborator

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

 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.

Showing 1 unique commit by 1 author.

Jan 04, 2011
`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="-"

`cc01f82`
 `@@ -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)`
 ... ... `@@ -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`