Repository: sympy/sympy

Issue:
Series expansion not working
Hello,

In our project we use very large functions and a lot of series expansions throw a "not implemented error". I managed to extract a relatively simple case:

`(1/sqrt(( - y + 1)**2 + (y - 0.23)**4)).series(y,x0=0,n=5)`

When using `apart()` the series expansion works: 

`apart((1/sqrt(( - y + 1)**2 + (y - 0.23)**4))).series(y,x0=0,n=5)`

sadly its not that easy with our larger functions. Any ideas or am I missing something fundamental? 

The error is: 

`Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/user/.local/lib/python3.10/site-packages/sympy/core/expr.py", line 3026, in series
    rv = self.subs(x, xpos).series(xpos, x0, n, dir, logx=logx, cdir=cdir)
  File "/home/user/.local/lib/python3.10/site-packages/sympy/core/expr.py", line 3034, in series
    s1 = self._eval_nseries(x, n=n, logx=logx, cdir=cdir)
  File "/home/user/.local/lib/python3.10/site-packages/sympy/core/power.py", line 1758, in _eval_nseries
    raise NotImplementedError()
NotImplementedError`

Discussion:
sympy-bot: :white_check_mark:

Hi, I am the [SymPy bot](https://github.com/sympy/sympy-bot). I'm here to help you write a release notes entry. Please read the [guide on how to write release notes](https://github.com/sympy/sympy/wiki/Writing-Release-Notes).



Your release notes are in good order.

Here is what the release notes will look like:
* functions
  * Fixed a bug in _eval_nseries method of Pow class to better handle the operation of negating the constant term from the expression. ([#26036](https://github.com/sympy/sympy/pull/26036) by [@arnabnandikgp](https://github.com/arnabnandikgp))

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.13.

<details><summary>Click here to see the pull request description that was parsed.</summary>

    <!-- Your title above should be a short description of what
    was changed. Do not include the issue number in the title. -->

    #### References to other Issues or PRs
    <!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
    format, e.g. "Fixes #1234" (see
    https://tinyurl.com/auto-closing for more information). Also, please
    write a comment on that issue linking back to this pull request once it is
    open. -->
    Fixes #25165 

    #### Brief description of what is fixed or changed
    Added fixes for better execution of thee operation to remove the constant term from an expression in _eval_nseries method in Pow class


    #### Other comments
    Changed some old tests, as the new implementation gives more simplified forms of the expected results.

    #### Release Notes

    <!-- Write the release notes for this release below between the BEGIN and END
    statements. The basic format is a bulleted list with the name of the subpackage
    and the release note for this PR. For example:

    * solvers
      * Added a new solver for logarithmic equations.

    * functions
      * Fixed a bug with log of integers. Formerly, `log(-x)` incorrectly gave `-log(x)`.

    * physics.units
      * Corrected a semantical error in the conversion between volt and statvolt which
        reported the volt as being larger than the statvolt.

    or if no release note(s) should be included use:

    NO ENTRY

    See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
    information on how to write release notes. The bot will check your release
    notes automatically to see if they are formatted correctly. -->

    <!-- BEGIN RELEASE NOTES -->
    * functions
      * Fixed a bug in _eval_nseries method of Pow class to better handle the operation of negating the constant term from the expression.
    <!-- END RELEASE NOTES -->


</details><p>

arnabnandikgp: ping @anutosh491 for review.
anutosh491: Thanks a lot for this pr. We've faced problems with using nsimplify in nseries methods in the past and this PR would help us with that. I shall review this soon !
anutosh491: Could you try fixing the failing test from test 1 ?
arnabnandikgp: > Could you try fixing the failing test from test 1 ?

That test is what I added and is the real issue we are solving, the problem that I am facing is that since the output consists of floats, it seems that we are not able to assert equality of both sides, similar to the behaviour of how we have to use `Rational(1,2)` instead of `1/2` in outputs of tests. but I do not know how to proceed here as the results here can't be be represented as ratios of simple integers.
oscarbenjamin: There is a recently added function `all_close` that can be used for testing equality of expressions with floats:
```python
In [1]: from sympy.core.numbers import all_close

In [2]: e1 = (1/sqrt(( - x + 1)**2 + (x - 0.23)**4)).series(x, 0, 2)

In [3]: e2 = 0.998603724830355 + 1.02004923189934*x + O(x**2)

In [4]: e1 == e2
Out[4]: False

In [5]: all_close(e1, e2)
Out[5]: True

In [6]: ?all_close
Signature: all_close(expr1, expr2, rtol=1e-05, atol=1e-08)
Docstring:
Return True if expr1 and expr2 are numerically close.

The expressions must have the same structure, but any Rational, Integer, or
Float numbers they contain are compared approximately using rtol and atol.
Any other parts of expressions are compared exactly.

Relative tolerance is measured with respect to expr2 so when used in
testing expr2 should be the expected correct answer.

Examples
========

>>> from sympy import exp
>>> from sympy.abc import x, y
>>> from sympy.core.numbers import all_close
>>> expr1 = 0.1*exp(x - y)
>>> expr2 = exp(x - y)/10
>>> expr1
0.1*exp(x - y)
>>> expr2
exp(x - y)/10
>>> expr1 == expr2
False
>>> all_close(expr1, expr2)
True
File:      ~/current/active/sympy/sympy/core/numbers.py
Type:      function
```
The function does not exist in the PR branch but does in master.
github-actions[bot]: Benchmark results from GitHub Actions

Lower numbers are good, higher numbers are bad. A ratio less than 1
means a speed up and greater than 1 means a slowdown. Green lines
beginning with `+` are slowdowns (the PR is slower then master or
master is slower than the previous release). Red lines beginning
with `-` are speedups.

Significantly changed benchmark results (PR vs master)
```diff

```
Significantly changed benchmark results (master vs previous release)
```diff
| Change   | Before [a00718ba]    | After [02eeb233]    |   Ratio | Benchmark (Parameter)                                                |
|----------|----------------------|---------------------|---------|----------------------------------------------------------------------|
| -        | 70.2±0.6ms           | 44.8±0.2ms          |    0.64 | integrate.TimeIntegrationRisch02.time_doit(10)                       |
| -        | 69.2±0.8ms           | 43.5±0.4ms          |    0.63 | integrate.TimeIntegrationRisch02.time_doit_risch(10)                 |
| +        | 18.2±0.3μs           | 30.3±0.4μs          |    1.66 | integrate.TimeIntegrationRisch03.time_doit(1)                        |
| -        | 5.44±0.06ms          | 2.85±0.02ms         |    0.52 | logic.LogicSuite.time_load_file                                      |
| -        | 71.0±0.9ms           | 28.7±0.3ms          |    0.4  | polys.TimeGCD_GaussInt.time_op(1, 'dense')                           |
| -        | 25.8±0.1ms           | 17.0±0.06ms         |    0.66 | polys.TimeGCD_GaussInt.time_op(1, 'expr')                            |
| -        | 73.6±0.3ms           | 29.0±0.1ms          |    0.39 | polys.TimeGCD_GaussInt.time_op(1, 'sparse')                          |
| -        | 256±1ms              | 125±0.5ms           |    0.49 | polys.TimeGCD_GaussInt.time_op(2, 'dense')                           |
| -        | 254±4ms              | 125±0.4ms           |    0.49 | polys.TimeGCD_GaussInt.time_op(2, 'sparse')                          |
| -        | 653±5ms              | 373±0.9ms           |    0.57 | polys.TimeGCD_GaussInt.time_op(3, 'dense')                           |
| -        | 664±2ms              | 373±2ms             |    0.56 | polys.TimeGCD_GaussInt.time_op(3, 'sparse')                          |
| -        | 493±1μs              | 286±2μs             |    0.58 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(1, 'dense')            |
| -        | 1.77±0ms             | 1.06±0ms            |    0.6  | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(2, 'dense')            |
| -        | 5.83±0.01ms          | 3.07±0.01ms         |    0.53 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(3, 'dense')            |
| -        | 452±2μs              | 232±2μs             |    0.51 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(1, 'dense')               |
| -        | 1.48±0.02ms          | 678±8μs             |    0.46 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(2, 'dense')               |
| -        | 4.90±0.02ms          | 1.66±0ms            |    0.34 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(3, 'dense')               |
| -        | 378±3μs              | 206±2μs             |    0.55 | polys.TimeGCD_SparseGCDHighDegree.time_op(1, 'dense')                |
| -        | 2.45±0.01ms          | 1.24±0.01ms         |    0.51 | polys.TimeGCD_SparseGCDHighDegree.time_op(3, 'dense')                |
| -        | 10.1±0.01ms          | 4.42±0.02ms         |    0.44 | polys.TimeGCD_SparseGCDHighDegree.time_op(5, 'dense')                |
| -        | 362±3μs              | 169±1μs             |    0.47 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(1, 'dense')            |
| -        | 2.51±0.01ms          | 878±5μs             |    0.35 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(3, 'dense')            |
| -        | 9.58±0.1ms           | 2.64±0.02ms         |    0.28 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(5, 'dense')            |
| -        | 1.02±0.01ms          | 438±2μs             |    0.43 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(3, 'dense')           |
| -        | 1.69±0.01ms          | 501±3μs             |    0.3  | polys.TimePREM_LinearDenseQuadraticGCD.time_op(3, 'sparse')          |
| -        | 5.84±0.08ms          | 1.80±0.02ms         |    0.31 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(5, 'dense')           |
| -        | 8.43±0.07ms          | 1.49±0ms            |    0.18 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(5, 'sparse')          |
| -        | 284±1μs              | 63.6±0.4μs          |    0.22 | polys.TimePREM_QuadraticNonMonicGCD.time_op(1, 'sparse')             |
| -        | 3.44±0.02ms          | 391±4μs             |    0.11 | polys.TimePREM_QuadraticNonMonicGCD.time_op(3, 'dense')              |
| -        | 4.03±0.02ms          | 277±0.9μs           |    0.07 | polys.TimePREM_QuadraticNonMonicGCD.time_op(3, 'sparse')             |
| -        | 7.06±0.02ms          | 1.25±0.01ms         |    0.18 | polys.TimePREM_QuadraticNonMonicGCD.time_op(5, 'dense')              |
| -        | 8.71±0.01ms          | 828±2μs             |    0.1  | polys.TimePREM_QuadraticNonMonicGCD.time_op(5, 'sparse')             |
| -        | 4.99±0.02ms          | 2.98±0.02ms         |    0.6  | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(2, 'sparse') |
| -        | 12.0±0.05ms          | 6.57±0.03ms         |    0.55 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(3, 'dense')  |
| -        | 22.1±0.3ms           | 9.04±0.03ms         |    0.41 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(3, 'sparse') |
| -        | 5.22±0.01ms          | 860±0.6μs           |    0.16 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(1, 'sparse')    |
| -        | 12.6±0.03ms          | 7.02±0.04ms         |    0.56 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(2, 'sparse')    |
| -        | 102±0.9ms            | 25.9±0.1ms          |    0.25 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(3, 'dense')     |
| -        | 165±0.8ms            | 53.4±0.08ms         |    0.32 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(3, 'sparse')    |
| -        | 169±0.6μs            | 112±0.2μs           |    0.67 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(1, 'dense')      |
| -        | 365±3μs              | 214±2μs             |    0.59 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(1, 'sparse')     |
| -        | 4.28±0.04ms          | 834±3μs             |    0.2  | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(3, 'dense')      |
| -        | 5.27±0.01ms          | 378±4μs             |    0.07 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(3, 'sparse')     |
| -        | 20.1±0.1ms           | 2.82±0.01ms         |    0.14 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(5, 'dense')      |
| -        | 22.8±0.1ms           | 616±0.7μs           |    0.03 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(5, 'sparse')     |
| -        | 479±1μs              | 136±1μs             |    0.28 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(1, 'sparse') |
| -        | 4.68±0.01ms          | 614±0.9μs           |    0.13 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(3, 'dense')  |
| -        | 5.21±0.1ms           | 138±0.9μs           |    0.03 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(3, 'sparse') |
| -        | 13.2±0.2ms           | 1.28±0ms            |    0.1  | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(5, 'dense')  |
| -        | 13.8±0.4ms           | 139±0.5μs           |    0.01 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(5, 'sparse') |
| -        | 132±0.7μs            | 73.1±0.9μs          |    0.55 | solve.TimeMatrixOperations.time_rref(3, 0)                           |
| -        | 248±0.4μs            | 88.0±0.4μs          |    0.35 | solve.TimeMatrixOperations.time_rref(4, 0)                           |
| -        | 24.4±0.04ms          | 10.2±0.03ms         |    0.42 | solve.TimeSolveLinSys189x49.time_solve_lin_sys                       |

```
Full benchmark results can be found as artifacts in GitHub Actions
(click on checks at the top of the PR).
arnabnandikgp: ping @anutosh491 , @smichr for further comments/suggestions.
arnabnandikgp: I would be great if anyone could please review this PR and provide further comments that may take this forward.
anutosh491: Still not sure if that's the best condition that we can use for addressing this case.

Patch:
diff --git a/sympy/core/expr.py b/sympy/core/expr.py
index f502625c7e..a29b829801 100644
--- a/sympy/core/expr.py
+++ b/sympy/core/expr.py
@@ -3241,8 +3241,7 @@ def aseries(self, x=None, n=6, bound=0, hir=False):
             logw = log(1/res)
 
         s = func.series(k, 0, n)
-        from sympy.core.function import expand_mul
-        s = expand_mul(s)
+
         # Hierarchical series
         if hir:
             return s.subs(k, exp(logw))
diff --git a/sympy/core/power.py b/sympy/core/power.py
index a8dc47bdfe..e6e9e310db 100644
--- a/sympy/core/power.py
+++ b/sympy/core/power.py
@@ -1533,7 +1533,8 @@ def _eval_nseries(self, x, n, logx, cdir=0):
                 return res
 
         f = b.as_leading_term(x, logx=logx)
-        g = (b/f - S.One).cancel(expand=False)
+        g = (_mexpand(b) - f).cancel()
+        g = g/f
         if not m.is_number:
             raise NotImplementedError()
         maxpow = n - m*e
@@ -1583,8 +1584,8 @@ def mul(d1, d2):
             # Convert floats like 0.5 to exact SymPy numbers like S.Half, to
             # prevent rounding errors which can induce wrong values of d leading
             # to a NotImplementedError being returned from the block below.
-            from sympy.simplify.simplify import nsimplify
-            _, d = nsimplify(g).leadterm(x, logx=logx)
+            g = g.replace(lambda x: x.is_Float, lambda x: Rational(x))
+            _, d = g.leadterm(x, logx=logx)
         if not d.is_positive:
             g = g.simplify()
             if g.is_zero:
diff --git a/sympy/functions/elementary/complexes.py b/sympy/functions/elementary/complexes.py
index d5f5bebe23..c615a3613d 100644
--- a/sympy/functions/elementary/complexes.py
+++ b/sympy/functions/elementary/complexes.py
@@ -4,7 +4,7 @@
 from sympy.core.expr import Expr
 from sympy.core.exprtools import factor_terms
 from sympy.core.function import (Function, Derivative, ArgumentIndexError,
-    AppliedUndef, expand_mul, PoleError)
+    AppliedUndef, expand_mul)
 from sympy.core.logic import fuzzy_not, fuzzy_or
 from sympy.core.numbers import pi, I, oo
 from sympy.core.power import Pow
@@ -797,25 +797,6 @@ def _eval_rewrite_as_atan2(self, arg, **kwargs):
         x, y = self.args[0].as_real_imag()
         return atan2(y, x)
 
-    def _eval_as_leading_term(self, x, logx=None, cdir=0):
-        arg0 = self.args[0]
-        t = Dummy('t', positive=True)
-        if cdir == 0:
-            cdir = 1
-        z = arg0.subs(x, cdir*t)
-        if z.is_positive:
-            return S.Zero
-        elif z.is_negative:
-            return S.Pi
-        else:
-            raise PoleError("Cannot expand %s around 0" % (self))
-
-    def _eval_nseries(self, x, n, logx, cdir=0):
-        from sympy.series.order import Order
-        if n <= 0:
-            return Order(1)
-        return self._eval_as_leading_term(x, logx=logx, cdir=cdir)
-
 
 class conjugate(Function):
     """
diff --git a/sympy/series/gruntz.py b/sympy/series/gruntz.py
index 0bf3bf3e50..407df70fdc 100644
--- a/sympy/series/gruntz.py
+++ b/sympy/series/gruntz.py
@@ -118,7 +118,7 @@
 """
 from functools import reduce
 
-from sympy.core import Basic, S, Mul, PoleError
+from sympy.core import Basic, S, Mul, PoleError, expand_mul
 from sympy.core.cache import cacheit
 from sympy.core.intfunc import ilcm
 from sympy.core.numbers import I, oo
@@ -550,11 +550,6 @@ def mrv_leadterm(e, x):
     #
     w = Dummy("w", positive=True)
     f, logw = rewrite(exps, Omega, x, w)
-
-    # Ensure expressions of the form exp(log(...)) don't get simplified automatically in the previous steps.
-    # see: https://github.com/sympy/sympy/issues/15323#issuecomment-478639399
-    f = f.replace(lambda f: f.is_Pow and f.has(x), lambda f: exp(log(f.base)*f.exp))
-
     try:
         lt = f.leadterm(w, logx=logw)
     except (NotImplementedError, PoleError, ValueError):
@@ -662,7 +657,7 @@ def rewrite(e, Omega, x, wsym):
             if not isinstance(rewrites[var], exp):
                 raise ValueError("Value should be exp")
             arg = rewrites[var].args[0]
-        O2.append((var, exp((arg - c*g.exp))*wsym**c))
+        O2.append((var, exp((arg - c*g.exp).expand())*wsym**c))
 
     # Remember that Omega contains subexpressions of "e". So now we find
     # them in "e" and substitute them for our rewriting, stored in O2
@@ -693,6 +688,7 @@ def rewrite(e, Omega, x, wsym):
     # -exp(p/(p + 1)) + exp(-p**2/(p + 1) + p). No current simplification
     # methods reduce this to 0 while not expanding polynomials.
     f = bottom_up(f, lambda w: getattr(w, 'normal', lambda: w)())
+    f = expand_mul(f)
 
     return f, logw
 


Test patch:
diff --git a/sympy/core/tests/test_expr.py b/sympy/core/tests/test_expr.py
index af83b22ab3..a95144d99c 100644
--- a/sympy/core/tests/test_expr.py
+++ b/sympy/core/tests/test_expr.py
@@ -479,14 +479,13 @@ def test_as_leading_term():
     # https://github.com/sympy/sympy/issues/21177
     e = -3*x + (x + Rational(3, 2) - sqrt(3)*S.ImaginaryUnit/2)**2\
         - Rational(3, 2) + 3*sqrt(3)*S.ImaginaryUnit/2
-    assert e.as_leading_term(x) == \
-        (12*sqrt(3)*x - 12*S.ImaginaryUnit*x)/(4*sqrt(3) + 12*S.ImaginaryUnit)
+    assert e.as_leading_term(x) == -sqrt(3)*I*x
 
     # https://github.com/sympy/sympy/issues/21245
     e = 1 - x - x**2
     d = (1 + sqrt(5))/2
     assert e.subs(x, y + 1/d).as_leading_term(y) == \
-        (-576*sqrt(5)*y - 1280*y)/(256*sqrt(5) + 576)
+        (-40*y - 16*sqrt(5)*y)/(16 + 8*sqrt(5))
 
 
 def test_leadterm2():
diff --git a/sympy/core/tests/test_power.py b/sympy/core/tests/test_power.py
index 640834ead0..f1080e338d 100644
--- a/sympy/core/tests/test_power.py
+++ b/sympy/core/tests/test_power.py
@@ -18,6 +18,7 @@
 from sympy.testing.pytest import warns, _both_exp_pow
 from sympy.utilities.exceptions import SymPyDeprecationWarning
 from sympy.abc import a, b, c, x, y
+from sympy.core.numbers import all_close
 
 def test_rational():
     a = Rational(1, 5)
@@ -661,3 +662,9 @@ def test_issue_26546():
     assert Pow(x+I, Rational(1,2)).is_extended_real is False
     assert Pow(x+I, Rational(1,13)).is_extended_real is False
     assert Pow(x+I, Rational(2,3)).is_extended_real is None
+
+
+def test_issue_25165():
+    e1 = (1/sqrt(( - x + 1)**2 + (x - 0.23)**4)).series(x, 0, 2)
+    e2 = 0.998603724830355 + 1.02004923189934*x + O(x**2)
+    assert all_close(e1, e2)
diff --git a/sympy/functions/elementary/tests/test_complexes.py b/sympy/functions/elementary/tests/test_complexes.py
index be2a45cd9b..9fd2a0edaa 100644
--- a/sympy/functions/elementary/tests/test_complexes.py
+++ b/sympy/functions/elementary/tests/test_complexes.py
@@ -1,5 +1,5 @@
 from sympy.core.expr import Expr
-from sympy.core.function import (Derivative, Function, Lambda, expand, PoleError)
+from sympy.core.function import (Derivative, Function, Lambda, expand)
 from sympy.core.numbers import (E, I, Rational, comp, nan, oo, pi, zoo)
 from sympy.core.relational import Eq
 from sympy.core.singleton import S
@@ -20,7 +20,6 @@
 from sympy.sets.sets import Interval
 from sympy.core.expr import unchanged
 from sympy.core.function import ArgumentIndexError
-from sympy.series.order import Order
 from sympy.testing.pytest import XFAIL, raises, _both_exp_pow
 
 
@@ -672,17 +671,6 @@ def test_arg_rewrite():
     assert arg(x + I*y).rewrite(atan2) == atan2(y, x)
 
 
-def test_arg_leading_term_and_series():
-    x = Symbol('x')
-    assert arg(x).as_leading_term(x, cdir = 1) == 0
-    assert arg(x).as_leading_term(x, cdir = -1) == pi
-    raises(PoleError, lambda: arg(x + I).as_leading_term(x, cdir = 1))
-    raises(PoleError, lambda: arg(2*x).as_leading_term(x, cdir = I))
-
-    assert arg(x).nseries(x) == 0
-    assert arg(x).nseries(x, n=0) == Order(1)
-
-
 def test_adjoint():
     a = Symbol('a', antihermitian=True)
     b = Symbol('b', hermitian=True)
diff --git a/sympy/series/tests/test_aseries.py b/sympy/series/tests/test_aseries.py
index cae0ac0a43..055d6b8aef 100644
--- a/sympy/series/tests/test_aseries.py
+++ b/sympy/series/tests/test_aseries.py
@@ -1,5 +1,6 @@
 from sympy.core.function import PoleError
 from sympy.core.numbers import oo
+from sympy.core.singleton import S
 from sympy.core.symbol import Symbol
 from sympy.functions.elementary.exponential import (exp, log)
 from sympy.functions.elementary.miscellaneous import sqrt
@@ -31,9 +32,9 @@ def test_simple():
 
     e3 = lambda x:exp(exp(exp(x)))
     e = e3(x)/e3(x - 1/e3(x))
-    assert e.aseries(x, n=3) == 1 + exp(2*x + 2*exp(x))*exp(-2*exp(exp(x)))/2\
-            - exp(2*x + exp(x))*exp(-2*exp(exp(x)))/2 - exp(x + exp(x))*exp(-2*exp(exp(x)))/2\
-            + exp(x + exp(x))*exp(-exp(exp(x))) + O(exp(-3*exp(exp(x))), (x, oo))
+    assert e.aseries(x, n=3) == 1 + exp(x + exp(x))*exp(-exp(exp(x)))\
+            + ((-exp(x)/2 - S.Half)*exp(x + exp(x))\
+            + exp(2*x + 2*exp(x))/2)*exp(-2*exp(exp(x))) + O(exp(-3*exp(exp(x))), (x, oo))
 
     e = exp(exp(x)) * (exp(sin(1/x + 1/exp(exp(x)))) - exp(sin(1/x)))
     assert e.aseries(x, n=4) == -1/(2*x**3) + 1/x + 1 + O(x**(-4), (x, oo))
diff --git a/sympy/series/tests/test_gruntz.py b/sympy/series/tests/test_gruntz.py
index c11d243c7c..4565c87608 100644
--- a/sympy/series/tests/test_gruntz.py
+++ b/sympy/series/tests/test_gruntz.py
@@ -5,6 +5,7 @@
 from sympy.functions.elementary.exponential import (exp, log)
 from sympy.functions.elementary.miscellaneous import sqrt
 from sympy.functions.elementary.trigonometric import (acot, atan, cos, sin)
+from sympy.functions.elementary.complexes import sign as _sign
 from sympy.functions.special.error_functions import (Ei, erf)
 from sympy.functions.special.gamma_functions import (digamma, gamma, loggamma)
 from sympy.functions.special.zeta_functions import zeta
@@ -313,7 +314,7 @@ def test_rewrite1():
     e = exp(x + 1/x)
     assert mrewrite(mrv(e, x), x, m) == (1/m, -x - 1/x)
     e = 1/exp(-x + exp(-x)) - exp(x)
-    assert mrewrite(mrv(e, x), x, m) == ((-m*exp(m) + m)*exp(-m)/m**2, -x)
+    assert mrewrite(mrv(e, x), x, m) == (1/(m*exp(m)) - 1/m, -x)
 
 
 def test_rewrite2():
@@ -328,7 +329,7 @@ def test_rewrite3():
     e = exp(-x + 1/x**2) - exp(x + 1/x)
     #both of these are correct and should be equivalent:
     assert mrewrite(mrv(e, x), x, m) in [(-1/m + m*exp(
-        (x**2 + x)/x**3), -x - 1/x), ((m**2 - exp((x**2 + x)/x**3))/m, x**(-2) - x)]
+        1/x + 1/x**2), -x - 1/x), (m - 1/m*exp(1/x + x**(-2)), x**(-2) - x)]
 
 
 def test_mrv_leadterm1():
