3939
4040
4141import math
42+ import operator
4243
4344import dpctl .tensor as dpt
4445import numpy
7778 "ravel" ,
7879 "repeat" ,
7980 "reshape" ,
81+ "resize" ,
8082 "result_type" ,
8183 "roll" ,
8284 "rollaxis" ,
85+ "rot90" ,
8386 "row_stack" ,
8487 "shape" ,
8588 "size" ,
@@ -1522,6 +1525,7 @@ def fliplr(m):
15221525 --------
15231526 :obj:`dpnp.flipud` : Flip an array vertically (axis=0).
15241527 :obj:`dpnp.flip` : Flip array in one or more dimensions.
1528+ :obj:`dpnp.rot90` : Rotate array counterclockwise.
15251529
15261530 Examples
15271531 --------
@@ -1572,6 +1576,7 @@ def flipud(m):
15721576 --------
15731577 :obj:`dpnp.fliplr` : Flip array in the left/right direction.
15741578 :obj:`dpnp.flip` : Flip array in one or more dimensions.
1579+ :obj:`dpnp.rot90` : Rotate array counterclockwise.
15751580
15761581 Examples
15771582 --------
@@ -1985,7 +1990,8 @@ def reshape(a, /, newshape, order="C", copy=None):
19851990 If ``False``, the result array can never be a copy
19861991 and a ValueError exception will be raised in case the copy is necessary.
19871992 If ``None``, the result array will reuse existing memory buffer of `a`
1988- if possible and copy otherwise. Default: None.
1993+ if possible and copy otherwise.
1994+ Default: ``None``.
19891995
19901996 Returns
19911997 -------
@@ -2004,14 +2010,14 @@ def reshape(a, /, newshape, order="C", copy=None):
20042010
20052011 Examples
20062012 --------
2007- >>> import dpnp as dp
2008- >>> a = dp .array([[1, 2, 3], [4, 5, 6]])
2009- >>> dp .reshape(a, 6)
2013+ >>> import dpnp as np
2014+ >>> a = np .array([[1, 2, 3], [4, 5, 6]])
2015+ >>> np .reshape(a, 6)
20102016 array([1, 2, 3, 4, 5, 6])
2011- >>> dp .reshape(a, 6, order='F')
2017+ >>> np .reshape(a, 6, order='F')
20122018 array([1, 4, 2, 5, 3, 6])
20132019
2014- >>> dp .reshape(a, (3, -1)) # the unspecified value is inferred to be 2
2020+ >>> np .reshape(a, (3, -1)) # the unspecified value is inferred to be 2
20152021 array([[1, 2],
20162022 [3, 4],
20172023 [5, 6]])
@@ -2031,6 +2037,91 @@ def reshape(a, /, newshape, order="C", copy=None):
20312037 return dpnp_array ._create_from_usm_ndarray (usm_res )
20322038
20332039
2040+ def resize (a , new_shape ):
2041+ """
2042+ Return a new array with the specified shape.
2043+
2044+ If the new array is larger than the original array, then the new array is
2045+ filled with repeated copies of `a`. Note that this behavior is different
2046+ from ``a.resize(new_shape)`` which fills with zeros instead of repeated
2047+ copies of `a`.
2048+
2049+ For full documentation refer to :obj:`numpy.resize`.
2050+
2051+ Parameters
2052+ ----------
2053+ a : {dpnp.ndarray, usm_ndarray}
2054+ Array to be resized.
2055+ new_shape : {int, tuple or list of ints}
2056+ Shape of resized array.
2057+
2058+ Returns
2059+ -------
2060+ out : dpnp.ndarray
2061+ The new array is formed from the data in the old array, repeated
2062+ if necessary to fill out the required number of elements. The
2063+ data are repeated iterating over the array in C-order.
2064+
2065+ See Also
2066+ --------
2067+ :obj:`dpnp.ndarray.resize` : Resize an array in-place.
2068+ :obj:`dpnp.reshape` : Reshape an array without changing the total size.
2069+ :obj:`dpnp.pad` : Enlarge and pad an array.
2070+ :obj:`dpnp.repeat` : Repeat elements of an array.
2071+
2072+ Notes
2073+ -----
2074+ When the total size of the array does not change :obj:`dpnp.reshape` should
2075+ be used. In most other cases either indexing (to reduce the size) or
2076+ padding (to increase the size) may be a more appropriate solution.
2077+
2078+ Warning: This functionality does **not** consider axes separately,
2079+ i.e. it does not apply interpolation/extrapolation.
2080+ It fills the return array with the required number of elements, iterating
2081+ over `a` in C-order, disregarding axes (and cycling back from the start if
2082+ the new shape is larger). This functionality is therefore not suitable to
2083+ resize images, or data where each axis represents a separate and distinct
2084+ entity.
2085+
2086+ Examples
2087+ --------
2088+ >>> import dpnp as np
2089+ >>> a = np.array([[0, 1], [2, 3]])
2090+ >>> np.resize(a, (2, 3))
2091+ array([[0, 1, 2],
2092+ [3, 0, 1]])
2093+ >>> np.resize(a, (1, 4))
2094+ array([[0, 1, 2, 3]])
2095+ >>> np.resize(a, (2, 4))
2096+ array([[0, 1, 2, 3],
2097+ [0, 1, 2, 3]])
2098+
2099+ """
2100+
2101+ dpnp .check_supported_arrays_type (a )
2102+ if a .ndim == 0 :
2103+ return dpnp .full_like (a , a , shape = new_shape )
2104+
2105+ if isinstance (new_shape , (int , numpy .integer )):
2106+ new_shape = (new_shape ,)
2107+
2108+ new_size = 1
2109+ for dim_length in new_shape :
2110+ if dim_length < 0 :
2111+ raise ValueError ("all elements of `new_shape` must be non-negative" )
2112+ new_size *= dim_length
2113+
2114+ a_size = a .size
2115+ if a_size == 0 or new_size == 0 :
2116+ # First case must zero fill. The second would have repeats == 0.
2117+ return dpnp .zeros_like (a , shape = new_shape )
2118+
2119+ repeats = - (- new_size // a_size ) # ceil division
2120+ a = dpnp .concatenate ((dpnp .ravel (a ),) * repeats )[:new_size ]
2121+
2122+ return a .reshape (new_shape )
2123+
2124+
20342125def result_type (* arrays_and_dtypes ):
20352126 """
20362127 result_type(*arrays_and_dtypes)
@@ -2052,16 +2143,16 @@ def result_type(*arrays_and_dtypes):
20522143
20532144 Examples
20542145 --------
2055- >>> import dpnp as dp
2056- >>> a = dp .arange(3, dtype=dp .int64)
2057- >>> b = dp .arange(7, dtype=dp .int32)
2058- >>> dp .result_type(a, b)
2146+ >>> import dpnp as np
2147+ >>> a = np .arange(3, dtype=np .int64)
2148+ >>> b = np .arange(7, dtype=np .int32)
2149+ >>> np .result_type(a, b)
20592150 dtype('int64')
20602151
2061- >>> dp .result_type(dp .int64, dp .complex128)
2152+ >>> np .result_type(np .int64, np .complex128)
20622153 dtype('complex128')
20632154
2064- >>> dp .result_type(dp .ones(10, dtype=dp .float32), dp .float64)
2155+ >>> np .result_type(np .ones(10, dtype=np .float32), np .float64)
20652156 dtype('float64')
20662157
20672158 """
@@ -2200,6 +2291,107 @@ def rollaxis(x, axis, start=0):
22002291 return dpnp .moveaxis (usm_array , source = axis , destination = start )
22012292
22022293
2294+ def rot90 (m , k = 1 , axes = (0 , 1 )):
2295+ """
2296+ Rotate an array by 90 degrees in the plane specified by axes.
2297+
2298+ Rotation direction is from the first towards the second axis.
2299+ This means for a 2D array with the default `k` and `axes`, the
2300+ rotation will be counterclockwise.
2301+
2302+ For full documentation refer to :obj:`numpy.rot90`.
2303+
2304+ Parameters
2305+ ----------
2306+ m : {dpnp.ndarray, usm_ndarray}
2307+ Array of two or more dimensions.
2308+ k : integer, optional
2309+ Number of times the array is rotated by 90 degrees.
2310+ Default: ``1``.
2311+ axes : (2,) array_like of ints, optional
2312+ The array is rotated in the plane defined by the axes.
2313+ Axes must be different.
2314+ Default: ``(0, 1)``.
2315+
2316+ Returns
2317+ -------
2318+ out : dpnp.ndarray
2319+ A rotated view of `m`.
2320+
2321+ See Also
2322+ --------
2323+ :obj:`dpnp.flip` : Reverse the order of elements in an array along
2324+ the given axis.
2325+ :obj:`dpnp.fliplr` : Flip an array horizontally.
2326+ :obj:`dpnp.flipud` : Flip an array vertically.
2327+
2328+ Notes
2329+ -----
2330+ ``rot90(m, k=1, axes=(1,0))`` is the reverse of
2331+ ``rot90(m, k=1, axes=(0,1))``.
2332+
2333+ ``rot90(m, k=1, axes=(1,0))`` is equivalent to
2334+ ``rot90(m, k=-1, axes=(0,1))``.
2335+
2336+ Examples
2337+ --------
2338+ >>> import dpnp as np
2339+ >>> m = np.array([[1, 2], [3, 4]])
2340+ >>> m
2341+ array([[1, 2],
2342+ [3, 4]])
2343+ >>> np.rot90(m)
2344+ array([[2, 4],
2345+ [1, 3]])
2346+ >>> np.rot90(m, 2)
2347+ array([[4, 3],
2348+ [2, 1]])
2349+ >>> m = np.arange(8).reshape((2, 2, 2))
2350+ >>> np.rot90(m, 1, (1, 2))
2351+ array([[[1, 3],
2352+ [0, 2]],
2353+ [[5, 7],
2354+ [4, 6]]])
2355+
2356+ """
2357+
2358+ dpnp .check_supported_arrays_type (m )
2359+ k = operator .index (k )
2360+
2361+ m_ndim = m .ndim
2362+ if m_ndim < 2 :
2363+ raise ValueError ("Input must be at least 2-d." )
2364+
2365+ if len (axes ) != 2 :
2366+ raise ValueError ("len(axes) must be 2." )
2367+
2368+ if axes [0 ] == axes [1 ] or abs (axes [0 ] - axes [1 ]) == m_ndim :
2369+ raise ValueError ("Axes must be different." )
2370+
2371+ if not (- m_ndim <= axes [0 ] < m_ndim and - m_ndim <= axes [1 ] < m_ndim ):
2372+ raise ValueError (
2373+ f"Axes={ axes } out of range for array of ndim={ m_ndim } ."
2374+ )
2375+
2376+ k %= 4
2377+ if k == 0 :
2378+ return m [:]
2379+ if k == 2 :
2380+ return dpnp .flip (dpnp .flip (m , axes [0 ]), axes [1 ])
2381+
2382+ axes_list = list (range (0 , m_ndim ))
2383+ (axes_list [axes [0 ]], axes_list [axes [1 ]]) = (
2384+ axes_list [axes [1 ]],
2385+ axes_list [axes [0 ]],
2386+ )
2387+
2388+ if k == 1 :
2389+ return dpnp .transpose (dpnp .flip (m , axes [1 ]), axes_list )
2390+
2391+ # k == 3
2392+ return dpnp .flip (dpnp .transpose (m , axes_list ), axes [1 ])
2393+
2394+
22032395def shape (a ):
22042396 """
22052397 Return the shape of an array.
0 commit comments