[pypy-commit] pypy numpypy-complex: random progress

alex_gaynor noreply at buildbot.pypy.org
Sat Feb 4 01:55:22 CET 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: numpypy-complex
Changeset: r52073:e226e803f299
Date: 2012-02-03 19:54 -0500
http://bitbucket.org/pypy/pypy/changeset/e226e803f299/

Log:	random progress

diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -31,7 +31,7 @@
         'concatenate': 'interp_numarray.concatenate',
 
         'set_string_function': 'appbridge.set_string_function',
-        
+
         'count_reduce_items': 'interp_numarray.count_reduce_items',
 
         'True_': 'types.Bool.True',
@@ -57,6 +57,8 @@
         'float_': 'interp_boxes.W_Float64Box',
         'float32': 'interp_boxes.W_Float32Box',
         'float64': 'interp_boxes.W_Float64Box',
+        'complexfloating': 'interp_boxes.W_ComplexFloatingBox',
+        'complex128': 'interp_boxes.W_Complex128Box',
     }
 
     # ufuncs
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -2,6 +2,7 @@
 from pypy.interpreter.error import operationerrfmt
 from pypy.interpreter.gateway import interp2app
 from pypy.interpreter.typedef import TypeDef
+from pypy.objspace.std.complextype import complex_typedef
 from pypy.objspace.std.floattype import float_typedef
 from pypy.objspace.std.inttype import int_typedef
 from pypy.rlib.rarithmetic import LONG_BIT
@@ -29,6 +30,18 @@
     def convert_to(self, dtype):
         return dtype.box(self.value)
 
+class ComplexBox(object):
+    _mixin_ = True
+
+    def __init__(self, real, imag):
+        self.real = real
+        self.imag = imag
+
+    def convert_to(self, dtype):
+        if type(self) is dtype.itemtype.BoxType:
+            return self
+        raise NotImplementedError
+
 
 class W_GenericBox(Wrappable):
     _attrs_ = ()
@@ -158,6 +171,12 @@
     descr__new__, get_dtype = new_dtype_getter("float64")
 
 
+class W_ComplexFloatingBox(W_InexactBox):
+    pass
+
+class W_Complex128Box(W_ComplexFloatingBox, ComplexBox):
+    descr__new__, get_dtype = new_dtype_getter("complex128")
+
 
 W_GenericBox.typedef = TypeDef("generic",
     __module__ = "numpypy",
@@ -271,13 +290,19 @@
 
 W_Float32Box.typedef = TypeDef("float32", W_FloatingBox.typedef,
     __module__ = "numpypy",
-
     __new__ = interp2app(W_Float32Box.descr__new__.im_func),
 )
 
 W_Float64Box.typedef = TypeDef("float64", (W_FloatingBox.typedef, float_typedef),
     __module__ = "numpypy",
-
     __new__ = interp2app(W_Float64Box.descr__new__.im_func),
 )
 
+W_ComplexFloatingBox.typedef = TypeDef("complexfloating", W_InexactBox.typedef,
+    __module__ = "numpypy",
+)
+
+W_Complex128Box.typedef = TypeDef("complex128", (W_ComplexFloatingBox.typedef, complex_typedef),
+    __module__ = "numpypy",
+    __new__ = interp2app(W_Complex128Box.descr__new__.im_func),
+)
\ No newline at end of file
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
@@ -13,6 +13,7 @@
 SIGNEDLTR = "i"
 BOOLLTR = "b"
 FLOATINGLTR = "f"
+COMPLEXLTR = "c"
 
 
 VOID_STORAGE = lltype.Array(lltype.Char, hints={'nolength': True, 'render_as_void': True})
@@ -235,17 +236,26 @@
             kind=FLOATINGLTR,
             name="float64",
             char="d",
-            w_box_type = space.gettypefor(interp_boxes.W_Float64Box),
+            w_box_type=space.gettypefor(interp_boxes.W_Float64Box),
             alternate_constructors=[space.w_float],
             aliases=["float"],
         )
+        self.w_complex128dtype = W_Dtype(
+            types.Complex128(),
+            num=15,
+            kind=COMPLEXLTR,
+            name="complex128",
+            char="c",
+            w_box_type=space.gettypefor(interp_boxes.W_Complex128Box),
+            alternate_constructors=[space.w_complex],
+        )
 
         self.builtin_dtypes = [
             self.w_booldtype, self.w_int8dtype, self.w_uint8dtype,
             self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype,
             self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype,
             self.w_int64dtype, self.w_uint64dtype, self.w_float32dtype,
-            self.w_float64dtype
+            self.w_float64dtype, self.w_complex128dtype
         ]
         self.dtypes_by_num_bytes = sorted(
             (dtype.itemtype.get_element_size(), dtype)
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
@@ -334,6 +334,7 @@
     bool_dtype = interp_dtype.get_dtype_cache(space).w_booldtype
     long_dtype = interp_dtype.get_dtype_cache(space).w_longdtype
     int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype
+    complex128_dtype = interp_dtype.get_dtype_cache(space).w_complex128dtype
 
     if isinstance(w_obj, interp_boxes.W_GenericBox):
         dtype = w_obj.get_dtype(space)
@@ -355,6 +356,8 @@
             current_guess is long_dtype or current_guess is int64_dtype):
             return int64_dtype
         return current_guess
