[pypy-commit] pypy default: update numpy.core._methods from upstream

bdkearns noreply at buildbot.pypy.org
Mon Oct 28 22:07:56 CET 2013


Author: Brian Kearns <bdkearns at gmail.com>
Branch: 
Changeset: r67658:63bfeb2e635e
Date: 2013-10-28 13:43 -0400
http://bitbucket.org/pypy/pypy/changeset/63bfeb2e635e/

Log:	update numpy.core._methods from upstream

diff --git a/lib_pypy/numpypy/core/_methods.py b/lib_pypy/numpypy/core/_methods.py
--- a/lib_pypy/numpypy/core/_methods.py
+++ b/lib_pypy/numpypy/core/_methods.py
@@ -1,9 +1,16 @@
-# Array methods which are called by the both the C-code for the method
-# and the Python code for the NumPy-namespace function
+"""
+Array methods which are called by the both the C-code for the method
+and the Python code for the NumPy-namespace function
 
-import multiarray as mu
-import umath as um
-from numeric import asanyarray
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+from . import multiarray as mu
+from . import umath as um
+from .numeric import asanyarray
+from . import numerictypes as nt
 
 def _amax(a, axis=None, out=None, keepdims=False):
     return um.maximum.reduce(a, axis=axis,
@@ -31,7 +38,7 @@
 
 def _count_reduce_items(arr, axis):
     if axis is None:
-        axis = tuple(xrange(arr.ndim))
+        axis = tuple(range(arr.ndim))
     if not isinstance(axis, tuple):
         axis = (axis,)
     items = 1
@@ -42,58 +49,66 @@
 def _mean(a, axis=None, dtype=None, out=None, keepdims=False):
     arr = asanyarray(a)
 
-    # Upgrade bool, unsigned int, and int to float64
-    if dtype is None and arr.dtype.kind in ['b','u','i']:
-        ret = um.add.reduce(arr, axis=axis, dtype='f8',
-                            out=out, keepdims=keepdims)
+    rcount = _count_reduce_items(arr, axis)
+    # Make this warning show up first
+    if rcount == 0:
+        warnings.warn("Mean of empty slice.", RuntimeWarning)
+
+
+    # Cast bool, unsigned int, and int to float64 by default
+    if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
+        dtype = mu.dtype('f8')
+
+    ret = um.add.reduce(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+    if isinstance(ret, mu.ndarray):
+        ret = um.true_divide(
+                ret, rcount, out=ret, casting='unsafe', subok=False)
     else:
-        ret = um.add.reduce(arr, axis=axis, dtype=dtype,
-                            out=out, keepdims=keepdims)
-    rcount = _count_reduce_items(arr, axis)
-    if isinstance(ret, mu.ndarray):
-        ret = um.true_divide(ret, rcount,
-                        out=ret, casting='unsafe', subok=False)
-    else:
-        ret = ret / float(rcount)
+        ret = ret.dtype.type(ret / rcount)
+
     return ret
 
-def _var(a, axis=None, dtype=None, out=None, ddof=0,
-                            keepdims=False):
+def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
     arr = asanyarray(a)
 
-    # First compute the mean, saving 'rcount' for reuse later
-    if dtype is None and arr.dtype.kind in ['b','u','i']:
-        arrmean = um.add.reduce(arr, axis=axis, dtype='f8', keepdims=True)
+    rcount = _count_reduce_items(arr, axis)
+    # Make this warning show up on top.
+    if ddof >= rcount:
+        warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
+
+    # Cast bool, unsigned int, and int to float64 by default
+    if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
+        dtype = mu.dtype('f8')
+
+    # Compute the mean.
+    # Note that if dtype is not of inexact type then arraymean will
+    # not be either.
+    arrmean = um.add.reduce(arr, axis=axis, dtype=dtype, keepdims=True)
+    if isinstance(arrmean, mu.ndarray):
+        arrmean = um.true_divide(
+                arrmean, rcount, out=arrmean, casting='unsafe', subok=False)
     else:
-        arrmean = um.add.reduce(arr, axis=axis, dtype=dtype, keepdims=True)
-    rcount = _count_reduce_items(arr, axis)
-    if isinstance(arrmean, mu.ndarray):
-        arrmean = um.true_divide(arrmean, rcount,
-                            out=arrmean, casting='unsafe', subok=False)
-    else:
-        arrmean = arrmean / float(rcount)
+        arrmean = arrmean.dtype.type(arrmean / rcount)
 
-    # arr - arrmean
-    x = arr - arrmean
-
-    # (arr - arrmean) ** 2
-    if arr.dtype.kind == 'c':
+    # Compute sum of squared deviations from mean
+    # Note that x may not be inexact and that we need it to be an array,
+    # not a scalar.
+    x = asanyarray(arr - arrmean)
+    if issubclass(arr.dtype.type, nt.complexfloating):
         x = um.multiply(x, um.conjugate(x), out=x).real
     else:
         x = um.multiply(x, x, out=x)
-
-    # add.reduce((arr - arrmean) ** 2, axis)
     ret = um.add.reduce(x, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
 
-    # add.reduce((arr - arrmean) ** 2, axis) / (n - ddof)
-    if not keepdims and isinstance(rcount, mu.ndarray):
-        rcount = rcount.squeeze(axis=axis)
-    rcount -= ddof
+    # Compute degrees of freedom and make sure it is not negative.
+    rcount = max([rcount - ddof, 0])
+
+    # divide by degrees of freedom
     if isinstance(ret, mu.ndarray):
-        ret = um.true_divide(ret, rcount,
-                        out=ret, casting='unsafe', subok=False)
+        ret = um.true_divide(
+                ret, rcount, out=ret, casting='unsafe', subok=False)
     else:
-        ret = ret / float(rcount)
+        ret = ret.dtype.type(ret / rcount)
 
     return ret
 
@@ -104,6 +119,6 @@
     if isinstance(ret, mu.ndarray):
         ret = um.sqrt(ret, out=ret)
     else:
-        ret = um.sqrt(ret)
+        ret = ret.dtype.type(um.sqrt(ret))
 
     return ret
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
@@ -1230,8 +1230,8 @@
         assert (a.mean(2) == array(range(0, 15), dtype=float).reshape(3, 5) * 7 + 3).all()
         assert (arange(10).reshape(5, 2).mean(axis=1) == [0.5, 2.5, 4.5, 6.5, 8.5]).all()
         assert (a.mean(axis=-1) == a.mean(axis=2)).all()
-        raises(ValueError, a.mean, -4)
-        raises(ValueError, a.mean, 3)
+        raises(IndexError, a.mean, -4)
+        raises(IndexError, a.mean, 3)
         a = arange(10).reshape(5, 2)
         assert (a.mean(1) == [0.5, 2.5, 4.5, 6.5, 8.5]).all()
 


More information about the pypy-commit mailing list