Author: Maciej Fijalkowski <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit