Author: Alex Gaynor <[email protected]>
Branch: numpy-dtype-alt
Changeset: r46586:5228abf0b5b4
Date: 2011-08-17 21:16 -0500
http://bitbucket.org/pypy/pypy/changeset/5228abf0b5b4/

Log:    unbreak float stuff.

diff --git a/pypy/module/micronumpy/interp_dtype.py 
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -162,6 +162,12 @@
         if v == 0.0:
             return rfloat.copysign(rfloat.INFINITY, v)
         return 1.0 / v
+    @unaryop
+    def fabs(self, v):
+        return math.fabs(v)
+    @unaryop
+    def floor(self, v):
+        return math.floor(v)
 
     @binop
     def max(self, v1, v2):
@@ -169,7 +175,37 @@
     @binop
     def min(self, v1, v2):
         return min(v1, v2)
-
+    @binop
+    def copysign(self, v1, v2):
+        return math.copysign(v1, v2)
+    @unaryop
+    def exp(self, v):
+        try:
+            return math.exp(v)
+        except OverflowError:
+            return rfloat.INFINITY
+    @unaryop
+    def sin(self, v):
+        return math.sin(v)
+    @unaryop
+    def cos(self, v):
+        return math.cos(v)
+    @unaryop
+    def tan(self, v):
+        return math.tan(v)
+    @unaryop
+    def arcsin(self, v):
+        if v < -1.0 or  v > 1.0:
+            return rfloat.NAN
+        return math.asin(v)
+    @unaryop
+    def arccos(self, v):
+        if v < -1.0 or v > 1.0:
+            return rfloat.NAN
+        return math.acos(v)
+    @unaryop
+    def arctan(self, v):
+        return math.atan(v)
 
     def ne(self, v1, v2):
         return self.unbox(v1) != self.unbox(v2)
diff --git a/pypy/module/micronumpy/interp_ufuncs.py 
b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -6,7 +6,9 @@
 from pypy.tool.sourcetools import func_with_new_name
 
 
-def ufunc(func):
+def ufunc(func=None, promote_to_float=False):
+    if func is None:
+        return lambda func: ufunc(func, promote_to_float)
     signature = Signature()
     def impl(space, w_obj):
         from pypy.module.micronumpy.interp_numarray import Call1, 
convert_to_array, scalar
@@ -20,7 +22,9 @@
             return func(res_dtype, scalar(space, interp_dtype.W_Float64Dtype, 
w_obj)).wrap(space)
     return func_with_new_name(impl, "%s_dispatcher" % func.__name__)
 
-def ufunc2(func):
+def ufunc2(func=None, promote_to_float=False):
+    if func is None:
+        return lambda func: ufunc2(func)
     signature = Signature()
     def impl(space, w_lhs, w_rhs):
         from pypy.module.micronumpy.interp_numarray import Call2, 
convert_to_array, scalar
@@ -41,13 +45,15 @@
             ).wrap(space)
     return func_with_new_name(impl, "%s_dispatcher" % func.__name__)
 
-def find_binop_result_dtype(space, dt1, dt2, promote_bools=False):
+def find_binop_result_dtype(space, dt1, dt2, promote_bools=False, 
promote_to_float=False):
     # dt1.num should be <= dt2.num
     if dt1.num > dt2.num:
         dt1, dt2 = dt2, dt1
     # Some operations promote op(bool, bool) to return int8, rather than bool
     if promote_bools and (dt1.kind == dt2.kind == interp_dtype.BOOLLTR):
         return space.fromcache(interp_dtype.W_Int8Dtype)
+    if promote_to_float:
+        return find_unaryop_result_dtype(space, dt2, promote_to_float=True)
     # If they're the same kind, choose the greater one.
     if dt1.kind == dt2.kind:
         return dt2
@@ -66,19 +72,19 @@
     return dt
 
 
-def ufunc_dtype_caller(ufunc_name, op_name, argcount):
+def ufunc_dtype_caller(ufunc_name, op_name, argcount, **kwargs):
     if argcount == 1:
-        @ufunc
+        @ufunc(**kwargs)
         def impl(res_dtype, value):
             return getattr(res_dtype, op_name)(value)
     elif argcount == 2:
-        @ufunc2
+        @ufunc2(**kwargs)
         def impl(res_dtype, lvalue, rvalue):
             return getattr(res_dtype, op_name)(lvalue, rvalue)
     impl.__name__ = ufunc_name
     return impl
 
