diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ab930af5d3b..b455232f1dce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Updated `pre-commit` GitHub workflow to pass `no-commit-to-branch` check [#2501](https://github.com/IntelPython/dpnp/pull/2501) * Updated the math formulas in summary of `dpnp.matvec` and `dpnp.vecmat` to correct a typo [#2503](https://github.com/IntelPython/dpnp/pull/2503) +* Avoided negating unsigned integers in ceil division used in `dpnp.resize` implementation [#2508](https://github.com/IntelPython/dpnp/pull/2508) ### Security diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index 28ba1a29d50b..19bcfd1e67b3 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -3129,9 +3129,9 @@ def resize(a, new_shape): Returns ------- out : dpnp.ndarray - The new array is formed from the data in the old array, repeated - if necessary to fill out the required number of elements. The - data are repeated iterating over the array in C-order. + The new array is formed from the data in the old array, repeated if + necessary to fill out the required number of elements. The data are + repeated iterating over the array in C-order. See Also -------- @@ -3146,8 +3146,10 @@ def resize(a, new_shape): be used. In most other cases either indexing (to reduce the size) or padding (to increase the size) may be a more appropriate solution. - Warning: This functionality does **not** consider axes separately, - i.e. it does not apply interpolation/extrapolation. + Warning + ------- + This functionality does **not** consider axes separately, i.e. it does not + apply interpolation/extrapolation. It fills the return array with the required number of elements, iterating over `a` in C-order, disregarding axes (and cycling back from the start if the new shape is larger). This functionality is therefore not suitable to @@ -3187,7 +3189,8 @@ def resize(a, new_shape): # First case must zero fill. The second would have repeats == 0. return dpnp.zeros_like(a, shape=new_shape) - repeats = -(-new_size // a_size) # ceil division + # ceiling division without negating new_size + repeats = (new_size + a_size - 1) // a_size a = dpnp.concatenate((dpnp.ravel(a),) * repeats)[:new_size] return a.reshape(new_shape) diff --git a/dpnp/tests/test_manipulation.py b/dpnp/tests/test_manipulation.py index 2950f393451a..30ac6f6c5d2e 100644 --- a/dpnp/tests/test_manipulation.py +++ b/dpnp/tests/test_manipulation.py @@ -1238,6 +1238,16 @@ def test_negative_resize(self, xp): with pytest.raises(ValueError, match=r"negative"): xp.resize(a, new_shape=new_shape) + @testing.with_requires("numpy>=2.3.1") + @pytest.mark.parametrize("dt", [dpnp.uint32, dpnp.uint64]) + def test_unsigned_resize(self, dt): + a = numpy.array([[23, 95], [66, 37]]) + ia = dpnp.array(a) + + result = dpnp.resize(ia, dt(1)) + expected = numpy.resize(a, dt(1)) + assert_array_equal(result, expected) + class TestRot90: @pytest.mark.parametrize("xp", [numpy, dpnp])