[pypy-svn] r71544 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test
electronicru at codespeak.net
electronicru at codespeak.net
Sat Feb 27 20:13:29 CET 2010
Author: electronicru
Date: Sat Feb 27 20:13:27 2010
New Revision: 71544
Modified:
pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py
pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py
pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py
pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py
pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py
Log:
Fixed nonsquare matrices issue, still working around dot() function.
TODO: test operators on multi-dimension arrays.
Modified: pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py (original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py Sat Feb 27 20:13:27 2010
@@ -11,5 +11,6 @@
'ndarray' : 'array.ndarray',
'zeros' : 'array.zeros',
'minimum' : 'ufunc.minimum',
+ 'dot' : 'ufunc.dot',
}
Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py (original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Sat Feb 27 20:13:27 2010
@@ -2,6 +2,7 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.interpreter.gateway import interp2app
from pypy.interpreter.baseobjspace import W_Root
+from pypy.objspace.std.sliceobject import W_SliceObject
from pypy.rlib.debug import make_sure_not_resized
from pypy.module.micronumpy.array import BaseNumArray
@@ -9,6 +10,8 @@
from pypy.module.micronumpy.array import construct_array
from pypy.module.micronumpy.array import array as array_fromseq
from pypy.module.micronumpy.array import validate_index
+from pypy.module.micronumpy.array import \
+ mul_operation, div_operation, add_operation, sub_operation
from pypy.module.micronumpy.dtype import unwrap_int, coerce_int
from pypy.module.micronumpy.dtype import unwrap_float, coerce_float
@@ -17,8 +20,7 @@
def compute_pos(space, indexes, dim):
current = 1
pos = 0
- indexes.reverse()
- for i in range(len(indexes)):
+ for i in range(len(indexes)-1, -1, -1):
index = indexes[i]
d = dim[i]
if index >= d or index <= -d - 1:
@@ -47,7 +49,7 @@
slicelen = i #saved
for i in range(len(slices)):
w_index = slices[i]
- if space.is_true(space.isinstance(w_index, space.w_slice)):
+ if isinstance(w_index, W_SliceObject):
newextract = []
l = shape[i]
stride = strides[i]
@@ -96,17 +98,94 @@
def descr_shape(space, self):
return space.newtuple([space.wrap(dim) for dim in self.shape])
+MUL = mul_operation()
+DIV = div_operation()
+ADD = add_operation()
+SUB = sub_operation()
+
def create_mdarray(data_type, unwrap, coerce):
+
+ def create_math_operation(f):
+ opname = f.__name__
+ def math_operation(self, w_x):
+ space = self.space
+ try:
+ space.iter(w_x)
+ except OperationError, e:
+ if not e.match(space, space.w_TypeError):
+ raise
+ result_t = result_mapping(space,
+ (space.type(w_x), self.dtype))
+ op2 = coerce(space, w_x)
+ result = sdresult(space, result_t)(
+ space, self.len(), result_t
+ )
+ operation = result.__class__.client_scalar[opname]
+ else:
+ op2 = array_fromseq(space, w_x)
+ if len(op2.shape) > len(self.shape):
+ self, op2 = op2, self
+ lss = len(self.shape)
+ ls = len(op2.shape)
+ if not op2.shape == self.shape[lss-ls:lss]:
+ raise OperationError(space.w_ValueError,
+ space.wrap("shape mismatch: objects cannot be"
+ " broadcast to the same shape"))
+ result_t = result_mapping(space, (self.dtype, op2.dtype))
+ result = mdresult(space, result_t)(space, self.shape, result_t)
+ operation = result.__class__.client_fixedview[opname]
+
+ operation(result, self, op2)
+
+ w_result = space.wrap(result)
+ return w_result
+ math_operation.unwrap_spec = ['self', W_Root]
+ math_operation.__name__ = 'descr_'+opname
+ return math_operation
+
+ def create_client_math_operation(f):
+ def scalar_operation(self, source, x):
+ for i in range(len(source.storage)):
+ self.storage[i] = data_type(f(source.storage[i], x))
+
+ def fixedview_operation(self, source1, source2):
+ #Here len(s1.storage)>=len(s2.storage)
+ ll = len(source1.storage)//len(source2.storage)
+ l2 = len(source2.storage)
+ for i in range(ll):
+ for j in range(l2):
+ idx=i*l2+j
+ self.storage[idx] = data_type(f(source1.storage[idx],
+ source2.storage[j]))
+
+ return scalar_operation, fixedview_operation
+
class MultiDimArray(BaseMultiDimArray):
def __init__(self, space, shape, w_dtype):
- self.shape = shape
+ self.shape = make_sure_not_resized(shape)
self.space = space
self.dtype = w_dtype
size = 1
for dimension in shape:
size *= dimension
- self.storage = [data_type(0.0)] * size
- make_sure_not_resized(self.storage)
+ self.storage = make_sure_not_resized([data_type(0.0)] * size)
+
+ client_scalar = {}
+ client_fixedview = {}
+
+ client_scalar['mul'], client_fixedview['mul'] = \
+ create_client_math_operation(MUL)
+ client_scalar['div'], client_fixedview['div'] = \
+ create_client_math_operation(DIV)
+ client_scalar['add'], client_fixedview['add'] = \
+ create_client_math_operation(ADD)
+ client_scalar['sub'], client_fixedview['sub'] = \
+ create_client_math_operation(SUB)
+ descr_mul = create_math_operation(MUL)
+ descr_div = create_math_operation(DIV)
+ descr_add = create_math_operation(ADD)
+ descr_sub = create_math_operation(SUB)
+
def load_iterable(self, w_xs):
self._internal_load(w_xs, self.shape, [])
Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Sat Feb 27 20:13:27 2010
@@ -1,4 +1,5 @@
from pypy.interpreter.baseobjspace import W_Root, Wrappable
+from pypy.objspace.std.sliceobject import W_SliceObject
from pypy.interpreter.error import OperationError
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.interpreter.gateway import interp2app
@@ -30,7 +31,51 @@
def descr_shape(space, self):
return space.newtuple([space.wrap(self.len())])
+
+
+MUL = mul_operation()
+DIV = div_operation()
+ADD = add_operation()
+SUB = sub_operation()
+COPY = copy_operation()
+
def create_sdarray(data_type, unwrap, coerce):
+
+ def create_math_operation(f):
+ opname = f.__name__
+ def math_operation(self, w_x):
+ space = self.space
+ try:
+ space.iter(w_x)
+ except OperationError, e:
+ if not e.match(space, space.w_TypeError):
+ raise
+ result_t = result_mapping(space,
+ (space.type(w_x), self.dtype))
+ op2 = coerce(space, w_x)
+ result = sdresult(space, result_t)(space, self.len(), result_t)
+ operation = result.__class__.client_scalar[opname]
+ else:
+ lop = space.int_w(space.len(w_x))
+ if lop != self.len():
+ raise OperationError(space.w_ValueError,
+ space.wrap("shape mismatch: objects cannot be"
+ " broadcast to the same shape"))
+ dtype = iterable_type(space, w_x)
+ result_t = result_mapping(space, (dtype, self.dtype))
+ op2 = sdresult(space, dtype)(space, lop, dtype)
+ op2.load_iterable(w_x)
+ result = sdresult(space, result_t)(space, self.len(), result_t)
+ operation = result.__class__.client_fixedview[opname]
+
+ operation(result, self, op2)
+
+ w_result = space.wrap(result)
+ return w_result
+ math_operation.unwrap_spec = ['self', W_Root]
+ math_operation.__name__ = 'descr_'+opname
+ return math_operation
+
class SingleDimIterator(Wrappable):
def __init__(self, space, array, i):
self.space = space
@@ -57,12 +102,6 @@
next = interp2app(SingleDimIterator.descr_next)
)
- mul = mul_operation()
- div = div_operation()
- add = add_operation()
- sub = sub_operation()
- copy = copy_operation()
-
def create_client_math_operation(f):
def scalar_operation(self, source, x):
for i in range(len(source.storage)):
@@ -74,78 +113,31 @@
data_type(f(source1.storage[i], source2.storage[i]))
return scalar_operation, fixedview_operation
- def create_math_operation(f):
- opname = f.__name__
- def math_operation(self, w_x):
- space = self.space
- try:
- space.iter(w_x)
- except OperationError, e:
- if not e.match(space, space.w_TypeError):
- raise
- result_t = result_mapping(space,
- (space.type(w_x), self.dtype))
- op2 = coerce(space, w_x)
- result = sdresult(space, result_t)(
- space, self.len(), result_t
- )
- operation = result.__class__.client_scalar[opname]
- else:
- lop = space.int_w(space.len(w_x))
- if lop != self.len():
- raise OperationError(space.w_ValueError,
- space.wrap("shape mismatch: objects cannot be"
- " broadcast to the same shape"))
- dtype = iterable_type(space, w_x)
- result_t = result_mapping(space, (dtype, self.dtype))
- op2 = sdresult(space, dtype)(space, lop, dtype)
- op2.load_iterable(w_x)
- result = sdresult(space, result_t)(
- space, self.len(), result_t
- )
- operation = result.__class__.client_fixedview[opname]
-
- operation(result, self, op2)
-
- w_result = space.wrap(result)
- return w_result
- math_operation.unwrap_spec = ['self', W_Root]
- return math_operation
-
-
class NumArray(BaseSingleDimArray):
def __init__(self, space, length, dtype):
self.shape = (length,)
self.space = space
- self.storage = [data_type(0.0)] * length
+ self.storage = make_sure_not_resized([data_type(0.0)] * length)
self.dtype = dtype
- make_sure_not_resized(self.storage)
client_scalar = {}
client_fixedview = {}
client_scalar['mul'], client_fixedview['mul'] = \
- create_client_math_operation(mul)
+ create_client_math_operation(MUL)
client_scalar['div'], client_fixedview['div'] = \
- create_client_math_operation(div)
+ create_client_math_operation(DIV)
client_scalar['add'], client_fixedview['add'] = \
- create_client_math_operation(add)
+ create_client_math_operation(ADD)
client_scalar['sub'], client_fixedview['sub'] = \
- create_client_math_operation(sub)
-
-
- descr_mul = create_math_operation(mul)
- descr_mul.__name__ = 'descr_mul'
-
- descr_div = create_math_operation(div)
- descr_div.__name__ = 'descr_div'
+ create_client_math_operation(SUB)
- descr_add = create_math_operation(add)
- descr_add.__name__ = 'descr_add'
- descr_sub = create_math_operation(sub)
- descr_sub.__name__ = 'descr_sub'
+ descr_mul = create_math_operation(MUL)
+ descr_div = create_math_operation(DIV)
+ descr_add = create_math_operation(ADD)
+ descr_sub = create_math_operation(SUB)
def load_iterable(self, w_values):
space = self.space
@@ -160,7 +152,7 @@
def descr_getitem(self, w_index):
space = self.space
- if space.is_true(space.isinstance(w_index, space.w_slice)):
+ if isinstance(w_index, W_SliceObject):
start, stop, step, slen = w_index.indices4(space, self.len())
res = sdresult(space, self.dtype)(space, slen, self.dtype)
if step == 1:
@@ -185,7 +177,7 @@
def descr_setitem(self, w_index, w_value):
space = self.space
- if space.is_true(space.isinstance(w_index, space.w_slice)):
+ if isinstance(w_index, W_SliceObject):
start, stop, step, slen = w_index.indices4(space, self.len())
try:
space.iter(w_value)
Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Sat Feb 27 20:13:27 2010
@@ -27,7 +27,7 @@
from numpy import array
from operator import mul, div, add, sub
d = range(1, self.length)
- #FIXME: overkill...
+ #skip('overkill...')
for data_type in (int, float):
data = [data_type(x) for x in d]
ar = array(data)
@@ -40,7 +40,6 @@
assert compare(operator(ar, ar2), [operator(x, y) for (x, y) in zip(ar, ar2)])
def test_operator_result_types(self):
- #skip("Haven't implemented dispatching for array/array operations")
from operator import mul, div, add, sub
from numpy import array
types = {
@@ -163,7 +162,6 @@
ar = array(gen_array((3,3)))
assert len(ar) == 3
- skip("Non-square matrices throw IndexError")
#2x3
ar = array(gen_array((2,3)))
assert len(ar) == 2
Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py (original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py Sat Feb 27 20:13:27 2010
@@ -1,6 +1,11 @@
-from pypy.module.micronumpy.array import array, zeros, ndarray
+from pypy.module.micronumpy.array import array, zeros, ndarray
+from pypy.module.micronumpy.array import construct_array
+from pypy.module.micronumpy.dtype import result_mapping
+from pypy.module.micronumpy.sdarray import sdresult
+from pypy.module.micronumpy.mdarray import mdresult, compute_pos
from pypy.interpreter.baseobjspace import ObjSpace, W_Root
from pypy.interpreter.error import OperationError
+from pypy.rlib.debug import make_sure_not_resized
def minimum(space, w_a, w_b):
if not isinstance(w_a, ndarray) or not isinstance(w_b, ndarray):
@@ -9,7 +14,8 @@
if w_a.len()!= w_b.len():
raise OperationError(space.w_ValueError,
space.wrap("minimum of arrays of different length"))
- res = zeros(space, space.wrap(w_a.len()), w_a.dtype)
+ dtype = result_mapping(space, (w_a.dtype, w_b.dtype))
+ res = construct_array(space, w_a.shape, dtype)
for i in range(len(w_a.storage)):
one = w_a.storage[i]
two = w_b.storage[i]
@@ -19,3 +25,89 @@
res.storage[i] = two
return space.wrap(res)
minimum.unwrap_spec = [ObjSpace, W_Root, W_Root]
+
+def dot(space, w_a, w_b):
+ if not isinstance(w_a, ndarray) or not isinstance(w_b, ndarray):
+ raise OperationError(space.w_TypeError,
+ space.wrap("expecting ndarray object"))
+
+ if len(w_b.shape) == 1:
+ the_b = mdresult(space, w_b.dtype)(space, [w_b.shape[0], 1], w_b.dtype)
+ the_b.storage[:] = w_b.storage
+ w_b = the_b
+
+ if len(w_a.shape)%2:
+ the_a = mdresult(space, w_a.dtype)(space, [1]+w_a.shape, w_a.dtype)
+ the_a.storage[:] = w_a.storage
+ w_a = the_a
+ ah, aw = w_a.shape[0], w_a.shape[1]
+ als = len(w_a.shape)
+
+ if len(w_b.shape)%2:
+ the_b = mdresult(space, w_b.dtype)(space, [1]+w_b.shape, w_b.dtype)
+ the_b.storage[:] = w_b.storage
+ w_b = the_b
+ bh, bw = w_a.shape[0], w_a.shape[1]
+ bls = len(w_b.shape)
+
+
+ if aw == bh == 1:
+ return dot(space, w_b, w_a)
+
+ shapemismatch = OperationError(space.w_TypeError,
+ space.wrap('shape mismatch'))
+
+ if aw != bh:
+ raise shapemismatch
+
+ if als != bls:
+ raise shapemismatch
+
+
+ data = _dotit(space, w_a, w_b, als, [], [])
+ if len(data) == 1:
+ return space.wrap(data[0])
+ shape = make_sure_not_resized([0]*als)
+ for i in range(0, als, 2):
+ shape[i] = w_a.shape[i]
+ shape[i+1] = w_b.shape[i+1]
+
+ dtype = result_mapping(space, (w_a.dtype, w_b.dtype))
+
+ res = construct_array(space, shape, dtype)
+ res.storage[:] = data
+ return space.wrap(res)
+dot.unwrap_spec = [ObjSpace, W_Root, W_Root]
+
+def _dotit(space, w_a, w_b, ls, indices1, indices2):
+ if len(indices1) == ls:
+ return w_a.storage[compute_pos(indices1)] * \
+ w_b.storage[compute_pos(indices2)]
+ else:
+ shift = len(indices1)
+ h = w_a.shape[shift]
+ w = w_b.shape[shift+1]
+ l = w_a.shape[shift+1]
+ if l != w_b.shape[shift]:
+ raise shapemismatch
+ total = []
+ for i in range(h):
+ for j in range(w):
+ #check if numbers on next level
+ if shift+2 == als:
+ sum = 0
+ for k in range(l):
+ sum += _dotit(indices1+[i, l], indices2+[l, j])
+ total.append(sum)
+ else:
+ sum = None
+ for k in range(l):
+ arg = _dotit(indices1+[i, l], indices2+[l, j])
+ if sum == None:
+ sum = arg
+ else:
+ for idx in range(len(sum)):
+ sum[idx] += arg[idx]
+ total.extend(sum)
+
+ return make_sure_not_resized(total)
More information about the Pypy-commit
mailing list