Skip to content

Commit f135e01

Browse files
authored
Merge branch 'master' into dependabot/github_actions/github/codeql-action-3.27.4
2 parents c141731 + acb5d25 commit f135e01

File tree

7 files changed

+317
-192
lines changed

7 files changed

+317
-192
lines changed

dpnp/dpnp_iface_functional.py

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@
3838

3939

4040
import numpy
41-
from dpctl.tensor._numpy_helper import normalize_axis_index
41+
from dpctl.tensor._numpy_helper import (
42+
normalize_axis_index,
43+
normalize_axis_tuple,
44+
)
4245

4346
import dpnp
4447

45-
__all__ = ["apply_along_axis"]
48+
__all__ = ["apply_along_axis", "apply_over_axes"]
4649

4750

4851
def apply_along_axis(func1d, axis, arr, *args, **kwargs):
@@ -185,3 +188,83 @@ def apply_along_axis(func1d, axis, arr, *args, **kwargs):
185188
buff = dpnp.moveaxis(buff, -1, axis)
186189

187190
return buff
191+
192+
193+
def apply_over_axes(func, a, axes):
194+
"""
195+
Apply a function repeatedly over multiple axes.
196+
197+
`func` is called as ``res = func(a, axis)``, where `axis` is the first
198+
element of `axes`. The result `res` of the function call must have
199+
either the same dimensions as `a` or one less dimension. If `res`
200+
has one less dimension than `a`, a dimension is inserted before
201+
`axis`. The call to `func` is then repeated for each axis in `axes`,
202+
with `res` as the first argument.
203+
204+
For full documentation refer to :obj:`numpy.apply_over_axes`.
205+
206+
Parameters
207+
----------
208+
func : function
209+
This function must take two arguments, ``func(a, axis)``.
210+
a : {dpnp.ndarray, usm_ndarray}
211+
Input array.
212+
axes : {int, sequence of ints}
213+
Axes over which `func` is applied.
214+
215+
Returns
216+
-------
217+
out : dpnp.ndarray
218+
The output array. The number of dimensions is the same as `a`,
219+
but the shape can be different. This depends on whether `func`
220+
changes the shape of its output with respect to its input.
221+
222+
See Also
223+
--------
224+
:obj:`dpnp.apply_along_axis` : Apply a function to 1-D slices of an array
225+
along the given axis.
226+
227+
Examples
228+
--------
229+
>>> import dpnp as np
230+
>>> a = np.arange(24).reshape(2, 3, 4)
231+
>>> a
232+
array([[[ 0, 1, 2, 3],
233+
[ 4, 5, 6, 7],
234+
[ 8, 9, 10, 11]],
235+
[[12, 13, 14, 15],
236+
[16, 17, 18, 19],
237+
[20, 21, 22, 23]]])
238+
239+
Sum over axes 0 and 2. The result has same number of dimensions
240+
as the original array:
241+
242+
>>> np.apply_over_axes(np.sum, a, [0, 2])
243+
array([[[ 60],
244+
[ 92],
245+
[124]]])
246+
247+
Tuple axis arguments to ufuncs are equivalent:
248+
249+
>>> np.sum(a, axis=(0, 2), keepdims=True)
250+
array([[[ 60],
251+
[ 92],
252+
[124]]])
253+
254+
"""
255+
256+
dpnp.check_supported_arrays_type(a)
257+
if isinstance(axes, int):
258+
axes = (axes,)
259+
axes = normalize_axis_tuple(axes, a.ndim)
260+
261+
for axis in axes:
262+
res = func(a, axis)
263+
if res.ndim != a.ndim:
264+
res = dpnp.expand_dims(res, axis)
265+
if res.ndim != a.ndim:
266+
raise ValueError(
267+
"function is not returning an array of the correct shape"
268+
)
269+
a = res
270+
return res

dpnp/dpnp_iface_manipulation.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3848,13 +3848,14 @@ def transpose(a, axes=None):
38483848
----------
38493849
a : {dpnp.ndarray, usm_ndarray}
38503850
Input array.
3851-
axes : None, tuple or list of ints, optional
3851+
axes : {None, tuple or list of ints}, optional
38523852
If specified, it must be a tuple or list which contains a permutation
38533853
of [0, 1, ..., N-1] where N is the number of axes of `a`.
38543854
The `i`'th axis of the returned array will correspond to the axis
38553855
numbered ``axes[i]`` of the input. If not specified or ``None``,
38563856
defaults to ``range(a.ndim)[::-1]``, which reverses the order of
38573857
the axes.
3858+
Default: ``None``.
38583859
38593860
Returns
38603861
-------
@@ -3894,18 +3895,13 @@ def transpose(a, axes=None):
38943895
38953896
"""
38963897

3897-
if isinstance(a, dpnp_array):
3898-
array = a
3899-
elif isinstance(a, dpt.usm_ndarray):
3900-
array = dpnp_array._create_from_usm_ndarray(a)
3901-
else:
3902-
raise TypeError(
3903-
f"An array must be any of supported type, but got {type(a)}"
3904-
)
3898+
dpnp.check_supported_arrays_type(a)
3899+
if isinstance(a, dpt.usm_ndarray):
3900+
a = dpnp_array._create_from_usm_ndarray(a)
39053901

39063902
if axes is None:
3907-
return array.transpose()
3908-
return array.transpose(*axes)
3903+
return a.transpose()
3904+
return a.transpose(*axes)
39093905

39103906

39113907
permute_dims = transpose # permute_dims is an alias for transpose

0 commit comments

Comments
 (0)