[pypy-commit] pypy default: (mattip) merge matrixmath, adds arange, transpose, flatiter
fijal
noreply at buildbot.pypy.org
Mon Nov 28 08:10:05 CET 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch:
Changeset: r49878:3998a7e1ed9b
Date: 2011-11-28 09:09 +0200
http://bitbucket.org/pypy/pypy/changeset/3998a7e1ed9b/
Log: (mattip) merge matrixmath, adds arange, transpose, flatiter
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
@@ -13,6 +13,7 @@
'empty': 'interp_numarray.zeros',
'ones': 'interp_numarray.ones',
'fromstring': 'interp_support.fromstring',
+ 'flatiter': 'interp_numarray.W_FlatIterator',
'True_': 'space.w_True',
'False_': 'space.w_False',
@@ -57,4 +58,5 @@
'mean': 'app_numpy.mean',
'inf': 'app_numpy.inf',
'e': 'app_numpy.e',
+ 'arange': 'app_numpy.arange',
}
diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py
--- a/pypy/module/micronumpy/app_numpy.py
+++ b/pypy/module/micronumpy/app_numpy.py
@@ -6,12 +6,33 @@
inf = float("inf")
e = math.e
+
def average(a):
# This implements a weighted average, for now we don't implement the
# weighting, just the average part!
return mean(a)
+
def mean(a):
if not hasattr(a, "mean"):
a = numpypy.array(a)
return a.mean()
+
+
+def arange(start, stop=None, step=1, dtype=None):
+ '''arange([start], stop[, step], dtype=None)
+ Generate values in the half-interval [start, stop).
+ '''
+ if stop is None:
+ stop = start
+ start = 0
+ if dtype is None:
+ test = numpypy.array([start, stop, step, 0])
+ dtype = test.dtype
+ arr = numpypy.zeros(int(math.ceil((stop - start) / step)), dtype=dtype)
+ i = start
+ for j in range(arr.size):
+ arr[j] = i
+ j += 1
+ i += step
+ return arr
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
@@ -221,6 +221,7 @@
@binop
def div(self, v1, v2):
+ # XXX this won't work after translation, probably requires ovfcheck
try:
return v1 / v2
except ZeroDivisionError:
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
@@ -227,7 +227,7 @@
self.strides = []
self.backstrides = []
for i in range(len(arr.shape)):
- if arr.shape[i]==1:
+ if arr.shape[i] == 1:
self.strides.append(0)
self.backstrides.append(0)
else:
@@ -312,12 +312,12 @@
def get_offset(self):
return 0
+
class BaseArray(Wrappable):
_attrs_ = ["invalidates", "signature", "shape", "strides", "backstrides",
"start", 'order']
- _immutable_fields_ = ['shape[*]', "strides[*]", "backstrides[*]", 'start',
- "order"]
+ _immutable_fields_ = ['start', "order"]
strides = None
start = 0
@@ -327,21 +327,24 @@
self.shape = shape
self.order = order
if self.strides is None:
- strides = []
- backstrides = []
- s = 1
- shape_rev = shape[:]
- if order == 'C':
- shape_rev.reverse()
- for sh in shape_rev:
- strides.append(s)
- backstrides.append(s * (sh - 1))
- s *= sh
- if order == 'C':
- strides.reverse()
- backstrides.reverse()
- self.strides = strides[:]
- self.backstrides = backstrides[:]
+ self.calc_strides(shape)
+
+ def calc_strides(self, shape):
+ strides = []
+ backstrides = []
+ s = 1
+ shape_rev = shape[:]
+ if self.order == 'C':
+ shape_rev.reverse()
+ for sh in shape_rev:
+ strides.append(s)
+ backstrides.append(s * (sh - 1))
+ s *= sh
+ if self.order == 'C':
+ strides.reverse()
+ backstrides.reverse()
+ self.strides = strides[:]
+ self.backstrides = backstrides[:]
def invalidated(self):
if self.invalidates:
@@ -684,6 +687,9 @@
def descr_getitem(self, space, w_idx):
if self._single_item_result(space, w_idx):
concrete = self.get_concrete()
+ if len(concrete.shape) < 1:
+ raise OperationError(space.w_IndexError, space.wrap(
+ "0-d arrays can't be indexed"))
item = concrete._index_of_single_item(space, w_idx)
return concrete.getitem(item).wrap(space)
chunks = self._prepare_slice_args(space, w_idx)
@@ -693,6 +699,9 @@
self.invalidated()
concrete = self.get_concrete()
if self._single_item_result(space, w_idx):
+ if len(concrete.shape) < 1:
+ raise OperationError(space.w_IndexError, space.wrap(
+ "0-d arrays can't be indexed"))
item = concrete._index_of_single_item(space, w_idx)
concrete.setitem_w(space, item, w_value)
return
@@ -750,15 +759,32 @@
return space.wrap(space.float_w(self.descr_sum(space)) / self.find_size())
def descr_nonzero(self, space):
- try:
- if self.find_size() > 1:
- raise OperationError(space.w_ValueError, space.wrap(
- "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"))
- except ValueError:
- pass
+ if self.find_size() > 1:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"))
return space.wrap(space.is_true(self.get_concrete().eval(
self.start_iter(self.shape)).wrap(space)))
+ def descr_get_transpose(self, space):
+ concrete = self.get_concrete()
+ if len(concrete.shape) < 2:
+ return space.wrap(self)
+ new_sig = signature.Signature.find_sig([
+ NDimSlice.signature, self.signature
+ ])
+ strides = []
+ backstrides = []
+ shape = []
+ for i in range(len(concrete.shape) - 1, -1, -1):
+ strides.append(concrete.strides[i])
+ backstrides.append(concrete.backstrides[i])
+ shape.append(concrete.shape[i])
+ return space.wrap(NDimSlice(concrete, new_sig, self.start, strides[:],
+ backstrides[:], shape[:]))
+
+ def descr_get_flatiter(self, space):
+ return space.wrap(W_FlatIterator(self))
+
def getitem(self, item):
raise NotImplementedError
@@ -796,7 +822,7 @@
self.value = value
def find_size(self):
- raise ValueError
+ return 1
def get_concrete(self):
return self
@@ -805,7 +831,7 @@
return self.dtype
def getitem(self, item):
- return self.value
+ raise NotImplementedError
def eval(self, iter):
return self.value
@@ -816,6 +842,7 @@
def to_str(self, space, comma, builder, indent=' ', use_ellipsis=False):
builder.append(self.dtype.str_format(self.value))
+
class VirtualArray(BaseArray):
"""
Class for representing virtual arrays, such as binary ops or ufuncs
@@ -985,6 +1012,7 @@
return space.wrap(self.shape[0])
return space.wrap(1)
+
class VirtualView(VirtualArray):
pass
@@ -1164,6 +1192,9 @@
shape = GetSetProperty(BaseArray.descr_get_shape),
size = GetSetProperty(BaseArray.descr_get_size),
+ T = GetSetProperty(BaseArray.descr_get_transpose),
+ flat = GetSetProperty(BaseArray.descr_get_flatiter),
+
mean = interp2app(BaseArray.descr_mean),
sum = interp2app(BaseArray.descr_sum),
prod = interp2app(BaseArray.descr_prod),
@@ -1177,3 +1208,25 @@
copy = interp2app(BaseArray.descr_copy),
)
+
+
+class W_FlatIterator(Wrappable):
+ _immutable_fields_ = ['shapelen', 'arr']
+
+ def __init__(self, arr):
+ self.arr = arr.get_concrete()
+ self.iter = arr.start_iter()
+ self.shapelen = len(arr.shape)
+
+ def descr_next(self, space):
+ if self.iter.done():
+ raise OperationError(space.w_StopIteration, space.wrap(''))
+ result = self.arr.eval(self.iter)
+ self.iter = self.iter.next(self.shapelen)
+ return result.wrap(space)
+
+
+W_FlatIterator.typedef = TypeDef(
+ 'flatiter',
+ next = interp2app(W_FlatIterator.descr_next),
+)
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
@@ -6,11 +6,14 @@
from pypy.interpreter.error import OperationError
from pypy.conftest import gettestobjspace
+
class MockDtype(object):
signature = signature.BaseSignature()
+
def malloc(self, size):
return None
+
class TestNumArrayDirect(object):
def newslice(self, *args):
return self.space.newslice(*[self.space.wrap(arg) for arg in args])
@@ -150,8 +153,11 @@
assert shape_agreement(self.space, [1, 2, 3], [1, 2, 3]) == [1, 2, 3]
py.test.raises(OperationError, shape_agreement, self.space, [2], [3])
assert shape_agreement(self.space, [4, 4], []) == [4, 4]
- assert shape_agreement(self.space, [8, 1, 6, 1], [7, 1, 5]) == [8, 7, 6, 5]
- assert shape_agreement(self.space, [5, 2], [4, 3, 5, 2]) == [4, 3, 5, 2]
+ assert shape_agreement(self.space,
+ [8, 1, 6, 1], [7, 1, 5]) == [8, 7, 6, 5]
+ assert shape_agreement(self.space,
+ [5, 2], [4, 3, 5, 2]) == [4, 3, 5, 2]
+
class AppTestNumArray(BaseNumpyAppTest):
def test_type(self):
@@ -208,9 +214,6 @@
from numpypy import array
a = array(range(5))
assert a[3] == 3
- a = array(1)
- assert a[0] == 1
- assert a.shape == ()
def test_getitem(self):
from numpypy import array
@@ -298,7 +301,10 @@
def test_scalar(self):
from numpypy import array
a = array(3)
- assert a[0] == 3
+ #assert a[0] == 3
+ raises(IndexError, "a[0]")
+ assert a.size == 1
+ assert a.shape == ()
def test_len(self):
from numpypy import array
@@ -737,6 +743,7 @@
assert bool(array([1]))
assert not bool(array([0]))
+
class AppTestMultiDim(BaseNumpyAppTest):
def test_init(self):
import numpypy
@@ -829,7 +836,8 @@
def test_ufunc(self):
from numpypy import array
a = array([[1, 2], [3, 4], [5, 6]])
- assert ((a + a) == array([[1 + 1, 2 + 2], [3 + 3, 4 + 4], [5 + 5, 6 + 6]])).all()
+ assert ((a + a) == \
+ array([[1 + 1, 2 + 2], [3 + 3, 4 + 4], [5 + 5, 6 + 6]])).all()
def test_getitem_add(self):
from numpypy import array
@@ -844,7 +852,8 @@
def test_getitem_3(self):
from numpypy import array
- a = array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14]])
+ a = array([[1, 2], [3, 4], [5, 6], [7, 8],
+ [9, 10], [11, 12], [13, 14]])
b = a[::2]
print a
print b
@@ -877,11 +886,12 @@
b = array(((10, 11, 12), (20, 21, 22), (30, 31, 32)))
c = ((a + b) == [b, b, b])
assert c.all()
- a = array((((10,11,12), ), ((20, 21, 22), ), ((30,31,32), )))
+ a = array((((10, 11, 12), ), ((20, 21, 22), ), ((30, 31, 32), )))
assert(a.shape == (3, 1, 3))
d = zeros((3, 3))
c = ((a + d) == [b, b, b])
- c = ((a + d) == array([[[10., 11., 12.]]*3, [[20.,21.,22.]]*3, [[30.,31.,32.]]*3]))
+ c = ((a + d) == array([[[10., 11., 12.]] * 3,
+ [[20., 21., 22.]] * 3, [[30., 31., 32.]] * 3]))
assert c.all()
def test_broadcast_scalar(self):
@@ -906,14 +916,15 @@
from numpypy import array
a = array([[1, 2], [3, 4], [5, 6]])
assert a.argmax() == 5
- assert a[:2,].argmax() == 3
+ assert a[:2, ].argmax() == 3
def test_broadcast_wrong_shapes(self):
from numpypy import zeros
a = zeros((4, 3, 2))
b = zeros((4, 2))
exc = raises(ValueError, lambda: a + b)
- assert str(exc.value) == "operands could not be broadcast together with shapes (4,3,2) (4,2)"
+ assert str(exc.value) == "operands could not be broadcast" \
+ " together with shapes (4,3,2) (4,2)"
def test_reduce(self):
from numpypy import array
@@ -923,6 +934,37 @@
c = b + b
assert c.sum() == (6 + 8 + 10 + 12) * 2
+ def test_transpose(self):
+ from numpypy import array
+ a = array(((range(3), range(3, 6)),
+ (range(6, 9), range(9, 12)),
+ (range(12, 15), range(15, 18)),
+ (range(18, 21), range(21, 24))))
+ assert a.shape == (4, 2, 3)
+ b = a.T
+ assert b.shape == (3, 2, 4)
+ assert(b[0, :, 0] == [0, 3]).all()
+ b[:, 0, 0] = 1000
+ assert(a[0, 0, :] == [1000, 1000, 1000]).all()
+ a = array(range(5))
+ b = a.T
+ assert(b == range(5)).all()
+ a = array((range(10), range(20, 30)))
+ b = a.T
+ assert(b[:, 0] == a[0, :]).all()
+
+ def test_flatiter(self):
+ from numpypy import array, flatiter
+ a = array([[10, 30], [40, 60]])
+ f_iter = a.flat
+ assert f_iter.next() == 10
+ assert f_iter.next() == 30
+ assert f_iter.next() == 40
+ assert f_iter.next() == 60
+ raises(StopIteration, "f_iter.next()")
+ raises(TypeError, "flatiter()")
+
+
class AppTestSupport(object):
def setup_class(cls):
import struct
@@ -936,6 +978,7 @@
assert a[i] == i + 1
raises(ValueError, fromstring, "abc")
+
class AppTestRepr(BaseNumpyAppTest):
def test_repr(self):
from numpypy import array, zeros
@@ -1008,7 +1051,9 @@
assert str(a) == "3"
a = zeros((400, 400), dtype=int)
- assert str(a) == "[[0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]\n ..., \n [0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]]"
+ assert str(a) == "[[0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]\n" \
+ " [0 0 0 ..., 0 0 0]\n ..., \n [0 0 0 ..., 0 0 0]\n" \
+ " [0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]]"
a = zeros((2, 2, 2))
r = str(a)
assert r == '[[[0.0 0.0]\n [0.0 0.0]]\n\n [[0.0 0.0]\n [0.0 0.0]]]'
@@ -1026,3 +1071,25 @@
assert str(b) == "[7 8 9]"
b = a[2:1, ]
assert str(b) == "[]"
+
+
+class AppTestRanges(BaseNumpyAppTest):
+ def test_arange(self):
+ from numpypy import arange, array, dtype
+ a = arange(3)
+ assert (a == [0, 1, 2]).all()
+ assert a.dtype is dtype(int)
+ a = arange(3.0)
+ assert (a == [0., 1., 2.]).all()
+ assert a.dtype is dtype(float)
+ a = arange(3, 7)
+ assert (a == [3, 4, 5, 6]).all()
+ assert a.dtype is dtype(int)
+ a = arange(3, 7, 2)
+ assert (a == [3, 5]).all()
+ a = arange(3, dtype=float)
+ assert (a == [0., 1., 2.]).all()
+ assert a.dtype is dtype(float)
+ a = arange(0, 0.8, 0.1)
+ assert len(a) == 8
+ assert arange(False, True, True).dtype is dtype(int)
\ No newline at end of file
More information about the pypy-commit
mailing list