Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r59923:32137bbbfdf8 Date: 2013-01-10 17:42 +0200 http://bitbucket.org/pypy/pypy/changeset/32137bbbfdf8/
Log: (mattip) merge numpypy-real-as-view, which makes .real and .imag attributes views instead of ufuncs, for compatibility diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -13,6 +13,7 @@ from pypy.rlib.debug import make_sure_not_resized class ConcreteArrayIterator(base.BaseArrayIterator): + _immutable_fields_ = ['dtype', 'skip', 'size'] def __init__(self, array): self.array = array self.offset = 0 @@ -21,10 +22,10 @@ self.size = array.size def setitem(self, elem): - self.array.setitem(self.offset, elem) + self.dtype.setitem(self.array, self.offset, elem) def getitem(self): - return self.array.getitem(self.offset) + return self.dtype.getitem(self.array, self.offset) def getitem_bool(self): return self.dtype.getitem_bool(self.array, self.offset) @@ -42,13 +43,16 @@ self.offset %= self.size class OneDimViewIterator(ConcreteArrayIterator): - def __init__(self, array): + ''' The view iterator dtype can be different from the + array.dtype, this is what makes it a View + ''' + def __init__(self, array, dtype, start, strides, shape): self.array = array - self.offset = array.start - self.skip = array.get_strides()[0] - self.dtype = array.dtype + self.dtype = dtype + self.offset = start + self.skip = strides[0] self.index = 0 - self.size = array.get_shape()[0] + self.size = shape[0] def next(self): self.offset += self.skip @@ -65,9 +69,13 @@ self.offset %= self.size class MultiDimViewIterator(ConcreteArrayIterator): - def __init__(self, array, start, strides, backstrides, shape): + ''' The view iterator dtype can be different from the + array.dtype, this is what makes it a View + ''' + def __init__(self, array, dtype, start, strides, backstrides, shape): self.indexes = [0] * len(shape) self.array = array + self.dtype = dtype self.shape = shape self.offset = start self.shapelen = len(shape) @@ -131,12 +139,13 @@ self.offset = array.start self.dim = dim self.array = array + self.dtype = array.dtype def setitem(self, elem): - self.array.setitem(self.offset, elem) + self.dtype.setitem(self.array, self.offset, elem) def getitem(self): - return self.array.getitem(self.offset) + return self.dtype.getitem(self.array, self.offset) @jit.unroll_safe def next(self): @@ -220,6 +229,32 @@ new_shape, self) else: return None + + def get_real(self): + strides = self.get_strides() + backstrides = self.get_backstrides() + if self.dtype.is_complex_type(): + dtype = self.dtype.float_type + return SliceArray(self.start, strides, backstrides, + self.get_shape(), self, dtype=dtype) + return SliceArray(self.start, strides, backstrides, + self.get_shape(), self) + + def get_imag(self): + strides = self.get_strides() + backstrides = self.get_backstrides() + if self.dtype.is_complex_type(): + dtype = self.dtype.float_type + return SliceArray(self.start + dtype.get_size(), strides, + backstrides, self.get_shape(), self, dtype=dtype) + if self.dtype.is_flexible_type(): + # numpy returns self for self.imag + return SliceArray(self.start, strides, backstrides, + self.get_shape(), self) + impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides, + backstrides) + impl.fill(self.dtype.box(0)) + return impl # -------------------- applevel get/setitem ----------------------- @@ -377,7 +412,7 @@ def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) - return MultiDimViewIterator(self, self.start, r[0], r[1], shape) + return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): shape = self.get_shape()[:] @@ -411,7 +446,7 @@ r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self, 0, r[0], r[1], shape) + return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): self.dtype.fill(self.storage, box, 0, self.size) @@ -424,6 +459,12 @@ self.order) return SliceArray(0, strides, backstrides, new_shape, self) +class NonWritableArray(ConcreteArray): + def descr_setitem(self, space, w_index, w_value): + raise OperationError(space.w_RuntimeError, space.wrap( + "array is not writable")) + + class SliceArray(BaseConcreteArray): def __init__(self, start, strides, backstrides, shape, parent, dtype=None): self.strides = strides @@ -448,11 +489,12 @@ r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self.parent, + return MultiDimViewIterator(self.parent, self.dtype, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return OneDimViewIterator(self) - return MultiDimViewIterator(self.parent, self.start, + return OneDimViewIterator(self.parent, self.dtype, self.start, + self.get_strides(), self.get_shape()) + return MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_backstrides(), self.get_shape()) 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 @@ -136,7 +136,7 @@ return self.kind == SIGNEDLTR def is_complex_type(self): - return (self.num == 14 or self.num == 15 or self.num == 16) + return False def is_bool_type(self): return self.kind == BOOLLTR @@ -155,6 +155,19 @@ def get_size(self): return self.itemtype.get_element_size() +class W_ComplexDtype(W_Dtype): + + def __init__(self, itemtype, num, kind, name, char, w_box_type, + alternate_constructors=[], aliases=[], + fields=None, fieldnames=None, native=True, float_type=None): + W_Dtype.__init__(self, itemtype, num, kind, name, char, w_box_type, + alternate_constructors=alternate_constructors, aliases=aliases, + fields=fields, fieldnames=fieldnames, native=native) + self.float_type = float_type + + def is_complex_type(self): + return True + def dtype_from_list(space, w_lst): lst_w = space.listview(w_lst) fields = {} @@ -413,15 +426,16 @@ alternate_constructors=[space.w_float], aliases=["float"], ) - self.w_complex64dtype = W_Dtype( + self.w_complex64dtype = W_ComplexDtype( types.Complex64(), num=14, kind=COMPLEXLTR, name="complex64", char="F", w_box_type = space.gettypefor(interp_boxes.W_Complex64Box), + float_type = self.w_float32dtype, ) - self.w_complex128dtype = W_Dtype( + self.w_complex128dtype = W_ComplexDtype( types.Complex128(), num=15, kind=COMPLEXLTR, @@ -430,6 +444,7 @@ w_box_type = space.gettypefor(interp_boxes.W_Complex128Box), alternate_constructors=[space.w_complex], aliases=["complex"], + float_type = self.w_float64dtype, ) if interp_boxes.long_double_size == 12: self.w_float96dtype = W_Dtype( @@ -443,7 +458,7 @@ ) self.w_longdouble = self.w_float96dtype - self.w_complex192dtype = W_Dtype( + self.w_complex192dtype = W_ComplexDtype( types.Complex192(), num=16, kind=COMPLEXLTR, @@ -452,6 +467,7 @@ w_box_type = space.gettypefor(interp_boxes.W_Complex192Box), alternate_constructors=[space.w_complex], aliases=["clongdouble", "clongfloat"], + float_type = self.w_float96dtype, ) self.w_clongdouble = self.w_complex192dtype @@ -467,7 +483,7 @@ ) self.w_longdouble = self.w_float128dtype - self.w_complex256dtype = W_Dtype( + self.w_complex256dtype = W_ComplexDtype( types.Complex256(), num=16, kind=COMPLEXLTR, @@ -476,6 +492,7 @@ w_box_type = space.gettypefor(interp_boxes.W_Complex256Box), alternate_constructors=[space.w_complex], aliases=["clongdouble", "clongfloat"], + float_type = self.w_float128dtype, ) self.w_clongdouble = self.w_complex256dtype else: diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -235,6 +235,29 @@ def descr_copy(self, space): return W_NDimArray(self.implementation.copy()) + def descr_get_real(self, space): + return W_NDimArray(self.implementation.get_real()) + + def descr_get_imag(self, space): + ret = self.implementation.get_imag() + if ret: + return W_NDimArray(ret) + raise OperationError(space.w_NotImplementedError, + space.wrap('imag not implemented for this dtype')) + + def descr_set_real(self, space, w_value): + # copy (broadcast) values into self + tmp = self.implementation.get_real() + tmp.setslice(space, convert_to_array(space, w_value)) + + def descr_set_imag(self, space, w_value): + # if possible, copy (broadcast) values into self + if not self.get_dtype().is_complex_type(): + raise OperationError(space.w_TypeError, + space.wrap('array does not have imaginary part to set')) + tmp = self.implementation.get_imag() + tmp.setslice(space, convert_to_array(space, w_value)) + def descr_reshape(self, space, args_w): """reshape(...) a.reshape(shape) @@ -387,8 +410,6 @@ descr_neg = _unaryop_impl("negative") descr_abs = _unaryop_impl("absolute") descr_invert = _unaryop_impl("invert") - descr_get_real = _unaryop_impl("real") - descr_get_imag = _unaryop_impl("imag") def descr_nonzero(self, space): if self.get_size() > 1: @@ -635,9 +656,10 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), - real = GetSetProperty(W_NDimArray.descr_get_real), - imag = GetSetProperty(W_NDimArray.descr_get_imag), - + real = GetSetProperty(W_NDimArray.descr_get_real, + W_NDimArray.descr_set_real), + imag = GetSetProperty(W_NDimArray.descr_get_imag, + W_NDimArray.descr_set_imag), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) diff --git a/pypy/module/micronumpy/test/test_iter.py b/pypy/module/micronumpy/test/test_iter.py --- a/pypy/module/micronumpy/test/test_iter.py +++ b/pypy/module/micronumpy/test/test_iter.py @@ -12,7 +12,7 @@ strides = [5, 1] backstrides = [x * (y - 1) for x,y in zip(strides, shape)] assert backstrides == [10, 4] - i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape) + i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape) i.next() i.next() i.next() @@ -30,7 +30,7 @@ strides = [1, 3] backstrides = [x * (y - 1) for x,y in zip(strides, shape)] assert backstrides == [2, 12] - i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape) + i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape) i.next() i.next() i.next() @@ -51,7 +51,7 @@ strides = [5, 1] backstrides = [x * (y - 1) for x,y in zip(strides, shape)] assert backstrides == [10, 4] - i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape) + i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape) i.next_skip_x(2) i.next_skip_x(2) i.next_skip_x(2) @@ -74,7 +74,7 @@ strides = [1, 3] backstrides = [x * (y - 1) for x,y in zip(strides, shape)] assert backstrides == [2, 12] - i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape) + i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape) i.next_skip_x(2) i.next_skip_x(2) i.next_skip_x(2) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1169,8 +1169,8 @@ assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() def test_eye(self): - from _numpypy import eye, array - from _numpypy import int32, float64, dtype + from _numpypy import eye + from _numpypy import int32, dtype a = eye(0) assert len(a) == 0 assert a.dtype == dtype('float64') @@ -1345,6 +1345,42 @@ assert b[0] == 3 assert b[1] == 2 + def test_realimag_views(self): + from _numpypy import arange, array + a = arange(15) + b = a.real + b[5]=50 + assert a[5] == 50 + b = a.imag + assert b[7] == 0 + raises(RuntimeError, 'b[7] = -2') + raises(TypeError, 'a.imag = -2') + a = array(['abc','def'],dtype='S3') + b = a.real + assert a[0] == b[0] + assert a[1] == b[1] + b[1] = 'xyz' + assert a[1] == 'xyz' + assert a.imag[0] == 'abc' + raises(TypeError, 'a.imag = "qop"') + a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) + assert a.real[0,1] == 2 + a.real[0,1] = -20 + assert a[0,1].real == -20 + b = a.imag + assert b[1,2] == -1 + b[1,2] = 30 + assert a[1,2].imag == 30 + a.real = 13 + assert a[1,1].real == 13 + a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) + a.real = 13 + assert a[3].real == 13 + a.imag = -5 + a.imag[3] = -10 + assert a[3].imag == -10 + assert a[2].imag == -5 + def test_tolist_scalar(self): from _numpypy import int32, bool_ x = int32(23) @@ -2273,7 +2309,7 @@ assert a[0]['x'] == 'a' def test_stringarray(self): - from _numpypy import array, flexible + from _numpypy import array a = array(['abc'],'S3') assert str(a.dtype) == '|S3' a = array(['abc']) @@ -2293,7 +2329,6 @@ def test_flexible_repr(self): # import overrides str(), repr() for array - from numpypy.core import arrayprint from _numpypy import array a = array(['abc'],'S3') s = repr(a) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit