[pypy-commit] pypy numppy-flatitter: redo, add lots of tests, some still fail
mattip
noreply at buildbot.pypy.org
Mon Jan 23 00:56:38 CET 2012
Author: mattip
Branch: numppy-flatitter
Changeset: r51670:ff368a6d0ff7
Date: 2012-01-19 01:16 +0200
http://bitbucket.org/pypy/pypy/changeset/ff368a6d0ff7/
Log: redo, add lots of tests, some still fail
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
@@ -1290,53 +1290,100 @@
tolist = interp2app(BaseArray.descr_tolist),
)
+#TODO:Move all this to another file after fijal finishes reorganization
+def _to_coords(space, arr, w_item_or_slice):
+ '''Always returns a list of coords.
+ '''
+ start = stop = step = 0
+ if space.isinstance_w(w_item_or_slice, space.w_int):
+ start = space.int_w(w_item_or_slice)
+ if start < 0:
+ start += arr.size
+ stop = start+1
+ step = 1
+ elif space.isinstance_w(w_item_or_slice, space.w_slice):
+ start, stop, step, lngth = space.decode_index4(w_item_or_slice,arr.size)
+ else:
+ operationerrfmt(space.NotImplementedError,'cannot iterator over %s yet', w_item_or_slice)
+ retval = []
+ for i in range(start, stop, step):
+ coords = []
+ ii = i
+ if arr.order =='C':
+ for s in range(len(arr.shape) -1, -1, -1):
+ coords.insert(0,ii % arr.shape[s])
+ ii /= arr.shape[s]
+ else:
+ raise NotImplementedError
+ #untested code. Erase?
+ for s in range(len(arr.shape)):
+ coords.append(ii % arr.shape[s])
+ ii /= arr.shape[s]
+ if ii != 0:
+ raise OperationError(space.w_IndexError,
+ space.wrap("invalid index"))
+
+ retval.append(space.newtuple([space.wrap(c) for c in coords]))
+ return retval
class W_FlatIterator(ViewArray):
@jit.unroll_safe
def __init__(self, arr):
arr = arr.get_concrete()
- size = 1
- for sh in arr.shape:
- size *= sh
- if arr.strides[-1] <= arr.strides[0]:
- self.strides = [arr.strides[-1]]
- self.backstrides = [arr.backstrides[-1]]
- else:
- XXX
- # This will not work: getitem and setitem will
- # fail. Need to be smarter: calculate the indices from the int
- self.strides = [arr.strides[0]]
- self.backstrides = [arr.backstrides[0]]
- ViewArray.__init__(self, size, [size], arr.dtype, order=arr.order,
- parent=arr)
self.shapelen = len(arr.shape)
sig = arr.find_sig()
- #self.iter = OneDimIterator(arr.start, self.strides[0],
- # self.shape[0])
self.iter = sig.create_frame(arr).get_final_iter()
- self.start = arr.start
self.base = arr
+ self.index = 0
+ ViewArray.__init__(self, arr.size, [arr.size], arr.dtype, arr.order, arr)
def descr_next(self, space):
if self.iter.done():
raise OperationError(space.w_StopIteration, space.w_None)
- result = self.getitem(self.iter.offset)
+ result = self.base.getitem(self.iter.offset)
self.iter = self.iter.next(self.shapelen)
+ self.index += 1
return result
def descr_iter(self):
return self
def descr_index(self, space):
- return space.wrap(self.iter.offset)
+ return space.wrap(self.index)
+ def descr_coords(self, space):
+ return _to_coords(space, self.base, space.wrap(self.index))[0]
+
+ def descr_getitem(self, space, w_idx):
+ coords = _to_coords(space, self.base, w_idx)
+ if len(coords)>1:
+ w_result = W_NDimArray(len(coords), [len(coords)], self.base.dtype,
+ self.base.order)
+ for i,c in enumerate(coords):
+ w_val = self.base.descr_getitem(space, c)
+ w_result.setitem(i,w_val)
+ return w_result
+ else:
+ return self.base.descr_getitem(space, coords[0])
+
+ def descr_setitem(self, space, w_idx, w_value):
+ coords = _to_coords(space, self.base, w_idx)
+ arr = convert_to_array(space, w_value)
+ ai = 0
+ for c in coords:
+ v = arr.getitem(ai)
+ self.base.descr_setitem(space, c,v)
+ ai = (ai + 1) % arr.size
+
W_FlatIterator.typedef = TypeDef(
'flatiter',
next = interp2app(W_FlatIterator.descr_next),
__iter__ = interp2app(W_FlatIterator.descr_iter),
- __getitem__ = interp2app(BaseArray.descr_getitem),
- __setitem__ = interp2app(BaseArray.descr_setitem),
+ __getitem__ = interp2app(W_FlatIterator.descr_getitem),
+ __setitem__ = interp2app(W_FlatIterator.descr_setitem),
index = GetSetProperty(W_FlatIterator.descr_index),
+ coords = GetSetProperty(W_FlatIterator.descr_coords),
+
)
W_FlatIterator.acceptable_as_base_class = False
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
@@ -1300,7 +1300,7 @@
assert (a + a).flat[3] == 6
assert a[::2].flat[3] == 6
assert a.reshape(2,5).flat[3] == 3
- b = a.flat
+ b = a.reshape(2,5).flat
b.next()
b.next()
b.next()
@@ -1309,6 +1309,19 @@
raises(IndexError, "b[11]")
raises(IndexError, "b[-11]")
assert b.index == 3
+ assert b.coords == (0,3)
+
+ def test_flatiter_setitem(self):
+ from _numpypy import arange, array
+ a = arange(12).reshape(3,4)
+ b = a.T.flat
+ b[6::2] = [-1, -2]
+ assert (a == [[0, 1, -1, 3], [4, 5, 6, -1], [8, 9, -2, 11]]).all()
+ b[1:2] = [[[100]]]
+ assert(a[0,0] == 100)
+ assert(a[1,0] == 100)
+ b[array([10, 11])] == [-20, -40]
+
def test_flatiter_view(self):
from _numpypy import arange
@@ -1323,8 +1336,14 @@
def test_flatiter_transpose(self):
from _numpypy import arange
- a = arange(10)
- assert a.reshape(2,5).T.flat[3] == 6
+ a = arange(10).reshape(2,5).T
+ b = a.flat
+ assert (b[:5] == [0, 5, 1, 6, 2]).all()
+ b.next()
+ b.next()
+ b.next()
+ assert b.index == 3
+ assert b.coords == (1,1)
def test_slice_copy(self):
from _numpypy import zeros
More information about the pypy-commit
mailing list