@@ -403,7 +404,7 @@ def test_gruntz_I():
     assert gruntz(I*x, x, oo) == I*oo
     assert gruntz(y*I*x, x, oo) == y*I*oo
     assert gruntz(y*3*I*x, x, oo) == y*I*oo
-    assert gruntz(y*3*sin(I)*x, x, oo) == y*I*oo
+    assert gruntz(y*3*sin(I)*x, x, oo).simplify().rewrite(_sign) == _sign(y)*I*oo
 
 
 def test_issue_4814():
diff --git a/sympy/series/tests/test_limits.py b/sympy/series/tests/test_limits.py
index 4f2760f8e8..ac28ad3eaf 100644
--- a/sympy/series/tests/test_limits.py
+++ b/sympy/series/tests/test_limits.py
@@ -1417,10 +1417,3 @@ def test_issue_26250():
 def test_issue_26916():
     assert limit(Ei(x)*exp(-x), x, +oo) == 0
     assert limit(Ei(x)*exp(-x), x, -oo) == 0
-
-
-def test_issue_22982_15323():
-    assert limit((log(E + 1/x) - 1)**(1 - sqrt(E + 1/x)), x, oo) == oo
-    assert limit((1 - 1/x)**x*(log(1 - 1/x) + 1/(x*(1 - 1/x))), x, 1, dir='+') == 1
-    assert limit((log(E + 1/x) )**(1 - sqrt(E + 1/x)), x, oo) == 1
-    assert limit((log(E + 1/x) - 1)**(- sqrt(E + 1/x)), x, oo) == oo
diff --git a/sympy/series/tests/test_series.py b/sympy/series/tests/test_series.py
index 6ae7ed2b84..3313b8e6ee 100644
--- a/sympy/series/tests/test_series.py
+++ b/sympy/series/tests/test_series.py
@@ -367,9 +367,9 @@ def test_issue_20697():
 def test_issue_21245():
     fi = (1 + sqrt(5))/2
     assert (1/(1 - x - x**2)).series(x, 1/fi, 1).factor() == \
-        (-4812 - 2152*sqrt(5) + 1686*x + 754*sqrt(5)*x\
-        + O((x - 2/(1 + sqrt(5)))**2, (x, 2/(1 + sqrt(5)))))/((1 + sqrt(5))\
-        *(20 + 9*sqrt(5))**2*(x + sqrt(5)*x - 2))
+        (-37*sqrt(5) - 83 + 13*sqrt(5)*x + 29*x + O((x - 2/(1 + sqrt(5)))**2, (x\
+            , 2/(1 + sqrt(5)))))/((2*sqrt(5) + 5)**2*(x + sqrt(5)*x - 2))
+
 
 
 def test_issue_21938():