+    elif space.isinstance_w(w_obj, space.w_complex):
+        return complex128_dtype
     return interp_dtype.get_dtype_cache(space).w_float64dtype
 
 
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -164,6 +164,16 @@
         for i in range(5):
             assert b[i] == i * 2
 
+    def test_complex128(self):
+        from _numpypy import dtype, complex128
+
+        d = dtype("complex128")
+        assert d.num == 15
+        assert d.kind== "c"
+        assert d.type is complex128
+        assert d.name == "complex128"
+        assert d.itemsize == 16
+
     def test_shape(self):
         from _numpypy import dtype
 
@@ -375,6 +385,19 @@
         assert numpy.float64('23.4') == numpy.float64(23.4)
         raises(ValueError, numpy.float64, '23.2df')
 
+    def test_complex128(self):
+        import _numpypy as numpy
+
+        assert numpy.complex128.mro() == [numpy.complex128, numpy.complexfloating, numpy.inexact, numpy.number, numpy.generic, complex, object]
+        a = numpy.array([1j], numpy.complex128)
+        assert type(a[0]) is numpy.complex128
+        assert numpy.dtype(complex).type is numpy.complex128
+        assert a[0] == 1j
+
+        assert numpy.complex128(2) == 2
+        assert numpy.complex128(2.0 + 3j) == 2.0 + 3j
+        raises(TypeError, numpy.complex128, "23")
+
     def test_subclass_type(self):
         import _numpypy as numpy
 
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -57,12 +57,11 @@
     return dispatcher
 
 class BaseType(object):
-    def _unimplemented_ufunc(self, *args):
-        raise NotImplementedError
-    # add = sub = mul = div = mod = pow = eq = ne = lt = le = gt = ge = max = \
-    #     min = copysign = pos = neg = abs = sign = reciprocal = fabs = floor = \
-    #     exp = sin = cos = tan = arcsin = arccos = arctan = arcsinh = \
-    #     arctanh = _unimplemented_ufunc
+    def coerce(self, space, w_item):
+        if isinstance(w_item, self.BoxType):
+            return w_item
+        return self.coerce_subtype(space, space.gettypefor(self.BoxType), w_item)
+
 
 class Primitive(object):
     _mixin_ = True
@@ -78,11 +77,6 @@
         assert isinstance(box, self.BoxType)
         return box.value
 
-    def coerce(self, space, w_item):
-        if isinstance(w_item, self.BoxType):
-            return w_item
-        return self.coerce_subtype(space, space.gettypefor(self.BoxType), w_item)
-
     def coerce_subtype(self, space, w_subtype, w_item):
         # XXX: ugly
         w_obj = space.allocate_instance(self.BoxType, w_subtype)
@@ -513,3 +507,58 @@
     T = rffi.DOUBLE
     BoxType = interp_boxes.W_Float64Box
     format_code = "d"
+
+
+class CompositeType(BaseType):
+    def __init__(self, fields):
+        BaseType.__init__(self)
+        self.fields = fields
+
+    def get_element_size(self):
+        s = 0
+        for field in self.fields:
+            s += field.get_element_size()
+        return s
+
+    def read(self, storage, width, i, offset):
+        subboxes = []
+        for field in self.fields:
+            subboxes.append(field.read(storage, width, i, offset))
+            offset += field.get_element_size()
+        return self.box(subboxes)
+
+    def store(self, storage, width, i, offset, box):
+        subboxes = self.get_subboxes(box)
+        assert len(subboxes) == len(self.fields)
+        for field, subbox in zip(self.fields, subboxes):
+            field.store(storage, width, i, offset, subbox)
+            offset += field.get_element_size()
+
+class Complex128(CompositeType):
+    BoxType = interp_boxes.W_Complex128Box
+    COMPLEX_TYPE = Float64
+
+    def __init__(self):
+        self.type = self.COMPLEX_TYPE()
+        CompositeType.__init__(self, [self.type, self.type])
+
+    def box(self, subboxes):
+        [real, imag] = subboxes
+        return self.BoxType(self.type.unbox(real), self.type.unbox(imag))
+
+    def get_subboxes(self, box):
+        return [self.type.box(box.real), self.type.box(box.imag)]
+
+    def coerce_subtype(self, space, w_subtype, w_item):
+        real, imag = space.unpackcomplex(w_item)
+        w_obj = space.allocate_instance(self.BoxType, w_subtype)
+        assert isinstance(w_obj, self.BoxType)
+        w_obj.__init__(real, imag)
+        return w_obj
+
+    def for_computation(self, v):
+        pass
+
+    @raw_binary_op
+    def eq(self, v1, v2):
+        return v1.real == v2.real and v1.imag == v2.imag
\ No newline at end of file


More information about the pypy-commit mailing list