Repository: sympy/sympy

Issue:
Recursion errors with exponential integral Ei composed with other functions
    >>> from sympy import *
    >>> Ei(cos(2))
    ...
    RecursionError: maximum recursion depth exceeded while calling a Python object
    >>> Ei(Li(S(1)/7))
    ...
    RecursionError: maximum recursion depth exceeded while calling a Python object

`Ei(cos(x))` is dependent on the specific value of `x`: 2, 3, 4, and 8 produce the recursion error for example, and 1, 5, 6 and 7 do not.

Discussion:

Patch:
diff --git a/sympy/functions/special/error_functions.py b/sympy/functions/special/error_functions.py
index 9312e2a0e7..455f7dab32 100644
--- a/sympy/functions/special/error_functions.py
+++ b/sympy/functions/special/error_functions.py
@@ -967,34 +967,14 @@ class Ei(Function):
     If the integral is interpreted as a Cauchy principal value, this statement
     holds for `x > 0` and `\operatorname{Ei}(x)` as defined above.
 
-    Note that we carefully avoided defining `\operatorname{Ei}(x)` for
-    negative real `x`. This is because above integral formula does not hold for
-    any polar lift of such `x`, indeed all branches of
-    `\operatorname{Ei}(x)` above the negative reals are imaginary.
-
-    However, the following statement holds for all `x \in \mathbb{R}^*`:
-
-    .. math:: \int_{-\infty}^x \frac{e^t}{t} \mathrm{d}t =
-              \frac{\operatorname{Ei}\left(|x|e^{i \arg(x)}\right) +
-                    \operatorname{Ei}\left(|x|e^{- i \arg(x)}\right)}{2},
-
-    where the integral is again understood to be a principal value if
-    `x > 0`, and `|x|e^{i \arg(x)}`,
-    `|x|e^{- i \arg(x)}` denote two conjugate polar lifts of `x`.
-
     Examples
     ========
 
     >>> from sympy import Ei, polar_lift, exp_polar, I, pi
     >>> from sympy.abc import x
 
-    The exponential integral in SymPy is strictly undefined for negative values
-    of the argument. For convenience, exponential integrals with negative
-    arguments are immediately converted into an expression that agrees with
-    the classical integral definition:
-
     >>> Ei(-1)
-    -I*pi + Ei(exp_polar(I*pi))
+    Ei(-1)
 
     This yields a real value:
 
@@ -1057,9 +1037,6 @@ def eval(cls, z):
         elif z is S.NegativeInfinity:
             return S.Zero
 
-        if not z.is_polar and z.is_negative:
-            # Note: is this a good idea?
-            return Ei(polar_lift(z)) - pi*I
         nz, n = z.extract_branch_factor()
         if n:
             return Ei(nz) + 2*I*pi*n


Test patch:
diff --git a/sympy/functions/special/tests/test_error_functions.py b/sympy/functions/special/tests/test_error_functions.py
index 1b028d8190..2f6d008c37 100644
--- a/sympy/functions/special/tests/test_error_functions.py
+++ b/sympy/functions/special/tests/test_error_functions.py
@@ -312,10 +312,6 @@ def fn(x):
 
 
 def test_ei():
-    pos = Symbol('p', positive=True)
-    neg = Symbol('n', negative=True)
-    assert Ei(-pos) == Ei(polar_lift(-1)*pos) - I*pi
-    assert Ei(neg) == Ei(polar_lift(neg)) - I*pi
     assert tn_branch(Ei)
     assert mytd(Ei(x), exp(x)/x, x)
     assert mytn(Ei(x), Ei(x).rewrite(uppergamma),
@@ -338,6 +334,7 @@ def test_ei():
     assert Ei(x).series(x) == EulerGamma + log(x) + x + x**2/4 + \
         x**3/18 + x**4/96 + x**5/600 + O(x**6)
 
+    assert str(Ei(cos(2)).evalf(n=10)) == '-0.6760647401'
 
 def test_expint():
     assert mytn(expint(x, y), expint(x, y).rewrite(uppergamma),