39
39
40
40
41
41
import math
42
+ import operator
42
43
43
44
import dpctl .tensor as dpt
44
45
import numpy
77
78
"ravel" ,
78
79
"repeat" ,
79
80
"reshape" ,
81
+ "resize" ,
80
82
"result_type" ,
81
83
"roll" ,
82
84
"rollaxis" ,
85
+ "rot90" ,
83
86
"row_stack" ,
84
87
"shape" ,
85
88
"size" ,
@@ -1522,6 +1525,7 @@ def fliplr(m):
1522
1525
--------
1523
1526
:obj:`dpnp.flipud` : Flip an array vertically (axis=0).
1524
1527
:obj:`dpnp.flip` : Flip array in one or more dimensions.
1528
+ :obj:`dpnp.rot90` : Rotate array counterclockwise.
1525
1529
1526
1530
Examples
1527
1531
--------
@@ -1572,6 +1576,7 @@ def flipud(m):
1572
1576
--------
1573
1577
:obj:`dpnp.fliplr` : Flip array in the left/right direction.
1574
1578
:obj:`dpnp.flip` : Flip array in one or more dimensions.
1579
+ :obj:`dpnp.rot90` : Rotate array counterclockwise.
1575
1580
1576
1581
Examples
1577
1582
--------
@@ -1985,7 +1990,8 @@ def reshape(a, /, newshape, order="C", copy=None):
1985
1990
If ``False``, the result array can never be a copy
1986
1991
and a ValueError exception will be raised in case the copy is necessary.
1987
1992
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``.
1989
1995
1990
1996
Returns
1991
1997
-------
@@ -2004,14 +2010,14 @@ def reshape(a, /, newshape, order="C", copy=None):
2004
2010
2005
2011
Examples
2006
2012
--------
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)
2010
2016
array([1, 2, 3, 4, 5, 6])
2011
- >>> dp .reshape(a, 6, order='F')
2017
+ >>> np .reshape(a, 6, order='F')
2012
2018
array([1, 4, 2, 5, 3, 6])
2013
2019
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
2015
2021
array([[1, 2],
2016
2022
[3, 4],
2017
2023
[5, 6]])
@@ -2031,6 +2037,91 @@ def reshape(a, /, newshape, order="C", copy=None):
2031
2037
return dpnp_array ._create_from_usm_ndarray (usm_res )
2032
2038
2033
2039
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
+
2034
2125
def result_type (* arrays_and_dtypes ):
2035
2126
"""
2036
2127
result_type(*arrays_and_dtypes)
@@ -2052,16 +2143,16 @@ def result_type(*arrays_and_dtypes):
2052
2143
2053
2144
Examples
2054
2145
--------
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)
2059
2150
dtype('int64')
2060
2151
2061
- >>> dp .result_type(dp .int64, dp .complex128)
2152
+ >>> np .result_type(np .int64, np .complex128)
2062
2153
dtype('complex128')
2063
2154
2064
- >>> dp .result_type(dp .ones(10, dtype=dp .float32), dp .float64)
2155
+ >>> np .result_type(np .ones(10, dtype=np .float32), np .float64)
2065
2156
dtype('float64')
2066
2157
2067
2158
"""
@@ -2200,6 +2291,107 @@ def rollaxis(x, axis, start=0):
2200
2291
return dpnp .moveaxis (usm_array , source = axis , destination = start )
2201
2292
2202
2293
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
+
2203
2395
def shape (a ):
2204
2396
"""
2205
2397
Return the shape of an array.
0 commit comments