Beispiel #1
0
 def reduce(self, space, w_obj, multidim, promote_to_largest, w_axis,
            keepdims=False, out=None):
     from pypy.module.micronumpy.interp_numarray import convert_to_array, \
                                          Scalar, ReduceArray, W_NDimArray
     if self.argcount != 2:
         raise OperationError(space.w_ValueError, space.wrap("reduce only "
             "supported for binary functions"))
     assert isinstance(self, W_Ufunc2)
     obj = convert_to_array(space, w_obj)
     if isinstance(obj, Scalar):
         raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
             "on a scalar"))
     axis = unwrap_axis_arg(space, len(obj.shape), w_axis)    
     assert axis>=0
     size = obj.size
     if self.comparison_func:
         dtype = interp_dtype.get_dtype_cache(space).w_booldtype
     else:
         dtype = find_unaryop_result_dtype(
             space, obj.find_dtype(),
             promote_to_float=self.promote_to_float,
             promote_to_largest=promote_to_largest,
             promote_bools=True
         )
     shapelen = len(obj.shape)
     if self.identity is None and size == 0:
         raise operationerrfmt(space.w_ValueError, "zero-size array to "
                 "%s.reduce without identity", self.name)
     if shapelen > 1 and axis < shapelen:
         if keepdims:
             shape = obj.shape[:axis] + [1] + obj.shape[axis + 1:]
         else:
             shape = obj.shape[:axis] + obj.shape[axis + 1:]
         if out:
             #Test for shape agreement
             if len(out.shape) > len(shape):
                 raise operationerrfmt(space.w_ValueError,
                     'output parameter for reduction operation %s' +
                     ' has too many dimensions', self.name)
             elif len(out.shape) < len(shape):
                 raise operationerrfmt(space.w_ValueError,
                     'output parameter for reduction operation %s' +
                     ' does not have enough dimensions', self.name)
             elif out.shape != shape:
                 raise operationerrfmt(space.w_ValueError,
                     'output parameter shape mismatch, expecting [%s]' +
                     ' , got [%s]',
                     ",".join([str(x) for x in shape]),
                     ",".join([str(x) for x in out.shape]),
                     )
             #Test for dtype agreement, perhaps create an itermediate
             #if out.dtype != dtype:
             #    raise OperationError(space.w_TypeError, space.wrap(
             #        "mismatched  dtypes"))
             return self.do_axis_reduce(obj, out.find_dtype(), axis, out)
         else:
             result = W_NDimArray(shape, dtype)
             return self.do_axis_reduce(obj, dtype, axis, result)
     if out:
         if len(out.shape)>0:
             raise operationerrfmt(space.w_ValueError, "output parameter "
                           "for reduction operation %s has too many"
                           " dimensions",self.name)
         arr = ReduceArray(self.func, self.name, self.identity, obj,
                                                         out.find_dtype())
         val = loop.compute(arr)
         assert isinstance(out, Scalar)
         out.value = val
     else:
         arr = ReduceArray(self.func, self.name, self.identity, obj, dtype)
         val = loop.compute(arr)
     return val
Beispiel #2
0
 def reduce(self, space, w_obj, promote_to_largest, w_axis,
            keepdims=False, out=None, dtype=None, cumulative=False):
     if self.argcount != 2:
         raise OperationError(space.w_ValueError, space.wrap("reduce only "
             "supported for binary functions"))
     assert isinstance(self, W_Ufunc2)
     obj = convert_to_array(space, w_obj)
     if obj.get_dtype().is_flexible_type():
         raise OperationError(space.w_TypeError,
                   space.wrap('cannot perform reduce for flexible type'))
     obj_shape = obj.get_shape()
     if obj.is_scalar():
         return obj.get_scalar_value()
     shapelen = len(obj_shape)
     axis = unwrap_axis_arg(space, shapelen, w_axis)
     assert axis >= 0
     dtype = interp_dtype.decode_w_dtype(space, dtype)
     if dtype is None:
         if self.comparison_func:
             dtype = interp_dtype.get_dtype_cache(space).w_booldtype
         else:
             dtype = find_unaryop_result_dtype(
                 space, obj.get_dtype(),
                 promote_to_float=self.promote_to_float,
                 promote_to_largest=promote_to_largest,
                 promote_bools=True
             )
     if self.identity is None:
         for i in range(shapelen):
             if space.is_none(w_axis) or i == axis:
                 if obj_shape[i] == 0:
                     raise operationerrfmt(space.w_ValueError, "zero-size array to "
                             "%s.reduce without identity", self.name)
     if shapelen > 1 and axis < shapelen:
         temp = None
         if cumulative:
             shape = obj_shape[:]
             temp_shape = obj_shape[:axis] + obj_shape[axis + 1:]
             if out:
                 dtype = out.get_dtype()
             temp = W_NDimArray.from_shape(space, temp_shape, dtype,
                                             w_instance=obj)
         elif keepdims:
             shape = obj_shape[:axis] + [1] + obj_shape[axis + 1:]
         else:
             shape = obj_shape[:axis] + obj_shape[axis + 1:]
         if out:
             # Test for shape agreement
             # XXX maybe we need to do broadcasting here, although I must
             #     say I don't understand the details for axis reduce
             if len(out.get_shape()) > len(shape):
                 raise operationerrfmt(space.w_ValueError,
                     'output parameter for reduction operation %s' +
                     ' has too many dimensions', self.name)
             elif len(out.get_shape()) < len(shape):
                 raise operationerrfmt(space.w_ValueError,
                     'output parameter for reduction operation %s' +
                     ' does not have enough dimensions', self.name)
             elif out.get_shape() != shape:
                 raise operationerrfmt(space.w_ValueError,
                     'output parameter shape mismatch, expecting [%s]' +
                     ' , got [%s]',
                     ",".join([str(x) for x in shape]),
                     ",".join([str(x) for x in out.get_shape()]),
                     )
             dtype = out.get_dtype()
         else:
             out = W_NDimArray.from_shape(space, shape, dtype, w_instance=obj)
         return loop.do_axis_reduce(shape, self.func, obj, dtype, axis, out,
                                    self.identity, cumulative, temp)
     if cumulative:
         if out:
             if out.get_shape() != [obj.get_size()]:
                 raise OperationError(space.w_ValueError, space.wrap(
                     "out of incompatible size"))
         else:
             out = W_NDimArray.from_shape(space, [obj.get_size()], dtype, w_instance=obj)
         loop.compute_reduce_cumulative(obj, out, dtype, self.func,
                                         self.identity)
         return out
     if out:
         if len(out.get_shape())>0:
             raise operationerrfmt(space.w_ValueError, "output parameter "
                           "for reduction operation %s has too many"
                           " dimensions",self.name)
         dtype = out.get_dtype()
     res = loop.compute_reduce(obj, dtype, self.func, self.done_func,
                               self.identity)
     if out:
         out.set_scalar_value(res)
         return out
     return res