-for ufunc_name, op_name, argcount in [
+for ufunc_def in [
     ("add", "add", 2),
     ("subtract", "sub", 2),
     ("multiply", "mul", 2),
@@ -89,10 +95,31 @@
     ("maximum", "max", 2),
     ("minimum", "min", 2),
 
+    ("copysign", "copysign", 2, {"promote_to_float": True}),
+
     ("positive", "pos", 1),
     ("negative", "neg", 1),
     ("absolute", "abs", 1),
     ("sign", "sign", 1),
     ("reciprocal", "reciprocal", 1),
+
+    ("fabs", "fabs", 1, {"promote_to_float": True}),
+    ("floor", "floor", 1, {"promote_to_float": True}),
+    ("exp", "exp", 1, {"promote_to_float": True}),
+
+    ("sin", "sin", 1, {"promote_to_float": True}),
+    ("cos", "cos", 1, {"promote_to_float": True}),
+    ("tan", "tan", 1, {"promote_to_float": True}),
+    ("arcsin", "arcsin", 1, {"promote_to_float": True}),
+    ("arccos", "arccos", 1, {"promote_to_float": True}),
+    ("arctan", "arctan", 1, {"promote_to_float": True}),
 ]:
-    globals()[ufunc_name] = ufunc_dtype_caller(ufunc_name, op_name, argcount)
+    ufunc_name = ufunc_def[0]
+    op_name = ufunc_def[1]
+    argcount = ufunc_def[2]
+    try:
+        extra_kwargs = ufunc_def[3]
+    except IndexError:
+        extra_kwargs = {}
+
+    globals()[ufunc_name] = ufunc_dtype_caller(ufunc_name, op_name, argcount, 
**extra_kwargs)
diff --git a/pypy/module/micronumpy/test/test_base.py 
b/pypy/module/micronumpy/test/test_base.py
--- a/pypy/module/micronumpy/test/test_base.py
+++ b/pypy/module/micronumpy/test/test_base.py
@@ -49,6 +49,9 @@
         assert find_binop_result_dtype(space, bool_dtype, bool_dtype, 
promote_bools=True) is int8_dtype
         assert find_binop_result_dtype(space, bool_dtype, float64_dtype, 
promote_bools=True) is float64_dtype
 
+        # Coerce to floats
+        assert find_binop_result_dtype(space, bool_dtype, float64_dtype, 
promote_to_float=True) is float64_dtype
+
     def test_unaryops(self, space):
         bool_dtype = space.fromcache(interp_dtype.W_BoolDtype)
         int8_dtype = space.fromcache(interp_dtype.W_Int8Dtype)
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py 
b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -84,8 +84,6 @@
             assert c[i] == a[i] / b[i]
 
     def test_fabs(self):
-        skip("broke float-type ufuncs")
-
         from numpy import array, fabs
         from math import fabs as math_fabs
 
@@ -149,7 +147,6 @@
             assert c[i] == a[i] - b[i]
 
     def test_floor(self):
-        skip("broke float-type ufuncs")
         from numpy import array, floor
 
         reference = [-2.0, -1.0, 0.0, 1.0, 1.0]
@@ -159,7 +156,6 @@
             assert b[i] == reference[i]
 
     def test_copysign(self):
-        skip("broke float-type ufuncs")
         from numpy import array, copysign
 
         reference = [5.0, -0.0, 0.0, -6.0]
@@ -169,8 +165,12 @@
         for i in range(4):
             assert c[i] == reference[i]
 
+        b = array([True, True, True, True], dtype=bool)
+        c = copysign(a, b)
+        for i in range(4):
+            assert c[i] == abs(a[i])
+
     def test_exp(self):
-        skip("broke float-type ufuncs")
         import math
         from numpy import array, exp
 
@@ -185,7 +185,6 @@
             assert b[i] == res
 
     def test_sin(self):
-        skip("broke float-type ufuncs")
         import math
         from numpy import array, sin
 
@@ -195,7 +194,6 @@
             assert b[i] == math.sin(a[i])
 
     def test_cos(self):
-        skip("broke float-type ufuncs")
         import math
         from numpy import array, cos
 
@@ -205,7 +203,6 @@
             assert b[i] == math.cos(a[i])
 
     def test_tan(self):
-        skip("broke float-type ufuncs")
         import math
         from numpy import array, tan
 
@@ -216,7 +213,6 @@
 
 
     def test_arcsin(self):
-        skip("broke float-type ufuncs")
         import math
         from numpy import array, arcsin
 
@@ -231,7 +227,6 @@
             assert math.isnan(f)
 
     def test_arccos(self):
-        skip("broke float-type ufuncs")
         import math
         from numpy import array, arccos
 
@@ -247,7 +242,6 @@
             assert math.isnan(f)
 
     def test_arctan(self):
-        skip("broke float-type ufuncs")
         import math
         from numpy import array, arctan
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to