Repository: sympy/sympy

Issue:
Order at negative infinity
The concept of Order at negative infinity seems to not be supported: 
```
>>> from sympy import *
>>> from sympy.abc import x
>>> O(x**(-6), (x, -oo))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/k3/sympy/sympy/series/order.py", line 218, in __new__
    expr = expr.as_leading_term(*args)
  File "/home/k3/sympy/sympy/core/expr.py", line 2960, in as_leading_term
    raise ValueError('expecting a Symbol but got %s' % x)
ValueError: expecting a Symbol but got nan
```
This concept is necessary to correctly express the following asymptotic, which is currently wrong. 
```
>>> series(exp(x), x, -oo)
O(x**(-6), (x, oo))
```
(should be `O(x**(-6), (x, -oo))`)

Discussion:

Patch:
diff --git a/sympy/core/expr.py b/sympy/core/expr.py
index 87eec1eb1e..7800aaf06b 100644
--- a/sympy/core/expr.py
+++ b/sympy/core/expr.py
@@ -2652,11 +2652,12 @@ def series(self, x=None, x0=0, n=6, dir="+", logx=None):
             raise ValueError("Dir must be '+' or '-'")
 
         if x0 in [S.Infinity, S.NegativeInfinity]:
-            dir = {S.Infinity: '+', S.NegativeInfinity: '-'}[x0]
-            s = self.subs(x, 1/x).series(x, n=n, dir=dir)
+            sgn = 1 if x0 is S.Infinity else -1
+            s = self.subs(x, sgn/x).series(x, n=n, dir='+')
             if n is None:
-                return (si.subs(x, 1/x) for si in s)
-            return s.subs(x, 1/x)
+                return (si.subs(x, sgn/x) for si in s)
+            return s.subs(x, sgn/x)
+
 
         # use rep to shift origin to x0 and change sign (if dir is negative)
         # and undo the process with rep2
diff --git a/sympy/series/order.py b/sympy/series/order.py
index ddbd2988fe..b2788bc209 100644
--- a/sympy/series/order.py
+++ b/sympy/series/order.py
@@ -184,6 +184,9 @@ def __new__(cls, expr, *args, **kwargs):
             if point[0] is S.Infinity:
                 s = {k: 1/Dummy() for k in variables}
                 rs = {1/v: 1/k for k, v in s.items()}
+            elif point[0] is S.NegativeInfinity:
+                s = {k: -1/Dummy() for k in variables}
+                rs = {-1/v: -1/k for k, v in s.items()}
             elif point[0] is not S.Zero:
                 s = dict((k, Dummy() + point[0]) for k in variables)
                 rs = dict((v - point[0], k - point[0]) for k, v in s.items())


Test patch:
diff --git a/sympy/series/tests/test_order.py b/sympy/series/tests/test_order.py
index 736b14d13f..903104b3bc 100644
--- a/sympy/series/tests/test_order.py
+++ b/sympy/series/tests/test_order.py
@@ -428,3 +428,10 @@ def test_issue_14622():
     assert O(x, (x, oo)).contains(O(x, (x, 0))) is None
     assert O(x, (x, 0)).contains(O(x, (x, oo))) is None
     raises(NotImplementedError, lambda: O(x**3).contains(x**w))
+
+
+def test_issue_15539():
+    assert O(1/x**2 + 1/x**4, (x, -oo)) == O(1/x**2, (x, -oo))
+    assert O(1/x**4 + exp(x), (x, -oo)) == O(1/x**4, (x, -oo))
+    assert O(1/x**4 + exp(-x), (x, -oo)) == O(exp(-x), (x, -oo))
+    assert O(1/x, (x, oo)).subs(x, -x) == O(-1/x, (x, -oo))
diff --git a/sympy/series/tests/test_series.py b/sympy/series/tests/test_series.py
index 430c272543..5c04177a59 100644
--- a/sympy/series/tests/test_series.py
+++ b/sympy/series/tests/test_series.py
@@ -206,3 +206,7 @@ def test_issue_14885():
     assert series(x**(-S(3)/2)*exp(x), x, 0) == (x**(-S(3)/2) + 1/sqrt(x) +
         sqrt(x)/2 + x**(S(3)/2)/6 + x**(S(5)/2)/24 + x**(S(7)/2)/120 +
         x**(S(9)/2)/720 + x**(S(11)/2)/5040 + O(x**6))
+
+
+def test_issue_15539():
+    assert series(exp(x), x, -oo) == O(x**(-6), (x, -oo))