Repository: mpmath/mpmath (python)

Issue:
log1p(x) with real x returns a complex value when x is sufficiently small.
When the real input `x` is small enough, `log1p(x)` returns a complex number, with imaginary part 0:

```
In [1]: import mpmath

In [2]: mpmath.__version__
Out[2]: '1.4.0a2.dev93+g9b99f41'

In [3]: from mpmath import mp

In [4]: mp.dps = 25

In [5]: mp.log1p(6e-30)  # unexpected complex result
Out[5]: mpc(real='5.999999999999999799369291483e-30', imag='0.0')

In [6]: mp.log1p(7e-30)  # slightly bigger input gives a real result.
Out[6]: mpf('7.000000000000000583354944253e-30')

```

Pull request:
Use correct constructor in series branch of log1p
This amends 7596816

Closes #853

Patch:
diff --git a/mpmath/functions/functions.py b/mpmath/functions/functions.py
index 593ac30..1cf05ef 100644
--- a/mpmath/functions/functions.py
+++ b/mpmath/functions/functions.py
@@ -238,7 +238,7 @@ def log1p(ctx, x):
             b2 = ctx.fmul(b, b, prec=2*wp)
             diff = ctx.fsub(b2, a2, prec=3*wp)
             real = a + ctx.ldexp(diff, -1)
-        result = ctx.mpc(real, b)
+        result = real if ctx._is_real_type(x) else ctx.mpc(real, b)
     return result
 
 @defun_wrapped


Test patch:
diff --git a/mpmath/tests/test_functions.py b/mpmath/tests/test_functions.py
index 01914f7..9be9101 100644
--- a/mpmath/tests/test_functions.py
+++ b/mpmath/tests/test_functions.py
@@ -974,6 +974,16 @@ def test_log1p():
     assert log1p(-1.430796815051627e-72+1.691624553529315e-36j).ae(4.6709293580298264e-91+1.691624553529315e-36j, 0)
     assert log1p(-3.1061140011623543e-21+7.881768838480807e-11j).ae(4.3173401185459216e-38+7.881768838480807e-11j, 0)
     assert log1p(-1.999999873062092e-40+1.999999936531045e-20j).ae(1.9999997461241924e-80+1.999999936531045e-20j)
+    # issue 853
+    mp.dps = 25
+    r = log1p(6e-30)
+    assert type(r) is type(r.real)
+    r = mp.log1p(7e-30)
+    assert type(r) is type(r.real)
+    r = mp.log1p(0.1 + 0j)
+    assert type(r) is not type(r.real)
+    r = mp.log1p(1e-30 + 0j)
+    assert type(r) is not type(r.real)
 
 def test_powm1():
     assert powm1(2,3) == 7