# [pypy-svn] pypy cmath: (lac, arigo)

Mon Jan 17 16:55:54 CET 2011

```Author: Armin Rigo <arigo at tunes.org>
Branch: cmath
Changeset: r40778:4c065bc6df99
Date: 2011-01-17 16:55 +0100
http://bitbucket.org/pypy/pypy/changeset/4c065bc6df99/

Log:	(lac, arigo)

asin(), asinh().

diff --git a/pypy/module/cmath/__init__.py b/pypy/module/cmath/__init__.py
--- a/pypy/module/cmath/__init__.py
+++ b/pypy/module/cmath/__init__.py
@@ -5,7 +5,9 @@
names_and_docstrings = {
'sqrt': "Return the square root of x.",
'acos': "Return the arc cosine of x.",
-    'acosh': "Return the hyperbolic arccosine of x.",
+    'acosh': "Return the hyperbolic arc cosine of x.",
+    'asin': "Return the arc sine of x.",
+    'asinh': "Return the hyperbolic arc sine of x.",
}

diff --git a/pypy/module/cmath/test/test_cmath.py b/pypy/module/cmath/test/test_cmath.py
--- a/pypy/module/cmath/test/test_cmath.py
+++ b/pypy/module/cmath/test/test_cmath.py
@@ -159,8 +159,8 @@
actual = function(*arg)

if 'ignore-real-sign' in flags:
-            actual = complex(abs(actual.real), actual.imag)
-            expected = complex(abs(expected.real), expected.imag)
+            actual = (abs(actual[0]), actual[1])
+            expected = (abs(expected[0]), expected[1])
if 'ignore-imag-sign' in flags:
actual = (actual[0], abs(actual[1]))
expected = (expected[0], abs(expected[1]))

diff --git a/pypy/module/cmath/interp_cmath.py b/pypy/module/cmath/interp_cmath.py
--- a/pypy/module/cmath/interp_cmath.py
+++ b/pypy/module/cmath/interp_cmath.py
@@ -9,6 +9,7 @@
from pypy.module.cmath.special_value import sqrt_special_values
from pypy.module.cmath.special_value import acos_special_values
from pypy.module.cmath.special_value import acosh_special_values
+from pypy.module.cmath.special_value import asinh_special_values

def unaryfn(c_func):
@@ -120,3 +121,30 @@
real = asinh(s1x*s2x + s1y*s2y)
imag = 2.*math.atan2(s1y, s2x)
return (real, imag)
+
+
+ at unaryfn
+def c_asin(x, y):
+    sx, sy = c_asinh(-y, x)
+    return (sy, -sx)
+
+
+ at unaryfn
+def c_asinh(x, y):
+    if not isfinite(x) or not isfinite(y):
+        return asinh_special_values[special_type(x)][special_type(y)]
+
+    if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE:
+        if y >= 0.:
+            real = copysign(math.log(math.hypot(x/2., y/2.)) +
+                            M_LN2*2., x)
+        else:
+            real = -copysign(math.log(math.hypot(x/2., y/2.)) +
+                             M_LN2*2., -x)
+        imag = math.atan2(y, fabs(x))
+    else:
+        s1x, s1y = c_sqrt(1.+y, -x)
+        s2x, s2y = c_sqrt(1.-y, x)
+        real = asinh(s1x*s2y - s2x*s1y)
+        imag = math.atan2(y, s1x*s2x - s1y*s2y)
+    return (real, imag)

diff --git a/pypy/module/cmath/special_value.py b/pypy/module/cmath/special_value.py
--- a/pypy/module/cmath/special_value.py
+++ b/pypy/module/cmath/special_value.py
@@ -76,6 +76,16 @@
(INF,N),    (N,N),     (N,N),     (N,N),    (N,N),    (INF,N),   (N,N),
])

+asinh_special_values = build_table([
+    (-INF,-P14),(-INF,-0.),(-INF,-0.),(-INF,0.),(-INF,0.),(-INF,P14),(-INF,N),
+    (-INF,-P12),(U,U),     (U,U),     (U,U),    (U,U),    (-INF,P12),(N,N),
+    (-INF,-P12),(U,U),     (-0.,-0.), (-0.,0.), (U,U),    (-INF,P12),(N,N),
+    (INF,-P12), (U,U),     (0.,-0.),  (0.,0.),  (U,U),    (INF,P12), (N,N),
+    (INF,-P12), (U,U),     (U,U),     (U,U),    (U,U),    (INF,P12), (N,N),
+    (INF,-P14), (INF,-0.), (INF,-0.), (INF,0.), (INF,0.), (INF,P14), (INF,N),
+    (INF,N),    (N,N),     (N,-0.),   (N,0.),   (N,N),    (INF,N),   (N,N),
+    ])
+
sqrt_special_values = build_table([
(INF,-INF), (0.,-INF), (0.,-INF), (0.,INF), (0.,INF), (INF,INF), (N,INF),
(INF,-INF), (U,U),     (U,U),     (U,U),    (U,U),    (INF,INF), (N,N),
```