diff --git a/doc/release/upcoming_changes/24445.deprecation.rst b/doc/release/upcoming_changes/24445.deprecation.rst index 2a1c8b3de14e..a2fb01a424cb 100644 --- a/doc/release/upcoming_changes/24445.deprecation.rst +++ b/doc/release/upcoming_changes/24445.deprecation.rst @@ -1,4 +1,4 @@ -* ``np.trapz`` has been deprecated. Use ``scipy.interpolate.trapezoid`` instead. +* ``np.trapz`` has been deprecated. Use ``np.trapezoid`` or a ``scipy.integrate`` function instead. * ``np.in1d`` has been deprecated. Use ``np.isin`` instead. diff --git a/doc/source/numpy_2_0_migration_guide.rst b/doc/source/numpy_2_0_migration_guide.rst index c29393f25b46..95f455a22765 100644 --- a/doc/source/numpy_2_0_migration_guide.rst +++ b/doc/source/numpy_2_0_migration_guide.rst @@ -201,7 +201,7 @@ deprecated member migration guideline ================= ======================================================================= in1d Use ``np.isin`` instead. row_stack Use ``np.vstack`` instead (``row_stack`` was an alias for ``vstack``). -trapz Use ``scipy.integrate.trapezoid`` instead. +trapz Use ``np.trapezoid`` or a ``scipy.integrate`` function instead. ================= ======================================================================= diff --git a/numpy/__init__.py b/numpy/__init__.py index 42addfed4c10..cbc5f49cd758 100644 --- a/numpy/__init__.py +++ b/numpy/__init__.py @@ -193,7 +193,8 @@ gradient, angle, unwrap, sort_complex, flip, rot90, extract, place, vectorize, asarray_chkfinite, average, bincount, digitize, cov, corrcoef, median, sinc, hamming, hanning, bartlett, blackman, - kaiser, trapz, i0, meshgrid, delete, insert, append, interp, quantile + kaiser, trapezoid, trapz, i0, meshgrid, delete, insert, append, + interp, quantile ) from .lib._twodim_base_impl import ( diag, diagflat, eye, fliplr, flipud, tri, triu, tril, vander, diff --git a/numpy/lib/_function_base_impl.py b/numpy/lib/_function_base_impl.py index 7013ada34bef..f51c0ccef6e0 100644 --- a/numpy/lib/_function_base_impl.py +++ b/numpy/lib/_function_base_impl.py @@ -42,7 +42,7 @@ 'rot90', 'extract', 'place', 'vectorize', 'asarray_chkfinite', 'average', 'bincount', 'digitize', 'cov', 'corrcoef', 'median', 'sinc', 'hamming', 'hanning', 'bartlett', - 'blackman', 'kaiser', 'trapz', 'i0', + 'blackman', 'kaiser', 'trapezoid', 'trapz', 'i0', 'meshgrid', 'delete', 'insert', 'append', 'interp', 'quantile' ] @@ -5019,18 +5019,15 @@ def find_cdf_1d(arr, cdf): return result -def _trapz_dispatcher(y, x=None, dx=None, axis=None): +def _trapezoid_dispatcher(y, x=None, dx=None, axis=None): return (y, x) -@array_function_dispatch(_trapz_dispatcher) -def trapz(y, x=None, dx=1.0, axis=-1): +@array_function_dispatch(_trapezoid_dispatcher) +def trapezoid(y, x=None, dx=1.0, axis=-1): r""" Integrate along the given axis using the composite trapezoidal rule. - .. deprecated:: 2.0 - Use `scipy.integrate.trapezoid` instead. - If `x` is provided, the integration happens in sequence along its elements - they are not sorted. @@ -5040,6 +5037,8 @@ def trapz(y, x=None, dx=1.0, axis=-1): computing :math:`\int_t y(t) dt = \int_t y(t) \left.\frac{dx}{dt}\right|_{x=x(t)} dt`. + .. versionadded:: 2.0.0 + Parameters ---------- y : array_like @@ -5055,7 +5054,7 @@ def trapz(y, x=None, dx=1.0, axis=-1): Returns ------- - trapz : float or ndarray + trapezoid : float or ndarray Definite integral of `y` = n-dimensional array as approximated along a single axis by the trapezoidal rule. If `y` is a 1-dimensional array, then the result is a float. If `n` is greater than 1, then the result @@ -5085,20 +5084,20 @@ def trapz(y, x=None, dx=1.0, axis=-1): -------- Use the trapezoidal rule on evenly spaced points: - >>> np.trapz([1, 2, 3]) + >>> np.trapezoid([1, 2, 3]) 4.0 The spacing between sample points can be selected by either the ``x`` or ``dx`` arguments: - >>> np.trapz([1, 2, 3], x=[4, 6, 8]) + >>> np.trapezoid([1, 2, 3], x=[4, 6, 8]) 8.0 - >>> np.trapz([1, 2, 3], dx=2) + >>> np.trapezoid([1, 2, 3], dx=2) 8.0 Using a decreasing ``x`` corresponds to integrating in reverse: - >>> np.trapz([1, 2, 3], x=[8, 6, 4]) + >>> np.trapezoid([1, 2, 3], x=[8, 6, 4]) -8.0 More generally ``x`` is used to integrate along a parametric curve. We can @@ -5106,36 +5105,29 @@ def trapz(y, x=None, dx=1.0, axis=-1): >>> x = np.linspace(0, 1, num=50) >>> y = x**2 - >>> np.trapz(y, x) + >>> np.trapezoid(y, x) 0.33340274885464394 Or estimate the area of a circle, noting we repeat the sample which closes the curve: >>> theta = np.linspace(0, 2 * np.pi, num=1000, endpoint=True) - >>> np.trapz(np.cos(theta), x=np.sin(theta)) + >>> np.trapezoid(np.cos(theta), x=np.sin(theta)) 3.141571941375841 - ``np.trapz`` can be applied along a specified axis to do multiple + ``np.trapezoid`` can be applied along a specified axis to do multiple computations in one call: >>> a = np.arange(6).reshape(2, 3) >>> a array([[0, 1, 2], [3, 4, 5]]) - >>> np.trapz(a, axis=0) + >>> np.trapezoid(a, axis=0) array([1.5, 2.5, 3.5]) - >>> np.trapz(a, axis=1) + >>> np.trapezoid(a, axis=1) array([2., 8.]) """ - # Deprecated in NumPy 2.0, 2023-08-18 - warnings.warn( - "`trapz` is deprecated. Use `scipy.integrate.trapezoid` instead.", - DeprecationWarning, - stacklevel=2 - ) - y = asanyarray(y) if x is None: d = dx @@ -5164,22 +5156,22 @@ def trapz(y, x=None, dx=1.0, axis=-1): return ret -# __array_function__ has no __code__ or other attributes normal Python funcs we -# wrap everything into a C callable. SciPy however, tries to "clone" `trapz` -# into a new Python function which requires `__code__` and a few other -# attributes. So we create a dummy clone and copy over its attributes allowing -# SciPy <= 1.10 to work: https://github.com/scipy/scipy/issues/17811 -assert not hasattr(trapz, "__code__") - -def _fake_trapz(y, x=None, dx=1.0, axis=-1): - return trapz(y, x=x, dx=dx, axis=axis) - +@set_module('numpy') +def trapz(y, x=None, dx=1.0, axis=-1): + """ + `trapz` is deprecated in NumPy 2.0. -trapz.__code__ = _fake_trapz.__code__ -trapz.__globals__ = _fake_trapz.__globals__ -trapz.__defaults__ = _fake_trapz.__defaults__ -trapz.__closure__ = _fake_trapz.__closure__ -trapz.__kwdefaults__ = _fake_trapz.__kwdefaults__ + Please use `trapezoid` instead, or one of the numerical integration + functions in `scipy.integrate`. + """ + # Deprecated in NumPy 2.0, 2023-08-18 + warnings.warn( + "`trapz` is deprecated. Use `trapezoid` instead, or one of the " + "numerical integration functions in `scipy.integrate`.", + DeprecationWarning, + stacklevel=2 + ) + return trapezoid(y, x=x, dx=dx, axis=axis) def _meshgrid_dispatcher(*xi, copy=None, sparse=None, indexing=None): diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index 4ce2f251ac5b..826a4bbd4833 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -15,7 +15,7 @@ ma, angle, average, bartlett, blackman, corrcoef, cov, delete, diff, digitize, extract, flipud, gradient, hamming, hanning, i0, insert, interp, kaiser, meshgrid, piecewise, place, rot90, - select, setxor1d, sinc, trapz, trim_zeros, unwrap, unique, vectorize + select, setxor1d, sinc, trapezoid, trim_zeros, unwrap, unique, vectorize ) from numpy.exceptions import AxisError from numpy.testing import ( @@ -2167,12 +2167,11 @@ def test_kaiser(self, dtype: str, M: int) -> None: assert_almost_equal(np.sum(w, axis=0), 10, 15) -@pytest.mark.filterwarnings('ignore:.*trapz.*:DeprecationWarning') -class TestTrapz: +class TestTrapezoid: def test_simple(self): x = np.arange(-10, 10, .1) - r = trapz(np.exp(-.5 * x ** 2) / np.sqrt(2 * np.pi), dx=0.1) + r = trapezoid(np.exp(-.5 * x ** 2) / np.sqrt(2 * np.pi), dx=0.1) # check integral of normal equals 1 assert_almost_equal(r, 1, 7) @@ -2198,19 +2197,19 @@ def test_ndim(self): qz = (q * wz[None, None, :]).sum(axis=2) # n-d `x` - r = trapz(q, x=x[:, None, None], axis=0) + r = trapezoid(q, x=x[:, None, None], axis=0) assert_almost_equal(r, qx) - r = trapz(q, x=y[None,:, None], axis=1) + r = trapezoid(q, x=y[None, :, None], axis=1) assert_almost_equal(r, qy) - r = trapz(q, x=z[None, None,:], axis=2) + r = trapezoid(q, x=z[None, None, :], axis=2) assert_almost_equal(r, qz) # 1-d `x` - r = trapz(q, x=x, axis=0) + r = trapezoid(q, x=x, axis=0) assert_almost_equal(r, qx) - r = trapz(q, x=y, axis=1) + r = trapezoid(q, x=y, axis=1) assert_almost_equal(r, qy) - r = trapz(q, x=z, axis=2) + r = trapezoid(q, x=z, axis=2) assert_almost_equal(r, qz) def test_masked(self): @@ -2221,13 +2220,13 @@ def test_masked(self): mask = x == 2 ym = np.ma.array(y, mask=mask) r = 13.0 # sum(0.5 * (0 + 1) * 1.0 + 0.5 * (9 + 16)) - assert_almost_equal(trapz(ym, x), r) + assert_almost_equal(trapezoid(ym, x), r) xm = np.ma.array(x, mask=mask) - assert_almost_equal(trapz(ym, xm), r) + assert_almost_equal(trapezoid(ym, xm), r) xm = np.ma.array(x, mask=mask) - assert_almost_equal(trapz(y, xm), r) + assert_almost_equal(trapezoid(y, xm), r) class TestSinc: