From 0fea57e2c3c890b63c91325f9f9ce07ead74b745 Mon Sep 17 00:00:00 2001 From: Warren Weckesser Date: Tue, 31 Dec 2019 09:57:58 -0500 Subject: BUG: lib: Fix handling of integer arrays by gradient. In numpy.gradient, convert integer array inputs to float64 to avoid unwanted modular arithmetic. Closes gh-15207. --- numpy/lib/function_base.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'numpy/lib/function_base.py') diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index c2680b016..4c3de4df9 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -974,13 +974,18 @@ def gradient(f, *varargs, **kwargs): # scalar or 1d array for each axis dx = list(varargs) for i, distances in enumerate(dx): - if np.ndim(distances) == 0: + distances = np.asanyarray(distances) + if distances.ndim == 0: continue - elif np.ndim(distances) != 1: + elif distances.ndim != 1: raise ValueError("distances must be either scalars or 1d") if len(distances) != f.shape[axes[i]]: raise ValueError("when 1d, distances must match " "the length of the corresponding dimension") + if np.issubdtype(distances.dtype, np.integer): + # Convert numpy integer types to float64 to avoid modular + # arithmetic in np.diff(distances). + distances = distances.astype(np.float64) diffx = np.diff(distances) # if distances are constant reduce to the scalar case # since it brings a consistent speedup @@ -1019,8 +1024,12 @@ def gradient(f, *varargs, **kwargs): elif np.issubdtype(otype, np.inexact): pass else: - # all other types convert to floating point - otype = np.double + # All other types convert to floating point. + # First check if f is a numpy integer type; if so, convert f to float64 + # to avoid modular arithmetic when computing the changes in f. + if np.issubdtype(otype, np.integer): + f = f.astype(np.float64) + otype = np.float64 for axis, ax_dx in zip(axes, dx): if f.shape[axis] < edge_order + 1: -- cgit v1.2.1 From ed1e9659f103260a32536b4a7615393e3b1173dc Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Tue, 27 Aug 2019 04:36:38 -0700 Subject: MAINT: Remove unnecessary 'from __future__ import ...' statements As numpy is Python 3 only, these import statements are now unnecessary and don't alter runtime behavior. --- numpy/lib/function_base.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'numpy/lib/function_base.py') diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index 4c3de4df9..3b0a6783b 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -1,5 +1,3 @@ -from __future__ import division, absolute_import, print_function - try: # Accessing collections abstract classes from collections # has been deprecated since Python 3.3 -- cgit v1.2.1 From c31cc36a8a814ed4844a2a553454185601914a5a Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sun, 5 Jan 2020 00:53:30 -0500 Subject: MAINT: Remove implicit inheritance from object class (#15236) Inheriting from object was necessary for Python 2 compatibility to use new-style classes. In Python 3, this is unnecessary as there are no old-style classes. Dropping the object is more idiomatic Python. --- numpy/lib/function_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/lib/function_base.py') diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index 3b0a6783b..6c7dfbfd3 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -1870,7 +1870,7 @@ def _create_arrays(broadcast_shape, dim_sizes, list_of_core_dims, dtypes): @set_module('numpy') -class vectorize(object): +class vectorize: """ vectorize(pyfunc, otypes=None, doc=None, excluded=None, cache=False, signature=None) -- cgit v1.2.1