Repository: sympy/sympy
Pull request: Functions: Resolves Extraneous Variable in Limit results
Fixes: #18501
Fixes: #18997 
Fixes: #19026 

The root cause of the issue is the `_eval_nseries() function of Abs() class`. 

#### Brief description of what is fixed or changed
**Previously:**
```
In[1]: limit(Abs(log(x - 1)**3 - 1), x, 1, '+')
Out[1]: -oo*sign(log(_w)**3)
```
A bit of substitution was missing in `_eval_nseries() function of Abs() class in complexes.py` which was causing extraneous variable in Limit results.

**Now the limit evaluates correctly:**
```
In[1]: limit(Abs(log(x - 1)**3 - 1), x, 1, '+')
Out[1]: oo
```



#### Other Comments
Regression Tests have been added.


#### Release Notes


<!-- BEGIN RELEASE NOTES -->
* functions
  * Adds substitution to `_eval_nseries() function of Abs() class` resolving incorrect limit evaluations 
<!-- END RELEASE NOTES -->

Problem statement:
Extraneous variable in limit result
`limit(Abs(log(x - 1)**3 - 1),x,1,'+')` returns expression involving `w`:
```python
>>> limit(Abs(log(x - 1)**3 - 1),x,1,'+')
-oo*sign(log(_w)**3)
```

Incorrect limit result involving Abs, returns expression involving a symbol
`limit(Abs(log(x)),x,0)` returns incorrect result. Similar result with `limit(Abs(log(Abs(x))),x,0)`

Both return expression `-oo*sign(log(_w))` involving a symbol `_w`

while `limit(log(Abs(x)),x,0)` works just fine.

```
>>> limit(Abs(log(x)),x,0)
-oo*sign(log(_w))
```
```
>>> limit(Abs(log(Abs(x))),x,0)
-oo*sign(log(_w))
```
```
>>> limit(log(Abs(x)),x,0)
-oo
```



Bug in Limit
There is a bug in limit

> x=symbols('x',positive=True)
 limit(Abs(log(x)+1)/log(x),x,oo)

results in 

> -sign(log(_w))

which is not the expected result. The expected result should be 1

Hints from issue discussion:

Commit message: Made changes to fix a minor bug

Patch to review:
diff --git a/sympy/functions/elementary/complexes.py b/sympy/functions/elementary/complexes.py
index fad4b28dae82..ac5e7a658568 100644
--- a/sympy/functions/elementary/complexes.py
+++ b/sympy/functions/elementary/complexes.py
@@ -591,6 +591,8 @@ def _eval_power(self, exponent):
 
     def _eval_nseries(self, x, n, logx):
         direction = self.args[0].leadterm(x)[0]
+        if direction.has(log(x)):
+            direction = direction.subs(log(x), logx)
         s = self.args[0]._eval_nseries(x, n=n, logx=logx)
         when = Eq(direction, 0)
         return Piecewise(
diff --git a/sympy/series/limitseq.py b/sympy/series/limitseq.py
index dec3cd328eb8..07e3f31ceb1e 100644
--- a/sympy/series/limitseq.py
+++ b/sympy/series/limitseq.py
@@ -242,5 +242,5 @@ def limit_seq(expr, n=None, trials=5):
         # Maybe the absolute value is easier to deal with (though not if
         # it has a Sum). If it tends to 0, the limit is 0.
         elif not expr.has(Sum):
-            if _limit_seq(Abs(expr.xreplace({n: n_})), n_, trials).is_zero:
+            if _limit_seq(Abs(expr.xreplace({n: n_})), n_, trials) is not None and _limit_seq(Abs(expr.xreplace({n: n_})), n_, trials).is_zero:
                 return S.Zero
diff --git a/sympy/series/tests/test_limits.py b/sympy/series/tests/test_limits.py
index 8a6fbcd50890..f523f0fdeff1 100644
--- a/sympy/series/tests/test_limits.py
+++ b/sympy/series/tests/test_limits.py
@@ -2,7 +2,7 @@
 
 from sympy import (
     limit, exp, oo, log, sqrt, Limit, sin, floor, cos, ceiling,
-    atan, gamma, Symbol, S, pi, Integral, Rational, I,
+    atan, Abs, gamma, Symbol, S, pi, Integral, Rational, I,
     tan, cot, integrate, Sum, sign, Function, subfactorial, symbols,
     binomial, simplify, frac, Float, sec, zoo, fresnelc, fresnels,
     acos, erfi, LambertW, factorial, Ei, EulerGamma)
@@ -641,11 +641,26 @@ def test_issue_18442():
     assert limit(tan(x)**(2**(sqrt(pi))), x, oo, dir='-') == AccumBounds(-oo, oo)
 
 
+def test_issue_18501():
+    assert limit(Abs(log(x - 1)**3 - 1), x, 1, '+') == oo
+
+
 def test_issue_18508():
     assert limit(sin(x)/sqrt(1-cos(x)), x, 0) == sqrt(2)
     assert limit(sin(x)/sqrt(1-cos(x)), x, 0, dir='+') == sqrt(2)
     assert limit(sin(x)/sqrt(1-cos(x)), x, 0, dir='-') == -sqrt(2)
 
+
+def test_issue_18997():
+    assert limit(Abs(log(x)), x, 0) == oo
+    assert limit(Abs(log(Abs(x))), x, 0) == oo
+
+
+def test_issue_19026():
+    x = Symbol('x', positive=True)
+    assert limit(Abs(log(x) + 1)/log(x), x, oo) == 1
+
+
 def test_issue_13715():
     n = Symbol('n')
     p = Symbol('p', zero=True)


Code review comments:
diff_hunk: @@ -242,5 +242,5 @@ def limit_seq(expr, n=None, trials=5):
         # Maybe the absolute value is easier to deal with (though not if
         # it has a Sum). If it tends to 0, the limit is 0.
         elif not expr.has(Sum):
-            if _limit_seq(Abs(expr.xreplace({n: n_})), n_, trials).is_zero:
+            if _limit_seq(Abs(expr.xreplace({n: n_})), n_, trials) is not None and _limit_seq(Abs(expr.xreplace({n: n_})), n_, trials).is_zero:
path: sympy/series/limitseq.py
text: @user1:
`_limit_seq` should not be computed twice. Do something like this instead:

        lim = _limit_seq(Abs(expr.xreplace({n: n_})), n_, trials)
        if lim is not None and lim.is_zero:

@author:
Okay will make the changes.