Beispiel #3
0
 def reduce(self,
            space,
            w_obj,
            promote_to_largest,
            w_axis,
            keepdims=False,
            out=None,
            dtype=None,
            cumulative=False):
     if self.argcount != 2:
         raise OperationError(
             space.w_ValueError,
             space.wrap("reduce only "
                        "supported for binary functions"))
     assert isinstance(self, W_Ufunc2)
     obj = convert_to_array(space, w_obj)
     if obj.get_dtype().is_flexible_type():
         raise OperationError(
             space.w_TypeError,
             space.wrap('cannot perform reduce for flexible type'))
     obj_shape = obj.get_shape()
     if obj.is_scalar():
         return obj.get_scalar_value()
     shapelen = len(obj_shape)
     axis = unwrap_axis_arg(space, shapelen, w_axis)
     assert axis >= 0
     dtype = interp_dtype.decode_w_dtype(space, dtype)
     if dtype is None:
         if self.comparison_func:
             dtype = interp_dtype.get_dtype_cache(space).w_booldtype
         else:
             dtype = find_unaryop_result_dtype(
                 space,
                 obj.get_dtype(),
                 promote_to_float=self.promote_to_float,
                 promote_to_largest=promote_to_largest,
                 promote_bools=True)
     if self.identity is None:
         for i in range(shapelen):
             if space.is_none(w_axis) or i == axis:
                 if obj_shape[i] == 0:
                     raise operationerrfmt(
                         space.w_ValueError, "zero-size array to "
                         "%s.reduce without identity", self.name)
     if shapelen > 1 and axis < shapelen:
         temp = None
         if cumulative:
             shape = obj_shape[:]
             temp_shape = obj_shape[:axis] + obj_shape[axis + 1:]
             if out:
                 dtype = out.get_dtype()
             temp = W_NDimArray.from_shape(space,
                                           temp_shape,
                                           dtype,
                                           w_instance=obj)
         elif keepdims:
             shape = obj_shape[:axis] + [1] + obj_shape[axis + 1:]
         else:
             shape = obj_shape[:axis] + obj_shape[axis + 1:]
         if out:
             # Test for shape agreement
             # XXX maybe we need to do broadcasting here, although I must
             #     say I don't understand the details for axis reduce
             if len(out.get_shape()) > len(shape):
                 raise operationerrfmt(
                     space.w_ValueError,
                     'output parameter for reduction operation %s' +
                     ' has too many dimensions', self.name)
             elif len(out.get_shape()) < len(shape):
                 raise operationerrfmt(
                     space.w_ValueError,
                     'output parameter for reduction operation %s' +
                     ' does not have enough dimensions', self.name)
             elif out.get_shape() != shape:
                 raise operationerrfmt(
                     space.w_ValueError,
                     'output parameter shape mismatch, expecting [%s]' +
                     ' , got [%s]',
                     ",".join([str(x) for x in shape]),
                     ",".join([str(x) for x in out.get_shape()]),
                 )
             dtype = out.get_dtype()
         else:
             out = W_NDimArray.from_shape(space,
                                          shape,
                                          dtype,
                                          w_instance=obj)
         return loop.do_axis_reduce(shape, self.func, obj, dtype, axis, out,
                                    self.identity, cumulative, temp)
     if cumulative:
         if out:
             if out.get_shape() != [obj.get_size()]:
                 raise OperationError(
                     space.w_ValueError,
                     space.wrap("out of incompatible size"))
         else:
             out = W_NDimArray.from_shape(space, [obj.get_size()],
                                          dtype,
                                          w_instance=obj)
         loop.compute_reduce_cumulative(obj, out, dtype, self.func,
                                        self.identity)
         return out
     if out:
         if len(out.get_shape()) > 0:
             raise operationerrfmt(
                 space.w_ValueError, "output parameter "
                 "for reduction operation %s has too many"
                 " dimensions", self.name)
         dtype = out.get_dtype()
     res = loop.compute_reduce(obj, dtype, self.func, self.done_func,
                               self.identity)
     if out:
         out.set_scalar_value(res)
         return out
     return res