1# Copyright 2020-2021 Huawei Technologies Co., Ltd 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================ 15"""array operations, the function docs are adapted from Numpy API.""" 16import math 17import operator 18 19import numpy as onp 20 21from ..common import Tensor 22from ..common import dtype as mstype 23from ..ops import operations as P 24from ..ops import functional as F 25from ..ops.primitive import constexpr 26from ..nn.layer.basic import tril as nn_tril 27from ..nn.layer.basic import triu as nn_triu 28from .._c_expression import Tensor as Tensor_ 29 30from .utils import _check_input_for_asarray, _deep_list, _deep_tensor_to_nparray, \ 31 _check_input_tensor, _convert_64_to_32, _get_dtype_from_scalar, \ 32 _expand, _to_tensor, _slice_along_axis, _callable 33from .utils_const import _raise_value_error, _empty, _max, _min, \ 34 _check_same_type, _is_shape_empty, _check_shape, _check_dtype, _tile_size, _abs, \ 35 _raise_type_error, _expanded_shape, _check_is_float, _iota, _type_convert, \ 36 _canonicalize_axis, _list_comprehensions, _ceil, _tuple_slice, _raise_unimplemented_error, \ 37 _tuple_setitem 38from .array_ops import ravel, concatenate, broadcast_arrays, reshape, broadcast_to, flip, \ 39 apply_along_axis, where, moveaxis 40from .dtypes import nan, pi 41 42# According to official numpy reference, the dimension of a numpy array must be less 43# than 32 44MAX_NUMPY_DIMS = 32 45# All types that can be accepted as "array_like" parameters in graph mode. 46ARRAY_TYPES = (int, float, bool, list, tuple, Tensor) 47 48_reduce_min_keepdims = P.ReduceMin(True) 49_reduce_max_keepdims = P.ReduceMax(True) 50_reduce_mean_keepdims = P.ReduceMean(True) 51 52 53def array(obj, dtype=None, copy=True, ndmin=0): 54 """ 55 Creates a tensor. 56 57 This function creates tensors from an array-like object. 58 59 Args: 60 obj (Union[int, float, bool, list, tuple]): Input data, in any form that 61 can be converted to a `Tensor`. This includes Tensor, list, tuple and numbers. 62 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, can 63 be in format of np.int32, or \'int32\'. If dtype is :class:`None`, the data type 64 of the new tensor will be inferred from obj. Default is :class:`None`. 65 copy (bool): If `True`, then the object is copied. Otherwise, a copy will 66 only be made if necessary. Default: `True`. 67 ndmin (int): Specifies the minimum number of dimensions that the resulting 68 tensor should have. Ones will be pre-pended to the shape as needed to 69 meet this requirement. Default: 0 70 71 Returns: 72 Tensor, generated tensor with the specified dtype. 73 74 Raises: 75 TypeError: If input arguments have types not specified above. 76 ValueError: If input `obj` has different sizes at different dimensions. 77 78 Supported Platforms: 79 ``Ascend`` ``GPU`` ``CPU`` 80 81 Examples: 82 >>> import mindspore.numpy as np 83 >>> print(np.array([1,2,3])) 84 [1 2 3] 85 """ 86 if dtype is not None: 87 dtype = _check_dtype(dtype) 88 res = asarray(obj, dtype) 89 90 if ndmin > res.ndim: 91 if res.size == 0: 92 _raise_value_error("Empty tensor cannot be expanded beyond the current dimension.") 93 res = _expand(res, ndmin) 94 95 if copy and isinstance(obj, Tensor): 96 res = copy_(res) 97 elif dtype is not None and dtype != res.dtype: 98 res = res.astype(dtype) 99 100 return res 101 102 103@constexpr 104def asarray_const(a, dtype=None): 105 """Converts the input to tensor. Note here `a` cannot be tensor itself.""" 106 _check_input_for_asarray(a) 107 108 if dtype is not None: 109 dtype = _check_dtype(dtype) 110 111 if isinstance(a, (float, int, bool)) and dtype is None: 112 dtype = _get_dtype_from_scalar(a) 113 114 if isinstance(a, (list, tuple)): 115 # Convert all tuple/nested tuples to lists 116 a = _deep_list(a) 117 # Convert all tensor sub-elements to numpy arrays 118 a = _deep_tensor_to_nparray(a) 119 a = onp.asarray(a) 120 if a.dtype is onp.dtype('object'): 121 raise ValueError('Input array must have the same size across all dimensions.') 122 # If dtype is not specified, we keep consistent with numpy decision 123 # only exceptions are: we use int/float32 124 if dtype is None: 125 dtype = mstype.pytype_to_dtype(a.dtype) 126 if dtype == mstype.float64: 127 dtype = mstype.float32 128 elif dtype == mstype.int64: 129 dtype = mstype.int32 130 131 if isinstance(a, onp.ndarray) and dtype is None: 132 if a.dtype is onp.dtype('object'): 133 raise TypeError(f"For Tensor conversion, the input_data is {a} that contains unsupported element.") 134 dtype = mstype.pytype_to_dtype(a.dtype) 135 a = Tensor.from_numpy(a) 136 137 return Tensor(a, dtype=dtype) 138 139 140def asarray(a, dtype=None): 141 """ 142 Converts the input to tensor. 143 144 This function converts tensors from an array-like object. 145 146 Args: 147 a (Union[int, float, bool, list, tuple, Tensor]): Input data, in any form that can 148 be converted to a `Tensor`. This includes Tensor, list, tuple and numbers. 149 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, can 150 be in format of np.int32, or \'int32\'. If dtype is :class:`None`, the data type 151 of the new tensor will be inferred from obj. Default is :class:`None`. 152 153 Returns: 154 Tensor, generated tensor with the specified dtype. 155 156 Raises: 157 TypeError: If input arguments have types not specified above. 158 ValueError: If input `a` has different sizes at different dimensions. 159 160 Supported Platforms: 161 ``Ascend`` ``GPU`` ``CPU`` 162 163 Examples: 164 >>> import mindspore.numpy as np 165 >>> print(np.asarray([1,2,3])) 166 [1 2 3] 167 """ 168 if dtype is not None: 169 dtype = _check_dtype(dtype) 170 if isinstance(a, Tensor): 171 if dtype is None or dtype == a.dtype: 172 return a 173 return a.astype(dtype) 174 return asarray_const(a, dtype) 175 176 177@constexpr 178def asfarray_const(a, dtype=mstype.float32): 179 """Converts the input to tensor. Note here `a` cannot be tensor itself.""" 180 _check_input_for_asarray(a) 181 if isinstance(a, (list, tuple)): 182 # Convert all tuple/nested tuples to lists 183 a = _deep_list(a) 184 # Convert all tensor sub-elements to numpy arrays 185 a = _deep_tensor_to_nparray(a) 186 a = onp.asarray(a) 187 if a.dtype is onp.dtype('object'): 188 raise ValueError(f"For Tensor conversion, the input_data is {a} that contains unsupported element.") 189 a = Tensor.from_numpy(a) 190 191 return Tensor(a, dtype) 192 193 194def asfarray(a, dtype=mstype.float32): 195 """ 196 Similar to asarray, converts the input to a float tensor. 197 198 If non-float dtype is defined, this function will return a float32 tensor instead. 199 200 Args: 201 a (Union[int, float, bool, list, tuple, Tensor]): Input data, in any form that can 202 be converted to a `Tensor`. This includes Tensor, list, tuple and numbers. 203 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, can 204 be in format of np.int32, or \'int32\'. If dtype is :class:`None`, the data type 205 of the new tensor will be inferred from `a`. Default is :class:`mindspore.float32`. 206 207 208 Returns: 209 Tensor, generated tensor with the specified float dtype. 210 211 Raises: 212 TypeError: If input arguments have types not specified above. 213 ValueError: If input `a` has different sizes at different dimensions. 214 215 Supported Platforms: 216 ``Ascend`` ``GPU`` ``CPU`` 217 218 Examples: 219 >>> import mindspore.numpy as np 220 >>> print(np.asfarray([1,2,3])) 221 [1. 2. 3.] 222 """ 223 if dtype is None: 224 return asarray(a) 225 226 dtype = _check_dtype(dtype) 227 if dtype not in (mstype.float16, mstype.float32, mstype.float64): 228 dtype = mstype.float32 229 230 if isinstance(a, Tensor): 231 return a.astype(dtype) 232 233 return asfarray_const(a, dtype) 234 235 236def copy_(a): 237 """ 238 Returns a tensor copy of the given object. 239 240 Args: 241 a (Union[int, float, bool, list, tuple, Tensor]): Input data, in any form that can 242 be converted to a Tensor. This includes Tensor, list, tuple and numbers. 243 244 Returns: 245 Tensor, has the same data as `a`. 246 247 Raises: 248 TypeError: If input `a` has type not specified above. 249 ValueError: If input `a` has different sizes at different dimensions. 250 251 Supported Platforms: 252 ``Ascend`` ``GPU`` ``CPU`` 253 254 Examples: 255 >>> import mindspore.numpy as np 256 >>> x = np.ones((2,2)) 257 >>> print(np.copy(x)) 258 [[1. 1.] 259 [1. 1.]] 260 """ 261 a = asarray(a) 262 return a.copy() 263 264 265def ones(shape, dtype=mstype.float32): 266 """ 267 Returns a new tensor of given shape and type, filled with ones. 268 269 Args: 270 shape (Union[int, tuple, list]): the shape of the new tensor. 271 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype. 272 Default is :class:`mstype.float32`. 273 274 Returns: 275 Tensor, with the designated `shape` and `dtype`, filled with ones. 276 277 Raises: 278 TypeError: If input arguments have types not specified above. 279 ValueError: If `shape` entries have values :math:`< 0`. 280 281 Supported Platforms: 282 ``Ascend`` ``GPU`` ``CPU`` 283 284 Examples: 285 >>> import mindspore.numpy as np 286 >>> print(np.ones((2,2))) 287 [[1. 1.] 288 [1. 1.]] 289 """ 290 shape = _check_shape(shape) 291 dtype = _check_dtype(dtype) 292 if _is_shape_empty(shape): 293 return full(shape, 1.0, dtype) 294 output = F.fill(dtype, shape, 1) 295 return output 296 297 298def zeros(shape, dtype=mstype.float32): 299 """ 300 Returns a new tensor of given shape and type, filled with zeros. 301 302 Args: 303 shape (Union[int, tuple, list]): the shape of the new tensor. 304 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype. 305 Default is :class:`mstype.float32`. 306 307 Returns: 308 Tensor, with the designated `shape` and `dtype`, filled with zeros. 309 310 Raises: 311 TypeError: If input arguments have types not specified above. 312 ValueError: If `shape` entries have values :math:`< 0`. 313 314 Supported Platforms: 315 ``Ascend`` ``GPU`` ``CPU`` 316 317 Examples: 318 >>> import mindspore.numpy as np 319 >>> print(np.zeros((2,2))) 320 [[0. 0.] 321 [0. 0.]] 322 """ 323 shape = _check_shape(shape) 324 dtype = _check_dtype(dtype) 325 if _is_shape_empty(shape): 326 return full(shape, 0.0, dtype) 327 output = F.fill(dtype, shape, 0) 328 return output 329 330 331def full(shape, fill_value, dtype=None): 332 """ 333 Returns a new tensor of given shape and type, filled with `fill_value`. 334 335 Args: 336 shape (Union[int, tuple(int), list(int)]): Shape of the new tensor, e.g., 337 :math:`(2, 3)` or :math:`2`. 338 fill_value (Union[int, float, bool, list, tuple]): Scalar or array_like 339 fill value. 340 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, 341 if `dtype` is :class:`None`, the data type of the new tensor will be inferred from 342 `fill_value`. Default is :class:`None`. 343 344 Returns: 345 Tensor, with the designated shape and dtype, filled with `fill_value`. 346 347 Raises: 348 TypeError: If input arguments have types not specified above. 349 ValueError: If `shape` has entries < 0. 350 351 Supported Platforms: 352 ``Ascend`` ``GPU`` ``CPU`` 353 354 Examples: 355 >>> import mindspore.numpy as np 356 >>> print(np.full((2,2), True)) 357 [[True True] 358 [True True]] 359 """ 360 shape = _check_shape(shape) 361 if not isinstance(fill_value, ARRAY_TYPES): 362 _raise_type_error("fill value should be int, float, bool, list, tuple, Tensor, but got", fill_value) 363 if dtype is not None: 364 dtype = _check_dtype(dtype) 365 else: 366 if isinstance(fill_value, (int, float, bool)): 367 dtype = _get_dtype_from_scalar(fill_value) 368 if isinstance(fill_value, Tensor): 369 dtype = fill_value.dtype 370 371 if not _is_shape_empty(shape): 372 if isinstance(fill_value, (int, float, bool)): 373 return F.fill(dtype, shape, fill_value) 374 if isinstance(fill_value, (list, tuple)): 375 fill_value = asarray_const(fill_value) 376 return broadcast_to(fill_value, shape) 377 # if shape contains zero, use c.Tensor() 378 return _convert_64_to_32(empty_compile(dtype, shape)) 379 380 381def arange(start, stop=None, step=None, dtype=None): 382 """ 383 Returns evenly spaced values within a given interval. 384 385 Args: 386 start(Union[int, float]): Start of interval. The interval includes this value. 387 When `stop` is provided as a position argument, `start` must be given, when `stop` 388 is a normal argument, `start` can be optional, and default is 0. 389 Please see additional examples below. 390 stop(Union[int, float], optional): End of interval. The interval does not 391 include this value, except in some cases where `step` is not an integer 392 and floating point round-off affects the length of out. 393 step(Union[int, float], optional): Spacing between values. For any output 394 `out`, this is the distance between two adjacent values, :math:`out[i+1] - out[i]`. 395 The default step size is 1. If `step` is specified as a position argument, 396 `start` must also be given. 397 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype. 398 If dtype is None, the data type of the new tensor will be inferred from start, 399 stop and step. Default is None. 400 401 Returns: 402 Tensor with evenly spaced values. 403 404 Raises: 405 TypeError(PyNative Mode): If input arguments have types not specified above, 406 or arguments are not given in the correct orders specified above. 407 RuntimeError(Graph Mode): The inputs that lead to TypeError in Pynative Mode 408 will lead to RuntimeError in Graph Mode. 409 410 Supported Platforms: 411 ``Ascend`` ``GPU`` ``CPU`` 412 413 Examples: 414 >>> import mindspore.numpy as np 415 >>> print(np.arange(0, 5, 1)) 416 [0 1 2 3 4] 417 >>> print(np.arange(3)) 418 [0 1 2] 419 >>> print(np.arange(start=0, stop=3)) 420 [0 1 2] 421 >>> print(np.arange(0, stop=3, step=0.5)) 422 [0. 0.5 1. 1.5 2. 2.5] 423 >>> print(np.arange(stop=3)) # This will lead to TypeError 424 """ 425 # This implementation was inspired by jax.numpy.arange 426 # infer the dtype 427 if dtype is None: 428 dtype = _get_dtype_from_scalar(start, stop, step) 429 if stop is None and step is None: # (start, stop, step) -> (0, start, 1) 430 num = _ceil(start) 431 out = _iota(mstype.float32, num) 432 elif step is None: # (start, stop, step) -> (start, stop, 1) 433 num = _ceil(stop - start) 434 out = _iota(mstype.float32, num) + start 435 elif stop is None: # (start, stop, step) -> (0, start, step) 436 num = _ceil((start + 0.0) / step) 437 out = _iota(mstype.float32, num) * step 438 else: 439 num = _ceil((stop - start + 0.0) / step) 440 out = _iota(mstype.float32, num) * step + start 441 return out.astype(dtype) 442 443 444def _type_checking_for_xspace(start, stop, num, endpoint, dtype): 445 """utility parameter checking function for linspace, logspace, geomspace.""" 446 if not isinstance(start, ARRAY_TYPES): 447 _raise_type_error("start should be int, float, bool, list, tuple, Tensor, but got", start) 448 if not isinstance(stop, ARRAY_TYPES): 449 _raise_type_error("end should be int, float, bool, list, tuple, Tensor, but got", stop) 450 if not isinstance(start, Tensor): 451 start = _type_convert(Tensor, start).astype(mstype.float32) 452 if not isinstance(stop, Tensor): 453 stop = _type_convert(Tensor, stop).astype(mstype.float32) 454 if not isinstance(num, int): 455 _raise_type_error("num should be an integer, but got ", num) 456 if not isinstance(endpoint, bool): 457 _raise_type_error("endpoint should be an boolean, but got ", endpoint) 458 if dtype is not None: 459 dtype = _check_dtype(dtype) 460 else: 461 dtype = mstype.float32 462 start, stop = broadcast_arrays(start, stop) 463 return start, stop, num, endpoint, dtype 464 465 466def _compute_shapes(start, axis, num, endpoint): 467 """Computes shapes for local variables for np.linspace""" 468 bounds_shape = start.shape 469 bounds_shape = _tuple_slice(bounds_shape, None, axis) + (1,) + _tuple_slice(bounds_shape, axis, None) 470 iota_shape = _list_comprehensions(start.ndim+1, 1, True) 471 iota_shape = _tuple_slice(iota_shape, None, axis) + (num,) + _tuple_slice(iota_shape, axis+1, None) 472 num_tensor = _type_convert(Tensor, num).astype(mstype.float32) 473 div = (num_tensor - 1) if endpoint else num_tensor 474 return bounds_shape, iota_shape, div 475 476 477def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0): 478 """ 479 Returns evenly spaced values within a given interval. 480 481 Args: 482 start (Union[int, list(int), tuple(int), tensor]): The starting value of the sequence. 483 stop (Union[int, list(int), tuple(int), tensor]): The end value of the sequence, 484 unless `endpoint` is set to False. In that case, the sequence consists 485 of all but the last of `num + 1` evenly spaced samples, so that `stop` 486 is excluded. Note that the step size changes when `endpoint` is False. 487 num (int, optional): Number of samples to generate. Default is 50. 488 endpoint (bool, optional): If True, `stop` is the last sample. Otherwise, it is 489 not included. Default is True. 490 retstep (bool, optional): If True, return (`samples`, `step`), where `step` is 491 the spacing between samples. 492 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, 493 If `dtype` is None, infer the data type from other input arguments. Default is None. 494 axis (int, optional): The axis in the result to store the samples. Relevant 495 only if start or stop are array-like. By default, the samples will 496 be along a new axis inserted at the beginning. Use -1 to get an axis at the end. 497 Default is 0. 498 499 Returns: 500 Tensor, with `num` equally spaced samples in the closed interval 501 :math:`[start, stop]` or the half-open interval :math:`[start, stop)` 502 (depending on whether `endpoint` is True or False). 503 504 Step, the size of spacing between samples, only returned if `retstep` is True. 505 506 Raises: 507 TypeError: If input arguments have types not specified above. 508 509 Supported Platforms: 510 ``Ascend`` ``GPU`` ``CPU`` 511 512 Examples: 513 >>> import mindspore.numpy as np 514 >>> print(np.linspace(0, 5, 6)) 515 [0. 1. 2. 3. 4. 5.] 516 """ 517 # This implementation was inspired by jax.numpy.linspace and numpy.linspace 518 start, stop, num, endpoint, dtype = _type_checking_for_xspace(start, stop, num, endpoint, dtype) 519 axis = _canonicalize_axis(axis, start.ndim+1) 520 if not isinstance(retstep, bool): 521 _raise_type_error("retstep should be an boolean, but got ", retstep) 522 bounds_shape, iota_shape, div = _compute_shapes(start, axis, num, endpoint) 523 out = None 524 delta = None 525 if num > 1: 526 delta = (stop - start) / div 527 # This is similar to how numpy and jax compute linspace 528 start_expand = reshape(start, bounds_shape) 529 incremental_expand = reshape(_iota(mstype.float32, num), iota_shape) 530 delta_expand = reshape(delta, bounds_shape) 531 start_expand, incremental_expand, delta_expand = broadcast_arrays( 532 start_expand, incremental_expand, delta_expand) 533 out = start_expand + (incremental_expand * delta_expand) 534 # recover endpoint 535 if endpoint: 536 out = moveaxis(out, axis, 0) 537 out[-1] = stop 538 out = moveaxis(out, 0, axis) 539 elif num == 1: 540 delta = nan if endpoint else stop - start 541 out = reshape(start, bounds_shape) 542 else: # num == 0 543 _raise_value_error("cannot support Tensor with num=0.") 544 if retstep: 545 return out.astype(dtype), delta 546 return out.astype(dtype) 547 548 549def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0): 550 """ 551 Returns numbers spaced evenly on a log scale. 552 553 In linear space, the sequence starts at base ** start (base to the power of 554 start) and ends with base ** stop (see endpoint below). 555 556 Args: 557 start (Union[int, list(int), tuple(int), tensor]): ``base ** start`` is the starting 558 value of the sequence. 559 stop (Union[int, list(int), tuple(int), tensor]): ``base ** stop`` is the final value of 560 the sequence, unless `endpoint` is False. In that case, ``num + 1`` values are spaced 561 over the interval in log-space, of which all but the last (a sequence of length num) 562 are returned. 563 num (int, optional): Number of samples to generate. Default is 50. 564 endpoint (bool, optional): If True, `stop` is the last sample. Otherwise, it is 565 not included. Default is True. 566 base (Union[int, float], optional): The base of the log space. The step size 567 between the elements in :math:`ln(samples) / ln(base)` (or :math:`log_{base}(samples)`) 568 is uniform. Default is 10.0. 569 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype. 570 If `dtype` is None, infer the data type from other input arguments. Default is None. 571 axis (int, optional): The axis in the result to store the samples. Relevant 572 only if start or stop is array-like. By default, the samples will 573 be along a new axis inserted at the beginning. Use -1 to get an axis at the end. 574 Default is 0. 575 576 Returns: 577 Tensor, equally spaced on a log scale. 578 579 Raises: 580 TypeError: If input arguments have types not specified above. 581 582 Supported Platforms: 583 ``Ascend`` ``GPU`` ``CPU`` 584 585 Examples: 586 >>> import mindspore.numpy as np 587 >>> print(np.logspace(0, 5, 6, base=2.0)) 588 [ 1. 2. 4. 8. 16. 32.] 589 """ 590 # This implementation was inspired by jax.numpy.linspace and numpy.linspace 591 start, stop, num, endpoint, dtype = _type_checking_for_xspace(start, stop, num, endpoint, dtype) 592 axis = _canonicalize_axis(axis, start.ndim+1) 593 if not isinstance(base, (int, float, bool)): 594 _raise_type_error("base should be a number, but got ", base) 595 linspace_res = linspace(start, stop, num, endpoint=endpoint, retstep=False, dtype=None, axis=axis) 596 return F.tensor_pow(base, linspace_res).astype(dtype) 597 598 599def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0): 600 """ 601 Returns numbers spaced evenly on a log scale (a geometric progression). 602 603 This is similar to logspace, but with endpoints specified directly. Each output sample 604 is a constant multiple of the previous. 605 606 Args: 607 start (Union[int, list(int), tuple(int), tensor]): The starting value of the sequence. 608 stop (Union[int, list(int), tuple(int), tensor]): The final value of the sequence, 609 unless endpoint is False. In that case, num + 1 values are spaced over the 610 interval in log-space, of which all but the last (a sequence of length num) are 611 returned. 612 num (int, optional): Number of samples to generate. Default is 50. 613 endpoint (bool, optional): If True, `stop` is the last sample. Otherwise, it is 614 not included. Default is True. 615 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, can 616 be in format of np.float32, or `float32`.If `dtype` is None, infer the data 617 type from other input arguments. Default is None. 618 axis (int, optional): The axis in the result to store the samples. Relevant 619 only if start or stop is array-like. By default (0), the samples will 620 be along a new axis inserted at the beginning. Use -1 to get an axis at the end. 621 Default is 0. 622 623 Returns: 624 Tensor, with samples equally spaced on a log scale. 625 626 Raises: 627 TypeError: If input arguments have types not specified above. 628 629 Supported Platforms: 630 ``Ascend`` ``GPU`` ``CPU`` 631 632 Examples: 633 >>> output = np.geomspace(1, 256, num=9) 634 >>> print(output) 635 [ 1. 2. 4. 8. 16. 32. 64. 128. 256.] 636 >>> output = np.geomspace(1, 256, num=8, endpoint=False) 637 >>> print(output) 638 [ 1. 2. 4. 8. 16. 32. 64. 128.] 639 """ 640 start, stop, num, endpoint, dtype = _type_checking_for_xspace(start, stop, num, endpoint, dtype) 641 axis = _canonicalize_axis(axis, start.ndim+1) 642 root = num 643 if endpoint: 644 root -= 1 645 bases = F.tensor_pow(F.tensor_div(stop, start), asarray_const(1./(root))) 646 exponents = linspace(zeros(F.shape(bases)), F.fill(F.dtype(bases), F.shape(bases), root), 647 num, endpoint=endpoint, dtype=dtype, axis=axis) 648 shape = F.shape(bases) 649 axis = axis + F.rank(bases) + 1 if axis < 0 else axis 650 expanded_shape = _tuple_slice(shape, None, axis) + (1,) + _tuple_slice(shape, axis, None) 651 bases = F.reshape(bases, expanded_shape) 652 start = F.reshape(start, expanded_shape) 653 res = F.tensor_mul(F.tensor_pow(bases, exponents), start) 654 if dtype is not None: 655 res = F.cast(res, dtype) 656 return res 657 658 659def eye(N, M=None, k=0, dtype=mstype.float32): 660 """ 661 Returns a 2-D tensor with ones on the diagonal and zeros elsewhere. 662 663 Args: 664 N (int): Number of rows in the output, must be larger than 0. 665 M (int, optional): Number of columns in the output. If is :class:`None`, defaults to `N`, 666 if defined, must be larger than 0. Deault is :class:`None`. 667 k (int, optional): Index of the diagonal: 0 (the default) refers to the main 668 diagonal, a positive value refers to an upper diagonal, and a negative value 669 to a lower diagonal. Default is 0. 670 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype. 671 Default is mstype.float32. 672 673 Returns: 674 A tensor of shape (N, M). A tensor where all elements are equal to zero, 675 except for the k-th diagonal, whose values are equal to one. 676 677 Raises: 678 TypeError: If input arguments have types not specified above. 679 680 Supported Platforms: 681 ``Ascend`` ``GPU`` ``CPU`` 682 683 Examples: 684 >>> import mindspore.numpy as np 685 >>> print(np.eye(2, 2)) 686 [[1. 0.] 687 [0. 1.]] 688 """ 689 dtype = _check_dtype(dtype) 690 if M is None: 691 M = N 692 if not (isinstance(M, int) and isinstance(N, int) and isinstance(k, int)): 693 _raise_type_error("Input tensor dimensions should be integers.") 694 out = None 695 if N == 0 or M == 0: 696 # Fill the shape with any value is fine. 697 return full((N, M), 0, dtype) 698 699 out = F.eye(N, M, dtype) 700 701 if k >= M or k <= -N: 702 return full((N, M), 0, dtype) 703 if k != 0: 704 out = out.astype(mstype.float32) 705 if k > 0: 706 out_left = full((N, k), 0, dtype) 707 out_right = out[..., 0:M-k:1] 708 return concatenate((out_left, out_right), 1).astype(dtype) 709 if k < 0: 710 out_upper = full((-k, M), 0, dtype) 711 out_lower = out[0:N+k:1, ...] 712 return concatenate((out_upper, out_lower), 0).astype(dtype) 713 return out 714 715 716def identity(n, dtype=mstype.float32): 717 """ 718 Returns the identity tensor. 719 720 Args: 721 n (int): Number of rows and columns in the output, must be larger than 0. 722 dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, 723 default is :class:`mstype.float32`. 724 725 Returns: 726 A tensor of shape `(n, n)`, where all elements are equal to zero, 727 except for the diagonal, whose values are equal to one. 728 729 Supported Platforms: 730 ``Ascend`` ``GPU`` ``CPU`` 731 732 Raises: 733 TypeError: If input arguments have types not specified above. 734 735 Examples: 736 >>> import mindspore.numpy as np 737 >>> print(np.identity(2)) 738 [[1. 0.] 739 [0. 1.]] 740 """ 741 if not isinstance(n, int): 742 _raise_type_error("Input tensor dimensions should be integers.") 743 dtype = _check_dtype(dtype) 744 return eye(n, dtype=dtype) 745 746 747@constexpr 748def empty_compile(dtype, shape): 749 """Returns an empty Tensor.""" 750 return Tensor_(dtype, shape) 751 752 753def empty(shape, dtype=mstype.float32): 754 """ 755 Returns a new array of given shape and type, without initializing 756 entries. 757 758 Note: 759 Numpy argument `order` is not supported. 760 Object arrays are not supported. 761 762 Args: 763 shape (Union[int, tuple(int)]): Shape of the empty array, e.g., 764 (2, 3) or 2. 765 dtype (:class:`mindspore.dtype`, optional): Desired output data-type for the 766 array, e.g, mstype.int8. Default is mstype.float32. 767 768 Returns: 769 Tensor, array of uninitialized (arbitrary) data of the given 770 shape and dtype. 771 772 Raises: 773 TypeError: if the input shape or dtype is invalid. 774 775 Supported Platforms: 776 ``Ascend`` ``GPU`` ``CPU`` 777 778 Examples: 779 >>> import mindspore.numpy as np 780 >>> output = np.empty((2, 3)) 781 >>> print(output) 782 # result may vary 783 Tensor(shape=[2, 3], dtype=Float32, value= 784 <uninitialized>) 785 """ 786 shape = _check_shape(shape) 787 dtype = _check_dtype(dtype) 788 return empty_compile(dtype, shape) 789 790 791def _get_shape(array_like): 792 """Returns the shape of the array like object.""" 793 if isinstance(array_like, Tensor): 794 return array_like.shape 795 return asarray_const(array_like).shape 796 797 798def _get_dtype(array_like): 799 """Returns the data type of the array like object.""" 800 if isinstance(array_like, Tensor): 801 return array_like.dtype 802 return asarray_const(array_like).dtype 803 804 805def _x_like(prototype, dtype, shape, constructor, fill_value=None): 806 """ 807 Returns a tensor with the same shape and type as prototype, 808 using constructor. 809 """ 810 if not isinstance(prototype, ARRAY_TYPES): 811 _raise_type_error("prototype should be int, float, bool, list, tuple, Tensor, but got", prototype) 812 dtype_out = dtype 813 shape_out = shape 814 if dtype_out is None: 815 dtype_out = _get_dtype(prototype) 816 if shape_out is None or isinstance(shape_out, (list, tuple)) and not shape_out: 817 shape_out = _get_shape(prototype) 818 if fill_value is not None: 819 return constructor(shape_out, fill_value, dtype_out) 820 return constructor(shape_out, dtype_out) 821 822 823def empty_like(prototype, dtype=None, shape=None): 824 """ 825 Returns a new array with the same shape and type as a given array. 826 827 Note: 828 Input array must have the same size across a dimension. 829 If `prototype` is not a Tensor, dtype is float32 by default if not provided. 830 831 Args: 832 prototype (Union[Tensor, list, tuple]): The shape and data-type of `prototype` 833 define these same attributes of the returned array. 834 dtype (:class:`mindspore.dtype`, optional): Overrides the data type of the 835 result. 836 shape (int or sequence of ints, optional): Overrides the shape 837 of the result. 838 839 Returns: 840 Tensor, array of uninitialized (arbitrary) data with the same 841 shape and type as `prototype`. 842 843 Raises: 844 ValueError: if `prototype` is not a Tensor, list or tuple. 845 846 Supported Platforms: 847 ``Ascend`` ``GPU`` ``CPU`` 848 849 Examples: 850 >>> import mindspore.numpy as np 851 >>> a = np.ones((4,1,2)) 852 >>> output = np.empty_like(a) 853 >>> print(output) 854 # result may vary 855 Tensor(shape=[4, 1, 2], dtype=Float32, value= 856 <uninitialized>) 857 """ 858 return _x_like(prototype, dtype, shape, empty) 859 860 861def ones_like(a, dtype=None, shape=None): 862 """ 863 Returns an array of ones with the same shape and type as a given array. 864 865 Note: 866 Input array must have the same size across a dimension. 867 If `a` is not a Tensor, dtype is float32 by default if not provided. 868 869 Args: 870 a (Union[Tensor, list, tuple]): The shape and data-type of a define these same 871 attributes of the returned array. 872 dtype (:class:`mindspore.dtype`, optional): Overrides the data type of the 873 result. 874 shape (int or sequence of ints, optional): Overrides the shape 875 of the result. 876 877 Returns: 878 Tensor, array of ones with the same shape and type as `a`. 879 880 Raises: 881 ValueError: if `a` is not a Tensor, list or tuple. 882 883 Supported Platforms: 884 ``Ascend`` ``GPU`` ``CPU`` 885 886 Examples: 887 >>> import mindspore.numpy as np 888 >>> a = np.ones((4,1,2)) 889 >>> output = np.ones_like(a) 890 >>> print(output) 891 [[[1. 1.]] 892 [[1. 1.]] 893 [[1. 1.]] 894 [[1. 1.]]] 895 """ 896 return _x_like(a, dtype, shape, ones) 897 898 899def zeros_like(a, dtype=None, shape=None): 900 """ 901 Returns an array of zeros with the same shape and type as a given array. 902 903 Note: 904 Input array must have the same size across a dimension. 905 If `a` is not a Tensor, dtype is float32 by default if not provided. 906 907 Args: 908 a (Union[Tensor, list, tuple]): The shape and data-type of a define these same 909 attributes of the returned array. 910 dtype (:class:`mindspore.dtype`, optional): Overrides the data type of the 911 result. 912 shape (int or sequence of ints, optional): Overrides the shape 913 of the result. 914 915 Returns: 916 Tensor, array of zeros with the same shape and type as `a`. 917 918 Raises: 919 ValueError: if `a` is not a Tensor, list or tuple. 920 921 Supported Platforms: 922 ``Ascend`` ``GPU`` ``CPU`` 923 924 Examples: 925 >>> import mindspore.numpy as np 926 >>> a = np.ones((4,1,2)) 927 >>> output = np.zeros_like(a) 928 >>> print(output) 929 [[[0. 0.]] 930 [[0. 0.]] 931 [[0. 0.]] 932 [[0. 0.]]] 933 """ 934 return _x_like(a, dtype, shape, zeros) 935 936 937def full_like(a, fill_value, dtype=None, shape=None): 938 """ 939 Returns a full array with the same shape and type as a given array. 940 941 Note: 942 Input array must have the same size across a dimension. 943 If `a` is not a Tensor, dtype is float32 by default if not provided. 944 945 Args: 946 a (Union[Tensor, list, tuple]): The shape and data-type of `a` define these same 947 attributes of the returned array. 948 fill_value (scalar): Fill value. 949 dtype (:class:`mindspore.dtype`, optional): Overrides the data type of the 950 result. 951 shape (int or sequence of ints, optional): Overrides the shape 952 of the result. 953 954 Returns: 955 Tensor, array of fill_value with the same shape and type as `a`. 956 957 Raises: 958 ValueError: if `a` is not a Tensor, list or tuple. 959 960 Supported Platforms: 961 ``Ascend`` ``GPU`` ``CPU`` 962 963 Examples: 964 >>> import mindspore.numpy as np 965 >>> a = np.ones((4,1,2)) 966 >>> output = np.full_like(a, 0.5) 967 >>> print(output) 968 [[[0.5 0.5]] 969 [[0.5 0.5]] 970 [[0.5 0.5]] 971 [[0.5 0.5]]] 972 """ 973 return _x_like(a, dtype, shape, full, fill_value=fill_value) 974 975 976def tri(N, M=None, k=0, dtype=mstype.float32): 977 """ 978 Returns a tensor with ones at and below the given diagonal and zeros elsewhere. 979 980 Args: 981 N(int): Number of rows in the array. 982 M(int, optional): Number of columns in the array. By default, `M` is taken 983 equal to N. 984 k(int, optional): The sub-diagonal at and below which the array is filled. 985 :math:`k = 0` is the main diagonal, while :math:`k < 0` is below it, and :math:`k > 0` is above. 986 The default is 0. 987 dtype(:class:`mindspore.dtype`, optional): Data type of the returned array. The default 988 is mstype.float32. 989 990 Returns: 991 Tensor with shape `(N, M)`, with its lower triangle filled with 992 ones and zeros elsewhere; in other words :math:`T[i,j] = 1` for :math:`j <= i + k`, 993 0 otherwise. 994 995 Raises: 996 TypeError: If input arguments have types not specified above. 997 998 Supported Platforms: 999 ``Ascend`` ``GPU`` ``CPU`` 1000 1001 Examples: 1002 >>> import mindspore.numpy as np 1003 >>> output = np.tri(3, 3, 1) 1004 >>> print(output) 1005 [[1. 1. 0.] 1006 [1. 1. 1.] 1007 [1. 1. 1.]] 1008 """ 1009 if M is None: 1010 M = N 1011 return nn_tril((N, M), dtype, k) 1012 1013 1014def tril(m, k=0): 1015 """ 1016 Returns a lower triangle of a tensor. 1017 1018 Returns a copy of a tensor with elements above the `k-th` diagonal zeroed. 1019 1020 Args: 1021 m (Union[Tensor, list, tuple]): The shape and data-type of `m` define these same 1022 attributes of the returned tensor. 1023 k (int, optional): Diagonal above which to zero elements. :math:`k = 0` (the default) 1024 is the main diagonal, :math:`k < 0` is below it and :math:`k > 0` is above. 1025 1026 Returns: 1027 Lower triangle of `m`, of same shape and data-type as `m`. 1028 1029 Supported Platforms: 1030 ``Ascend`` ``GPU`` ``CPU`` 1031 1032 Raises: 1033 TypeError: If input arguments have types not specified above. 1034 ValueError: If input `m`\'s rank :math:`< 1`. 1035 1036 Examples: 1037 >>> import mindspore.numpy as np 1038 >>> output = np.tril(np.ones((3, 3))) 1039 >>> print(output) 1040 [[1. 0. 0.] 1041 [1. 1. 0.] 1042 [1. 1. 1.]] 1043 """ 1044 if not isinstance(m, Tensor): 1045 m = asarray_const(m) 1046 dtype = m.dtype 1047 m = m.astype(mstype.float32) 1048 assist = nn_tril(m.shape, mstype.float32, k) 1049 return F.tensor_mul(assist, m).astype(dtype) 1050 1051 1052def triu(m, k=0): 1053 """ 1054 Returns an upper triangle of a tensor. 1055 1056 Returns a copy of a tensor with elements below the `k-th` diagonal zeroed. 1057 1058 Args: 1059 m (Union[Tensor, list, tuple]): The shape and data-type of `m` define these same 1060 attributes of the returned tensor. 1061 k (int, optional): Diagonal below which to zero elements. :math:`k = 0` (the default) 1062 is the main diagonal, :math:`k < 0` is below it and :math:`k > 0` is above. 1063 1064 Returns: 1065 Upper triangle of `m`, of same shape and data-type as `m`. 1066 1067 Raises: 1068 TypeError: If input arguments have types not specified above. 1069 ValueError: If input `m`\'s rank < 1. 1070 1071 Supported Platforms: 1072 ``Ascend`` ``GPU`` ``CPU`` 1073 1074 Examples: 1075 >>> import mindspore.numpy as np 1076 >>> output = np.triu(np.ones((3, 3))) 1077 >>> print(output) 1078 [[1. 1. 1.] 1079 [0. 1. 1.] 1080 [0. 0. 1.]] 1081 """ 1082 if not isinstance(m, Tensor): 1083 m = asarray_const(m) 1084 dtype = m.dtype 1085 m = m.astype(mstype.float32) 1086 assist = nn_triu(m.shape, mstype.float32, k) 1087 return F.tensor_mul(assist, m).astype(dtype) 1088 1089 1090def diagonal(a, offset=0, axis1=0, axis2=1): 1091 """ 1092 Returns specified diagonals. 1093 1094 If `a` is 2-D, returns the diagonal of `a` with the given offset, i.e., the 1095 collection of elements of the form ``a[i, i+offset]``. If `a` has more than two 1096 dimensions, then the axes specified by `axis1` and `axis2` are used to determine 1097 the 2-D sub-array whose diagonal is returned. The shape of the resulting 1098 array can be determined by removing `axis1` and `axis2` and appending an index 1099 to the right equal to the size of the resulting diagonals. 1100 1101 Args: 1102 a (Tensor): Array from which the diagonals are taken. 1103 offset (int, optional): Offset of the diagonal from the main diagonal. 1104 Can be positive or negative. Defaults to main diagonal. 1105 axis1 (int, optional): Axis to be used as the first axis of the 2-D 1106 sub-arrays from which the diagonals should be taken. Defaults to 1107 first axis (0). 1108 axis2 (int, optional): Axis to be used as the second axis of the 2-D 1109 sub-arrays from which the diagonals should be taken. Defaults to 1110 second axis. 1111 1112 Returns: 1113 Tensor, if `a` is 2-D, then `a` 1-D array containing the diagonal. If 1114 ``a.ndim > 2``, then the dimensions specified by `axis1` and `axis2` are removed, 1115 and a new axis inserted at the end corresponding to the diagonal. 1116 1117 Raises: 1118 ValueError: if the input tensor has less than two dimensions. 1119 1120 Supported Platforms: 1121 ``Ascend`` ``GPU`` ``CPU`` 1122 1123 Examples: 1124 >>> import mindspore.numpy as np 1125 >>> a = np.arange(4).reshape(2,2).astype(np.float32) 1126 >>> print(a) 1127 [[0. 1.] 1128 [2. 3.]] 1129 >>> output = np.diagonal(a) 1130 >>> print(output) 1131 [0. 3.] 1132 >>> output = np.diagonal(a, 1) 1133 >>> print(output) 1134 [1.] 1135 >>> a = np.arange(8).reshape(2, 2, 2).astype(np.float32) 1136 >>> print(a) 1137 [[[0. 1.] 1138 [2. 3.]] 1139 [[4. 5.] 1140 [6. 7.]]] 1141 >>> output = np.diagonal(a, 0, 0, 1) 1142 >>> print(output) 1143 [[0. 6.] 1144 [1. 7.]] 1145 """ 1146 return a.diagonal(offset=offset, axis1=axis1, axis2=axis2) 1147 1148 1149def trace(a, offset=0, axis1=0, axis2=1, dtype=None): 1150 """ 1151 Returns the sum along diagonals of the array. 1152 1153 If `a` is 2-D, the sum along its diagonal with the given offset is returned, 1154 i.e., the sum of elements ``a[i,i+offset]`` for all `i`. 1155 If `a` has more than two dimensions, then the axes specified by `axis1` and 1156 `axis2` are used to determine the 2-D sub-arrays whose traces are returned. 1157 The shape of the resulting array is the same as that of a with `axis1` and 1158 `axis2` removed. 1159 1160 Note: 1161 On GPU, the supported dtypes are np.float16, and np.float32. 1162 On CPU, the supported dtypes are np.float16, np.float32, and np.float64. 1163 1164 Args: 1165 a (Tensor): Array from which the diagonals are taken. 1166 offset (int, optional): Offset of the diagonal from the main diagonal. 1167 Can be positive or negative. Defaults to main diagonal. 1168 axis1 (int, optional): Axis to be used as the first axis of the 2-D 1169 sub-arrays from which the diagonals should be taken. Defaults to 1170 first axis (0). 1171 axis2 (int, optional): Axis to be used as the second axis of the 2-D 1172 sub-arrays from which the diagonals should be taken. Defaults to 1173 second axis. 1174 dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the 1175 output Tensor. 1176 1177 Returns: 1178 Tensor, sum_along_diagonals. If `a` is 2-D, the sum along the diagonal 1179 is returned. If `a` has larger dimensions, then an array of sums along 1180 diagonals is returned. 1181 1182 Raises: 1183 ValueError: if the input tensor has less than two dimensions. 1184 1185 Supported Platforms: 1186 ``Ascend`` ``GPU`` ``CPU`` 1187 1188 Examples: 1189 >>> import mindspore.numpy as np 1190 >>> output = np.trace(np.eye(3)) 1191 >>> print(output) 1192 3.0 1193 >>> a = np.arange(8).reshape((2,2,2)) 1194 >>> output = np.trace(a) 1195 >>> print(output) 1196 [6 8] 1197 >>> a = np.arange(24).reshape((2,2,2,3)) 1198 >>> output = np.trace(a).shape 1199 >>> print(output) 1200 (2, 3) 1201 """ 1202 return a.trace(offset=offset, axis1=axis1, axis2=axis2, dtype=dtype) 1203 1204 1205def _index(i, size, cartesian=True): 1206 """If cartesian=True, index 0 is swapped with index 1.""" 1207 if cartesian: 1208 if i == 1: 1209 return 0 1210 if i == 0 and size >= 2: 1211 return 1 1212 return i 1213 1214 1215def meshgrid(*xi, sparse=False, indexing='xy'): 1216 """ 1217 Returns coordinate matrices from coordinate vectors. 1218 1219 Make `N-D` coordinate arrays for vectorized evaluations of `N-D` 1220 scalar/vector fields over `N-D` grids, given one-dimensional 1221 coordinate arrays `x1, x2,…, xn`. 1222 1223 Note: 1224 Numpy argument copy is not supported, and a copy is always 1225 returned. 1226 1227 Args: 1228 *xi (Tensor): 1-D arrays representing the coordinates 1229 of a grid. 1230 indexing (‘xy’, ‘ij’, optional): Cartesian (‘xy’, default) or 1231 matrix (‘ij’) indexing of output. In the 2-D case with 1232 inputs of length `M` and `N`, the outputs are of shape `(N, M)` 1233 for ‘xy’ indexing and `(M, N)` for ‘ij’ indexing. In the 3-D 1234 case with inputs of length `M`, `N` and `P`, outputs are of shape 1235 `(N, M, P)` for ‘xy’ indexing and `(M, N, P)` for ‘ij’ indexing. 1236 sparse (bool, optional): If True a sparse grid is returned in 1237 order to conserve memory. Default is False. 1238 1239 Returns: 1240 Tuple of tensors, for vectors `x1, x2,…, xn` with lengths 1241 ``Ni=len(xi)``, return `(N1, N2, N3,...Nn)` shaped arrays if 1242 ``indexing=’ij’`` or `(N2, N1, N3,...Nn)` shaped arrays if 1243 ``indexing=’xy’`` with the elements of `xi` repeated to fill the matrix 1244 along the first dimension for `x1`, the second for `x2` and so on. 1245 1246 Raises: 1247 TypeError: if the input is not a tensor, or sparse is not boolean, or 1248 indexing is not 'xy' or 'ij'. 1249 1250 Supported Platforms: 1251 ``Ascend`` ``GPU`` ``CPU`` 1252 1253 Examples: 1254 >>> import mindspore.numpy as np 1255 >>> x = np.linspace(0, 1, 3) 1256 >>> y = np.linspace(0, 1, 2) 1257 >>> xv, yv = np.meshgrid(x, y) 1258 >>> print(xv) 1259 [[0. 0.5 1. ] 1260 [0. 0.5 1. ]] 1261 >>> print(yv) 1262 [[0. 0. 0.] 1263 [1. 1. 1.]] 1264 >>> xv, yv = np.meshgrid(x, y, sparse=True) 1265 >>> print(xv) 1266 [[0. 0.5 1. ]] 1267 >>> print(yv) 1268 [[0.] 1269 [1.]] 1270 """ 1271 _check_input_tensor(*xi) 1272 if not isinstance(sparse, bool): 1273 _raise_type_error('argument sparse should be boolean') 1274 if indexing not in ('xy', 'ij'): 1275 _raise_type_error("Valid values for `indexing` are 'xy' and 'ij'.") 1276 1277 shape_out = () 1278 for x in xi: 1279 shape_out += (x.size,) 1280 if _is_shape_empty(shape_out): 1281 return ones(shape_out) 1282 1283 grids = [] 1284 for x in xi: 1285 if F.rank(x) == 1: 1286 grids.append(x) 1287 else: 1288 grids.append(ravel(x)) 1289 ndim = len(grids) 1290 1291 cartesian = indexing == 'xy' 1292 shape_out = () 1293 for i in range(len(grids)): 1294 grid_index = _index(i, ndim, cartesian=cartesian) 1295 shape_out += (F.shape(grids[grid_index])[0],) 1296 1297 res = [] 1298 for i, x in enumerate(grids): 1299 grid_index = _index(i, ndim, cartesian=cartesian) 1300 shape_expanded = _expanded_shape(ndim, shape_out[grid_index], grid_index) 1301 x = x.reshape(shape_expanded) 1302 if not sparse: 1303 x = F.tile(x, _tile_size(shape_expanded, shape_out, ndim)) 1304 res.append(x) 1305 return res 1306 1307 1308class NdGrid: 1309 """ 1310 Construct a multi-dimensional "meshgrid". 1311 1312 ``grid = NdGrid()`` creates an instance which will return a mesh-grid 1313 when indexed. 1314 If instantiated with an argument of ``sparse=True``, the mesh-grid is 1315 open (or not fleshed out) so that only one-dimension of each 1316 returned argument is greater than 1. 1317 1318 Args: 1319 sparse (bool): Whether the grid is sparse or not. Default is 1320 False. 1321 1322 Returns: 1323 Tensor or tuple of tensor, a meshgrid. If ``sparse=False``, returns 1324 tensors are all of the same dimensions; and if ``sparse=True``, 1325 returns tensors with only one dimension not equal to `1`. 1326 """ 1327 def __init__(self, sparse=False): 1328 self.sparse = sparse 1329 1330 def __getitem__(self, keys): 1331 if isinstance(keys, slice): 1332 keys = (keys,) 1333 1334 xi = [] 1335 for k in keys: 1336 if not isinstance(k.start, int) or not isinstance(k.stop, int): 1337 _raise_type_error('slice indices must be integers') 1338 if k.step: 1339 step = k.step 1340 else: 1341 step = 1 1342 if isinstance(step, complex): 1343 v = linspace(k.start, k.stop, int(abs(step))) 1344 else: 1345 v = arange(k.start, k.stop, step) 1346 xi.append(v) 1347 grids = meshgrid(*xi, sparse=self.sparse, indexing='ij') 1348 1349 if len(grids) == 1: 1350 return grids[0] 1351 if self.sparse: 1352 return grids 1353 1354 if isinstance(grids, Tensor_): 1355 return grids 1356 expanded = [] 1357 for grid in grids: 1358 expanded.append(F.expand_dims(grid, 0)) 1359 res = concatenate(tuple(expanded)) 1360 return res 1361 1362 1363class MGridClass(NdGrid): 1364 """ 1365 mgrid is an :class:`NdGrid` instance with ``sparse=False``. 1366 1367 The dimension and number of the output arrays are equal to the number 1368 of indexing dimensions. If the step length is not a complex number, 1369 then the stop is not inclusive. However, if the step length is a complex 1370 number (e.g. 5j), then the integer part of its magnitude is interpreted 1371 as specifying the number of points to create between the start and 1372 stop values, where the stop value is inclusive. 1373 1374 Note: 1375 Not supported in graph mode. 1376 Unlike Numpy, if the step length is a complex number with a real 1377 component, the step length is handled as equivalent to 1378 ``int(abs(step))``. 1379 1380 Returns: 1381 Tensor or tuple of tensor, a meshgrid. 1382 1383 Raises: 1384 TypeError: if slicing indices are not integers. 1385 1386 Supported Platforms: 1387 ``Ascend`` ``GPU`` ``CPU`` 1388 1389 Examples: 1390 >>> from mindspore.numpy import mgrid 1391 >>> output = mgrid[0:5, 0:5] 1392 >>> print(output) 1393 [[[0 0 0 0 0] 1394 [1 1 1 1 1] 1395 [2 2 2 2 2] 1396 [3 3 3 3 3] 1397 [4 4 4 4 4]] 1398 [[0 1 2 3 4] 1399 [0 1 2 3 4] 1400 [0 1 2 3 4] 1401 [0 1 2 3 4] 1402 [0 1 2 3 4]]] 1403 >>> output = mgrid[-1:1:5j] 1404 >>> print(output) 1405 [-1. -0.5 0. 0.5 1. ] 1406 """ 1407 def __init__(self): 1408 super(MGridClass, self).__init__(sparse=False) 1409 1410 1411class OGridClass(NdGrid): 1412 """ 1413 ogrid is an :class:`NdGrid` instance with ``sparse=True``. 1414 1415 The dimension and number of the output arrays are equal to the number 1416 of indexing dimensions. If the step length is not a complex number, 1417 then the stop is not inclusive. However, if the step length is a complex 1418 number (e.g. 5j), then the integer part of its magnitude is interpreted 1419 as specifying the number of points to create between the start and 1420 stop values, where the stop value is inclusive. 1421 1422 Note: 1423 Not supported in graph mode. 1424 Unlike Numpy, if the step length is a complex number with a real 1425 component, the step length is handled as equivalent to 1426 ``int(abs(step))``. 1427 1428 Raises: 1429 TypeError: if slicing indices are not integers. 1430 1431 Supported Platforms: 1432 ``Ascend`` ``GPU`` ``CPU`` 1433 1434 Examples: 1435 >>> from mindspore.numpy import ogrid 1436 >>> output = ogrid[0:5,0:5] 1437 >>> print(output) 1438 [Tensor(shape=[5, 1], dtype=Int32, value= 1439 [[0], 1440 [1], 1441 [2] 1442 [3], 1443 [4]]), Tensor(shape=[1, 5], dtype=Int32, value= 1444 [[0, 1, 2, 3, 4]])] 1445 >>> output = ogrid[-1:1:5j] 1446 >>> print(output) 1447 [-1. -0.5 0. 0.5 1. ] 1448 """ 1449 def __init__(self): 1450 super(OGridClass, self).__init__(sparse=True) 1451 1452 1453mgrid = MGridClass() 1454 1455 1456ogrid = OGridClass() 1457 1458 1459def diag(v, k=0): 1460 """ 1461 Extracts a diagonal or construct a diagonal array. 1462 1463 Args: 1464 v (Tensor): If `v` is a 2-D array, return a copy of its `k-th` diagonal. 1465 If `v` is a 1-D array, return a 2-D array with v on the `k-th` diagonal. 1466 k (int, optional): Diagonal in question. The default is 0. Use ``k>0`` for 1467 diagonals above the main diagonal, and ``k<0`` for diagonals below the 1468 main diagonal. 1469 1470 Returns: 1471 Tensor, the extracted diagonal or constructed diagonal array. 1472 1473 Raises: 1474 ValueError: if input is not 1-D or 2-D. 1475 1476 Supported Platforms: 1477 ``Ascend`` ``GPU`` ``CPU`` 1478 1479 Examples: 1480 >>> import mindspore.numpy as np 1481 >>> x = np.arange(9).reshape((3,3)) 1482 >>> print(x) 1483 [[0 1 2] 1484 [3 4 5] 1485 [6 7 8]] 1486 >>> output = np.diag(x) 1487 >>> print(output) 1488 [0 4 8] 1489 >>> output = np.diag(x, k=1) 1490 >>> print(output) 1491 [1 5] 1492 >>> output = np.diag(x, k=-1) 1493 >>> print(output) 1494 [3 7] 1495 """ 1496 ndim = F.rank(v) 1497 if ndim == 1: 1498 return diagflat(v, k=k) 1499 if ndim == 2: 1500 shape = F.shape(v) 1501 dtype = F.dtype(v) 1502 if _is_shape_empty(shape): 1503 return _empty(dtype, (0,)) 1504 e = eye(shape[0], shape[1], k, dtype) 1505 prod = F.tensor_mul(v, e) 1506 1507 cast_type = dtype 1508 if not _check_is_float(dtype): 1509 # reduce sum only supports float types 1510 cast_type = mstype.float32 1511 prod = F.cast(prod, cast_type) 1512 1513 res = F.reduce_sum(prod, 1) 1514 res = res[_max(0, -k): _min(shape[0], _max(0, shape[1] - k))] 1515 1516 if not _check_same_type(cast_type, dtype): 1517 res = F.cast(res, dtype) 1518 1519 return res 1520 return _raise_value_error("Input must be 1- or 2-d.") 1521 1522 1523def diagflat(v, k=0): 1524 """ 1525 Creates a two-dimensional array with the flattened input as a diagonal. 1526 1527 Note: 1528 On GPU, the supported dtypes are np.float16, and np.float32. 1529 1530 Args: 1531 v (Tensor): Input data, which is flattened and set as the `k-th` diagonal 1532 of the output. 1533 k (int, optional): Diagonal to set; 0, the default, corresponds to the 1534 “main” diagonal, a positive (negative) `k` giving the number of the 1535 diagonal above (below) the main. 1536 1537 Returns: 1538 Tensor, The 2-D output array. 1539 1540 Raises: 1541 TypeError: if the input is not a tensor. 1542 1543 Supported Platforms: 1544 ``Ascend`` ``GPU`` ``CPU`` 1545 1546 Examples: 1547 >>> import mindspore.numpy as np 1548 >>> output = np.diagflat(np.asarray([[1,2], [3,4]])) 1549 >>> print(output) 1550 [[1 0 0 0] 1551 [0 2 0 0] 1552 [0 0 3 0] 1553 [0 0 0 4]] 1554 >>> output = np.diagflat(np.asarray([1,2]), 1) 1555 >>> print(output) 1556 [[0 1 0] 1557 [0 0 2] 1558 [0 0 0]] 1559 """ 1560 _check_input_tensor(v) 1561 dtype = F.dtype(v) 1562 k_abs = _abs(k) 1563 if _is_shape_empty(F.shape(v)): 1564 return zeros((k_abs, k_abs), dtype) 1565 1566 v = ravel(v) 1567 size = F.shape(v)[0] 1568 e = eye(size, size, 0, dtype) 1569 res = F.tensor_mul(v, e) 1570 1571 if k != 0: 1572 pad_y = zeros((size, k_abs), dtype) 1573 pad_x = zeros((k_abs, size + k_abs), dtype) 1574 if k < 0: 1575 res = concatenate((res, pad_y), axis=1) 1576 res = concatenate((pad_x, res), axis=0) 1577 else: 1578 res = concatenate((pad_y, res), axis=1) 1579 res = concatenate((res, pad_x), axis=0) 1580 return res 1581 1582 1583def diag_indices(n, ndim=2): 1584 """ 1585 Returns the indices to access the main diagonal of an array. 1586 1587 This returns a tuple of indices that can be used to access the main 1588 diagonal of an array a with ``a.ndim >= 2`` dimensions and shape `(n, n, …, n)`. 1589 For ``a.ndim = 2`` this is the usual diagonal, for ``a.ndim > 2`` this is the set 1590 of indices to access ``a[i, i, ..., i]`` for ``i = [0..n-1]``. 1591 1592 Args: 1593 n (int): The size, along each dimension, of the arrays for which 1594 the returned indices can be used. 1595 ndim (int, optional): The number of dimensions. 1596 1597 Returns: 1598 Tuple of Tensor. 1599 1600 Raises: 1601 TypeError: if input are not integers. 1602 1603 Supported Platforms: 1604 ``Ascend`` ``GPU`` ``CPU`` 1605 1606 Examples: 1607 >>> import mindspore.numpy as np 1608 >>> output = np.diag_indices(5, 3) 1609 >>> print(output) 1610 (Tensor(shape=[5], dtype=Int32, value= [0, 1, 2, 3, 4]), 1611 Tensor(shape=[5], dtype=Int32, value= [0, 1, 2, 3, 4]), 1612 Tensor(shape=[5], dtype=Int32, value= [0, 1, 2, 3, 4])) 1613 """ 1614 if not isinstance(n, int) or not isinstance(ndim, int): 1615 _raise_type_error('input must be integers') 1616 return _list_comprehensions(ndim, arange(start=0, stop=n), True) 1617 1618 1619def ix_(*args): 1620 r""" 1621 Constructs an open mesh from multiple sequences. 1622 1623 This function takes `N` 1-D sequences and returns `N` outputs with `N` 1624 dimensions each, such that the shape is 1 in all but one dimension 1625 and the dimension with the non-unit shape value cycles through all 1626 N dimensions. 1627 Using ix\_ one can quickly construct index arrays that will index 1628 the cross product. ``a[np.ix_([1,3],[2,5])]`` returns the array 1629 ``[[a[1,2] a[1,5]], [a[3,2] a[3,5]]]``. 1630 1631 Note: 1632 Boolean masks are not supported. 1633 1634 Args: 1635 *args (Tensor): 1-D sequences. 1636 1637 Returns: 1638 Tuple of Tensor, `N` arrays with `N` dimensions each, with `N` the 1639 number of input sequences. Together these arrays form an open 1640 mesh. 1641 1642 Raises: 1643 TypeError: if the input is not a tensor. 1644 1645 Supported Platforms: 1646 ``Ascend`` ``GPU`` ``CPU`` 1647 1648 Examples: 1649 >>> import mindspore.numpy as np 1650 >>> ixgrid = np.ix_(np.array([0, 1]), np.array([2, 4])) 1651 >>> print(ixgrid) 1652 (Tensor(shape=[2, 1], dtype=Int32, value= 1653 [[0], 1654 [1]]), Tensor(shape=[1, 2], dtype=Int32, value= 1655 [[2, 4]])) 1656 """ 1657 _check_input_tensor(*args) 1658 ndim = len(args) 1659 res = () 1660 for i, arr in enumerate(args): 1661 if F.rank(arr) != 1: 1662 return _raise_value_error('Cross index must be 1 dimensional') 1663 res += (F.reshape(arr, _expanded_shape(ndim, arr.size, i)),) 1664 return res 1665 1666 1667def vander(x, N=None, increasing=False): 1668 """ 1669 Generates a Vandermonde matrix. 1670 1671 The columns of the output matrix are powers of the input vector. The order of 1672 the powers is determined by the increasing boolean argument. Specifically, when 1673 increasing is `False`, the i-th output column is the input vector raised element-wise 1674 to the power of :math:`N - i - 1`. Such a matrix with a geometric progression in each row 1675 is named for Alexandre-Theophile Vandermonde. 1676 1677 Args: 1678 x (Union[list, tuple, Tensor]): 1-D input array. 1679 N (int, optional): Number of columns in the output. If N is not specified, a 1680 square array is returned (``N = len(x)``). 1681 increasing (bool, optional): Order of the powers of the columns. If True, the 1682 powers increase from left to right, if False (the default) they are reversed. 1683 1684 Returns: 1685 Vandermonde matrix. If `increasing` is `False`, the first column is :math:`x^{(N-1)}`, 1686 the second :math:`x^{(N-2)}` and so forth. If `increasing` is `True`, the columns are 1687 :math:`x^0, x^1, ..., x^{(N-1)}`. 1688 1689 Raises: 1690 TypeError: If inputs have types not specified above. 1691 ValueError: If `x` is not 1-D, or `N` < 0. 1692 1693 Supported Platforms: 1694 ``Ascend`` ``GPU`` ``CPU`` 1695 1696 Examples: 1697 >>> import mindspore.numpy as np 1698 >>> print(np.vander([1., 2., 3., 4., 5.])) 1699 [[ 1. 1. 1. 1. 1.] 1700 [ 16. 8. 4. 2. 1.] 1701 [ 81. 27. 9. 3. 1.] 1702 [256. 64. 16. 4. 1.] 1703 [625. 125. 25. 5. 1.]] 1704 """ 1705 if isinstance(x, (list, tuple)): 1706 x = asarray_const(x) 1707 elif not isinstance(x, Tensor): 1708 _raise_type_error("Input x must be list, tuple or Tensor, but got ", x) 1709 if x.ndim != 1: 1710 _raise_value_error("Input x must be 1-D, but got dimension=", x.ndim) 1711 N = N or x.size 1712 if not isinstance(N, int): 1713 _raise_type_error("Input N must be an integer.") 1714 if N <= 0: 1715 _raise_value_error("Input N must > 0.") 1716 if not isinstance(increasing, bool): 1717 _raise_type_error("increasing must be a bool.") 1718 exponent = _iota(x.dtype, N, increasing) 1719 x = F.expand_dims(x, 1) 1720 exponent = F.expand_dims(exponent, 0) 1721 return F.tensor_pow(x, exponent) 1722 1723 1724def indices(dimensions, dtype=mstype.int32, sparse=False): 1725 """ 1726 Returns an array representing the indices of a grid. 1727 1728 Computes an array where the subarrays contain index values 0, 1, … 1729 varying only along the corresponding axis. 1730 1731 Args: 1732 dimensions (tuple or list of ints): The shape of the grid. 1733 dtype (:class:`mindspore.dtype`, optional): Data type of the result. 1734 sparse (boolean, optional): Defaults to False. Return a sparse 1735 representation of the grid instead of a dense representation. 1736 1737 Returns: 1738 Tensor or tuple of Tensor, If `sparse` is False, returns one array 1739 of grid indices, ``grid.shape = (len(dimensions),) + tuple(dimensions)``. 1740 If sparse is True, returns a tuple of arrays, with 1741 ``grid[i].shape = (1, ..., 1, dimensions[i], 1, ..., 1)`` with 1742 ``dimensions[i]`` in the `ith` place 1743 1744 Raises: 1745 TypeError: if input dimensions is not a tuple or list. 1746 1747 Supported Platforms: 1748 ``Ascend`` ``GPU`` ``CPU`` 1749 1750 Examples: 1751 >>> import mindspore.numpy as np 1752 >>> grid = np.indices((2, 3)) 1753 >>> print(grid) 1754 [Tensor(shape=[2, 3], dtype=Int32, value= 1755 [[0, 0, 0], 1756 [1, 1, 1]]), Tensor(shape=[2, 3], dtype=Int32, value= 1757 [[0, 1, 2], 1758 [0, 1, 2]])] 1759 """ 1760 if not isinstance(dimensions, (tuple, list)): 1761 _raise_type_error('Shape of the grid must be tuple or list') 1762 grids = () 1763 for d in dimensions: 1764 grids += (arange(d, dtype=dtype),) 1765 return meshgrid(*grids, sparse=sparse, indexing='ij') 1766 1767 1768def _check_window_size(x): 1769 """Returns True if window size is greater than 1.""" 1770 if not isinstance(x, int): 1771 _raise_type_error('the number fo points should be an int') 1772 return x > 1 1773 1774 1775def bartlett(M): 1776 """ 1777 Returns the Bartlett window. 1778 The Bartlett window is very similar to a triangular window, except that the 1779 end points are at zero. It is often used in signal processing for tapering a 1780 signal, without generating too much ripple in the frequency domain. 1781 1782 Args: 1783 M (int): Number of points in the output window. If zero or less, an empty 1784 array is returned. 1785 1786 Returns: 1787 Tensor, the triangular window, with the maximum value normalized to one 1788 (the value one appears only if the number of samples is odd), with the 1789 first and last samples equal to zero. 1790 1791 Raises: 1792 TypeError: if `M` is not an int. 1793 1794 Supported Platforms: 1795 ``Ascend`` ``GPU`` ``CPU`` 1796 1797 Examples: 1798 >>> import mindspore.numpy as np 1799 >>> print(np.bartlett(12)) 1800 [0. 0.18181819 0.36363637 0.5454545 0.72727275 0.9090909 1801 0.9090909 0.72727275 0.5454545 0.36363637 0.18181819 0. ] 1802 """ 1803 if not _check_window_size(M): 1804 return ones(_max(0, M)) 1805 n = _iota(mstype.float32, M) 1806 m_minus_one = _to_tensor(M - 1) 1807 return _to_tensor(1) - F.absolute(_to_tensor(2)*n - m_minus_one)/m_minus_one 1808 1809 1810def blackman(M): 1811 """ 1812 Returns the Blackman window. 1813 The Blackman window is a taper formed by using the first three terms of a 1814 summation of cosines. It was designed to have close to the minimal leakage 1815 possible. It is close to optimal, only slightly worse than a Kaiser window. 1816 1817 Args: 1818 M (int): Number of points in the output window. If zero or less, an empty 1819 array is returned. 1820 1821 Returns: 1822 Tensor, the window, with the maximum value normalized to one (the value 1823 one appears only if the number of samples is odd). 1824 1825 Raises: 1826 TypeError: if `M` is not an int. 1827 1828 Supported Platforms: 1829 ``Ascend`` ``GPU`` ``CPU`` 1830 1831 Examples: 1832 >>> import mindspore.numpy as np 1833 >>> print(np.blackman(12)) 1834 [-1.4901161e-08 3.2606430e-02 1.5990365e-01 4.1439798e-01 1835 7.3604518e-01 9.6704674e-01 9.6704674e-01 7.3604518e-01 1836 4.1439798e-01 1.5990365e-01 3.2606430e-02 -1.4901161e-08] 1837 """ 1838 if not _check_window_size(M): 1839 return ones(_max(0, M)) 1840 n_doubled = arange(1 - M, M, 2, dtype=mstype.float32) 1841 return (_to_tensor(0.42) + _to_tensor(0.5)*F.cos(_to_tensor(pi/(M - 1))*n_doubled) + 1842 _to_tensor(0.08)*F.cos(_to_tensor(2*pi/(M - 1))*n_doubled)) 1843 1844 1845def hamming(M): 1846 """ 1847 Returns the Hamming window. 1848 The Hamming window is a taper formed by using a weighted cosine. 1849 1850 Args: 1851 M (int): Number of points in the output window. If zero or less, an empty 1852 array is returned. 1853 1854 Returns: 1855 Tensor, the window, with the maximum value normalized to one (the value 1856 one appears only if the number of samples is odd). 1857 1858 Raises: 1859 TypeError: if `M` is not an int. 1860 1861 Supported Platforms: 1862 ``Ascend`` ``GPU`` ``CPU`` 1863 1864 Examples: 1865 >>> import mindspore.numpy as np 1866 >>> print(np.hamming(12)) 1867 [0.08000001 0.15302339 0.34890914 0.6054648 0.841236 0.9813669 1868 0.9813668 0.8412359 0.6054647 0.34890908 0.15302327 0.08000001] 1869 """ 1870 if not _check_window_size(M): 1871 return ones(_max(0, M)) 1872 n = _iota(mstype.float32, M) 1873 return _to_tensor(0.54) - _to_tensor(0.46)*F.cos(_to_tensor(2*pi/(M - 1))*n) 1874 1875 1876def hanning(M): 1877 """ 1878 Returns the Hanning window. 1879 The Hanning window is a taper formed by using a weighted cosine. 1880 1881 Args: 1882 M (int): Number of points in the output window. If zero or less, an empty 1883 array is returned. 1884 1885 Returns: 1886 Tensor, the window, with the maximum value normalized to one (the value 1887 one appears only if the number of samples is odd). 1888 1889 Raises: 1890 TypeError: if `M` is not an int. 1891 1892 Supported Platforms: 1893 ``Ascend`` ``GPU`` ``CPU`` 1894 1895 Examples: 1896 >>> import mindspore.numpy as np 1897 >>> print(np.hanning(12)) 1898 [0. 0.07937324 0.29229254 0.5711574 0.8274304 0.9797465 1899 0.97974646 0.82743025 0.5711573 0.29229245 0.07937312 0. ] 1900 """ 1901 if not _check_window_size(M): 1902 return ones(_max(0, M)) 1903 n = _iota(mstype.float32, M) 1904 return _to_tensor(0.5) - _to_tensor(0.5)*F.cos(_to_tensor(2*pi/(M - 1))*n) 1905 1906 1907@constexpr 1908def tri_indices(n, k=0, m=None, upper=True): 1909 """Returns triu/tril indices in o(nm) time.""" 1910 if not isinstance(n, (int, float, bool)): 1911 raise TypeError("Input n must be a number.") 1912 if not isinstance(k, (int, float, bool)): 1913 raise TypeError("Input k must be a number.") 1914 if m is None: 1915 m = n 1916 elif not isinstance(m, (int, float, bool)): 1917 raise TypeError("Input m must be a number.") 1918 if upper: 1919 compare = operator.ge 1920 else: 1921 compare = operator.le 1922 x_coordinate = [] 1923 y_coordinate = [] 1924 # math.ceil is used to match numpy's behaviour 1925 for i in range(math.ceil(n)): 1926 curr_limit = i + k 1927 for j in range(math.ceil(m)): 1928 if compare(j, curr_limit): 1929 x_coordinate.append(i) 1930 y_coordinate.append(j) 1931 return asarray_const(x_coordinate), asarray_const(y_coordinate) 1932 1933 1934def triu_indices(n, k=0, m=None): 1935 """ 1936 Returns the indices for the upper-triangle of an (n, m) array. 1937 1938 Args: 1939 n (int): The size of the arrays for which the returned indices will be valid. 1940 k (int, optional): Diagonal offset, default is 0. 1941 m (int, optional): The column dimension of the arrays for which the returned 1942 arrays will be valid. By default `m` is taken equal to `n`. 1943 1944 Returns: 1945 The indices for the triangle. The returned tuple contains two tensors, each 1946 with the indices along one dimension of the tensor. 1947 1948 Raises: 1949 TypeError: if `n`, `k`, `m` are not numbers. 1950 1951 Supported Platforms: 1952 ``Ascend`` ``GPU`` ``CPU`` 1953 1954 Examples: 1955 >>> import mindspore.numpy as np 1956 >>> print(np.triu_indices(3)) 1957 (Tensor(shape=[6], dtype=Int32, value= [0, 0, 0, 1, 1, 2]), 1958 Tensor(shape=[6], dtype=Int32, value= [0, 1, 2, 1, 2, 2])) 1959 """ 1960 return tri_indices(n, k, m, True) 1961 1962 1963def tril_indices(n, k=0, m=None): 1964 """ 1965 Returns the indices for the lower-triangle of an (n, m) array. 1966 1967 Args: 1968 n (int): The size of the arrays for which the returned indices will be valid. 1969 k (int, optional): Diagonal offset, default is 0. 1970 m (int, optional): The column dimension of the arrays for which the returned 1971 arrays will be valid. By default `m` is taken equal to `n`. 1972 1973 Returns: 1974 The indices for the triangle. The returned tuple contains two tensors, each 1975 with the indices along one dimension of the tensor. 1976 1977 Raises: 1978 TypeError: if `n`, `k`, `m` are not numbers. 1979 1980 Supported Platforms: 1981 ``Ascend`` ``GPU`` ``CPU`` 1982 1983 Examples: 1984 >>> import mindspore.numpy as np 1985 >>> print(np.tril_indices(3)) 1986 (Tensor(shape=[6], dtype=Int32, value= [0, 1, 1, 2, 2, 2]), 1987 Tensor(shape=[6], dtype=Int32, value= [0, 0, 1, 0, 1, 2])) 1988 """ 1989 return tri_indices(n, k, m, False) 1990 1991 1992def triu_indices_from(arr, k=0): 1993 """ 1994 Returns the indices for the upper-triangle of `arr`. 1995 1996 Args: 1997 arr (Union[Tensor, list, tuple]): 2-dimensional array. 1998 k (int, optional): Diagonal offset, default is 0. 1999 2000 Returns: 2001 triu_indices_from, tuple of 2 tensor, shape(N) 2002 Indices for the upper-triangle of `arr`. 2003 2004 Raises: 2005 TypeError: if `arr` cannot be converted to tensor, or `k` is not a number. 2006 ValueError: if `arr` cannot be converted to a 2-dimensional tensor. 2007 2008 Supported Platforms: 2009 ``Ascend`` ``GPU`` ``CPU`` 2010 2011 Examples: 2012 >>> import mindspore.numpy as np 2013 >>> tensor = np.ones((3,3)) 2014 >>> print(np.triu_indices_from(tensor)) 2015 (Tensor(shape=[6], dtype=Int32, value= [0, 0, 0, 1, 1, 2]), 2016 Tensor(shape=[6], dtype=Int32, value= [0, 1, 2, 1, 2, 2])) 2017 """ 2018 arr = asarray(arr) 2019 if arr.ndim != 2: 2020 _raise_value_error("input array must be 2-d") 2021 return triu_indices(arr.shape[-2], k=k, m=arr.shape[-1]) 2022 2023 2024def tril_indices_from(arr, k=0): 2025 """ 2026 Returns the indices for the lower-triangle of `arr`. 2027 2028 Args: 2029 arr (Union[Tensor, list, tuple]): 2-dimensional array. 2030 k (int, optional): Diagonal offset, default is 0. 2031 2032 Returns: 2033 triu_indices_from, tuple of 2 tensor, shape(N) 2034 Indices for the upper-triangle of `arr`. 2035 2036 Raises: 2037 TypeError: if `arr` cannot be converted to tensor, or `k` is not a number. 2038 ValueError: if `arr` cannot be converted to a 2-dimensional tensor. 2039 2040 Supported Platforms: 2041 ``Ascend`` ``GPU`` ``CPU`` 2042 2043 Examples: 2044 >>> import mindspore.numpy as np 2045 >>> tensor = np.ones((3,3)) 2046 >>> print(np.tril_indices_from(tensor)) 2047 (Tensor(shape=[6], dtype=Int32, value= [0, 1, 1, 2, 2, 2]), 2048 Tensor(shape=[6], dtype=Int32, value= [0, 0, 1, 0, 1, 2])) 2049 """ 2050 arr = asarray(arr) 2051 if arr.ndim != 2: 2052 _raise_value_error("input array must be 2-d") 2053 return tril_indices(arr.shape[-2], k=k, m=arr.shape[-1]) 2054 2055 2056def histogram_bin_edges(a, bins=10, range=None, weights=None): # pylint: disable=redefined-builtin 2057 """ 2058 Function to calculate only the edges of the bins used by the histogram function. 2059 2060 Note: 2061 String values for `bins` is not supported. 2062 2063 Args: 2064 a (Union[int, float, bool, list, tuple, Tensor]): Input data. The histogram 2065 is computed over the flattened array. 2066 bins ((Union[int, tuple, list, Tensor])): If `bins` is an int, it defines the number 2067 of equal-width bins in the given range (10, by default). If `bins` is a 2068 sequence, it defines the bin edges, including the rightmost edge, 2069 allowing for non-uniform bin widths. 2070 range((float, float), optional): The lower and upper range of the bins. If 2071 not provided, `range` is simply ``(a.min(), a.max())``. Values outside 2072 the range are ignored. The first element of the range must be less than 2073 or equal to the second. Default is None. 2074 weights(Union[int, float, bool, list, tuple, Tensor], optional): An array of weights, 2075 of the same shape as `a`. Each value in `a` only contributes its associated weight 2076 towards the bin count (instead of 1). This is currently not used by any of the bin 2077 estimators, but may be in the future. Default is None. 2078 2079 Returns: 2080 Tensor, the edges to pass into `histogram`. 2081 2082 Supported Platforms: 2083 ``Ascend`` ``GPU`` ``CPU`` 2084 2085 Raises: 2086 TypeError: if `bins` is an array and not one-dimensional. 2087 2088 Examples: 2089 >>> import mindspore.numpy as np 2090 >>> arr = np.array([0, 0, 0, 1, 2, 3, 3, 4, 5]) 2091 >>> print(np.histogram_bin_edges(arr, bins=2)) 2092 [0. 2.5 5. ] 2093 """ 2094 a = _to_tensor(a) 2095 if weights is not None: 2096 weights = _to_tensor(weights) 2097 if F.shape(a) != F.shape(weights): 2098 _raise_value_error('weights should have the same shape as a') 2099 if isinstance(bins, (tuple, list, Tensor)): 2100 bins = _to_tensor(bins) 2101 if F.rank(bins) != 1: 2102 _raise_value_error('`bins` must be 1d, when an array') 2103 return bins 2104 if isinstance(bins, str): 2105 # linspace does not support Tensor for num 2106 _raise_unimplemented_error('string value for `bins` not implemented') 2107 a = a.ravel().astype(mstype.float32) 2108 if range is None: 2109 start = F.reduce_min(a) 2110 end = F.reduce_max(a) 2111 else: 2112 if not isinstance(range, (list, tuple)) or len(range) != 2: 2113 _raise_value_error('`range` should take the form (start, end)') 2114 start, end = range 2115 if start > end: 2116 _raise_value_error('max must be larger than min in range parameter') 2117 start, end = _to_tensor(start, end) 2118 no_range = (end - start) == 0 2119 start = where(no_range, start - 0.5, start) 2120 end = where(no_range, end + 0.5, end) 2121 return linspace(start, end, bins + 1) 2122 2123 2124def _pad_empty(arr, pad_width): 2125 """ 2126 pads the array with constant values, used in mode: "empty" 2127 """ 2128 dtype = arr.dtype 2129 for i in range(arr.ndim): 2130 shape = arr.shape 2131 pad_before = () 2132 pad_after = () 2133 # To avoid any memory issues, we don't make tensor with 0s in their shapes 2134 if pad_width[i][0] > 0: 2135 pad_before += (empty(_tuple_setitem(shape, i, pad_width[i][0]), dtype=dtype),) 2136 if pad_width[i][1] > 0: 2137 pad_after += (empty(_tuple_setitem(shape, i, pad_width[i][1]), dtype=dtype),) 2138 tensor_with_pad = pad_before + (arr,) + pad_after 2139 arr = concatenate(tensor_with_pad, axis=i) 2140 return arr 2141 2142 2143def _pad_constant(arr, pad_width, value): 2144 """ 2145 pads the array with constant values, used in mode: "constant" 2146 """ 2147 dtype = arr.dtype 2148 for i in range(arr.ndim): 2149 shape = arr.shape 2150 pad_before = () 2151 pad_after = () 2152 # To avoid any memory issues, we don't make tensor with 0s in their shapes 2153 if pad_width[i][0] > 0: 2154 pad_before += (full(_tuple_setitem(shape, i, pad_width[i][0]), value[i][0], dtype=dtype),) 2155 if pad_width[i][1] > 0: 2156 pad_after += (full(_tuple_setitem(shape, i, pad_width[i][1]), value[i][1], dtype=dtype),) 2157 tensor_with_pad = pad_before + (arr,) + pad_after 2158 arr = concatenate(tensor_with_pad, axis=i) 2159 return arr 2160 2161 2162def _pad_statistic(arr, pad_width, stat_length, stat_op): 2163 """ 2164 pads the array with values calculated along the given axis, used in mode: "maximum", 2165 "minimum", "mean" 2166 """ 2167 ndim = arr.ndim 2168 shape = arr.shape 2169 if stat_length is None: 2170 stat_length = _make_stat_length(shape) 2171 else: 2172 stat_length = _convert_pad_to_nd(stat_length, ndim) 2173 stat_length = _limit_stat_length(stat_length, shape) 2174 for i in range(ndim): 2175 pad_before = stat_op(_slice_along_axis(arr, i, 0, stat_length[i][0]), i) 2176 pad_before = (F.tile(pad_before, _tuple_setitem((1,)*ndim, i, pad_width[i][0])),) 2177 pad_after = stat_op(_slice_along_axis(arr, i, shape[i]-stat_length[i][1], shape[i]), i) 2178 pad_after = (F.tile(pad_after, _tuple_setitem((1,)*ndim, i, pad_width[i][1])),) 2179 tensor_with_pad = pad_before + (arr,) + pad_after 2180 arr = concatenate(tensor_with_pad, axis=i) 2181 return arr 2182 2183 2184def _pad_edge(arr, pad_width): 2185 """pad_edge is equivalent to pad_statistic with stat_lenght=1, used in mode:"edge".""" 2186 def identity_op(arr, axis): 2187 return arr 2188 return _pad_statistic(arr, pad_width, 1, identity_op) 2189 2190 2191def _pad_wrap(arr, pad_width): 2192 """The behaviour of wrap mode is consistent with jax.numpy, used in mode:"wrap".""" 2193 ndim = arr.ndim 2194 shape = arr.shape 2195 for i in range(ndim): 2196 padsize_before = pad_width[i][0] % shape[i] 2197 padsize_after = pad_width[i][1] % shape[i] 2198 total_repeats = pad_width[i][0] // shape[i] + 1 + pad_width[i][1] // shape[i] 2199 tensor_with_pad = () 2200 # To avoid any memory issues, we don't make tensor with 0s in their shapes 2201 if padsize_before > 0: 2202 tensor_with_pad += (_slice_along_axis(arr, i, shape[i]-padsize_before, shape[i]),) 2203 tensor_with_pad += (F.tile(arr, _tuple_setitem((1,)*ndim, i, total_repeats)),) 2204 if padsize_after > 0: 2205 tensor_with_pad += (_slice_along_axis(arr, i, 0, padsize_after),) 2206 arr = concatenate(tensor_with_pad, axis=i) 2207 return arr 2208 2209 2210def _pad_linear(arr, pad_width, end_values): 2211 """Pads the arr with linear range values, used in mode: "linear_ramp".""" 2212 ndim = arr.ndim 2213 shape = arr.shape 2214 dtype = arr.dtype 2215 end_values = _convert_pad_to_nd(end_values, ndim) 2216 for i in range(ndim): 2217 left_value = _slice_along_axis(arr, i, 0, 1) 2218 right_value = _slice_along_axis(arr, i, shape[i]-1, shape[i]) 2219 pad_before = () 2220 pad_after = () 2221 if pad_width[i][0] > 0: 2222 pad_before = (linspace(end_values[i][0], left_value, num=pad_width[i][0], 2223 endpoint=False, dtype=dtype, axis=i).squeeze(i+1),) 2224 if pad_width[i][1] > 0: 2225 pad_after = linspace(right_value, end_values[i][1], num=pad_width[i][1]+1, 2226 endpoint=True, dtype=dtype, axis=i).squeeze(i+1) 2227 pad_after = (_slice_along_axis(pad_after, i, 1, pad_width[i][1]+1),) 2228 tensor_with_pad = pad_before + (arr,) + pad_after 2229 arr = concatenate(tensor_with_pad, axis=i) 2230 return arr 2231 2232 2233def _add_pads_before(arr, pad_args, mode): 2234 """handle pads before the array""" 2235 idx, array_length, times_to_pad_before, additional_pad_before, reflect_type = pad_args 2236 curr_pad = None 2237 endpoint_adder = None 2238 edge_before = _slice_along_axis(arr, idx, 0, 1) 2239 if mode == "reflect": 2240 endpoint_adder = 1 2241 else: 2242 endpoint_adder = 0 2243 # Deal with paddings before the original array 2244 for times in range(times_to_pad_before): 2245 if times < times_to_pad_before - 1: 2246 endpoint = array_length 2247 else: 2248 endpoint = additional_pad_before + endpoint_adder 2249 if endpoint != endpoint_adder: 2250 curr_pad = _slice_along_axis(arr, idx, endpoint_adder, endpoint) 2251 curr_pad = flip(curr_pad, axis=idx) 2252 if reflect_type == "odd": 2253 curr_pad = 2 * edge_before - curr_pad 2254 arr = P.Concat(idx)((curr_pad, arr)) 2255 edge_before = _slice_along_axis(arr, idx, 0, 1) 2256 return arr 2257 2258 2259def _add_pads_after(arr, pad_args, mode): 2260 """handle pads after the array""" 2261 idx, array_length, times_to_pad_after, additional_pad_after, reflect_type = pad_args 2262 curr_pad = None 2263 endpoint_adder = None 2264 edge_end = _slice_along_axis(arr, idx, arr.shape[idx]-1, arr.shape[idx]) 2265 if mode == "reflect": 2266 endpoint_adder = 1 2267 else: 2268 endpoint_adder = 0 2269 # Deal with paddings after the original array 2270 for times in range(times_to_pad_after): 2271 if times < times_to_pad_after - 1: 2272 startpoint = arr.shape[idx] - array_length 2273 else: 2274 startpoint = arr.shape[idx] - additional_pad_after - endpoint_adder 2275 if startpoint != arr.shape[idx] - endpoint_adder: 2276 curr_pad = _slice_along_axis(arr, idx, startpoint, arr.shape[idx] - endpoint_adder) 2277 curr_pad = flip(curr_pad, axis=idx) 2278 if reflect_type == "odd": 2279 curr_pad = 2 * edge_end - curr_pad 2280 arr = P.Concat(idx)((arr, curr_pad)) 2281 edge_end = _slice_along_axis(arr, idx, arr.shape[idx]-1, arr.shape[idx]) 2282 return arr 2283 2284 2285def _pad_symmetric(arr, pad_width, reflect_type): 2286 """pad the array with symmetric paddings""" 2287 for i in range(arr.ndim): 2288 array_length = arr.shape[i] 2289 2290 has_pad_before = (pad_width[i][0] > 0) 2291 has_pad_after = (pad_width[i][1] > 0) 2292 2293 times_to_pad_before = pad_width[i][0] // array_length + 1 2294 additional_pad_before = pad_width[i][0] % array_length 2295 times_to_pad_after = pad_width[i][1] // array_length + 1 2296 additional_pad_after = pad_width[i][1] % array_length 2297 if has_pad_before: 2298 # Deal with paddings before the original array 2299 pad_args = (i, array_length, times_to_pad_before, additional_pad_before, reflect_type) 2300 arr = _add_pads_before(arr, pad_args, "symmetric") 2301 if has_pad_after: 2302 # Deal with paddings after the original array 2303 pad_args = (i, array_length, times_to_pad_after, additional_pad_after, reflect_type) 2304 arr = _add_pads_after(arr, pad_args, "symmetric") 2305 return arr 2306 2307 2308def _pad_reflect(arr, pad_width, reflect_type): 2309 """ 2310 pad the array with reflect paddings, this is very similar to symmetric paddings, 2311 but differs at how edges are selected. 2312 """ 2313 for i in range(arr.ndim): 2314 array_length = arr.shape[i] 2315 if array_length == 1: 2316 total_repeats = pad_width[i][0] + pad_width[i][1] + 1 2317 arr = F.tile(arr, _tuple_setitem((1,)*arr.ndim, i, total_repeats)) 2318 else: 2319 has_pad_before = (pad_width[i][0] > 0) 2320 has_pad_after = (pad_width[i][1] > 0) 2321 2322 pad_size = array_length - 1 2323 times_to_pad_before = pad_width[i][0] // pad_size + 1 2324 additional_pad_before = pad_width[i][0] % pad_size 2325 times_to_pad_after = pad_width[i][1] // pad_size + 1 2326 additional_pad_after = pad_width[i][1] % pad_size 2327 if has_pad_before: 2328 # Deal with paddings before the original array 2329 pad_args = (i, array_length, times_to_pad_before, additional_pad_before, reflect_type) 2330 arr = _add_pads_before(arr, pad_args, "reflect") 2331 if has_pad_after: 2332 # Deal with paddings after the original array 2333 pad_args = (i, array_length, times_to_pad_after, additional_pad_after, reflect_type) 2334 arr = _add_pads_after(arr, pad_args, "reflect") 2335 return arr 2336 2337 2338def _pad_func(arr, pad_width, func, **kwargs): 2339 """applies padding function over different axis.""" 2340 # first creates a padded array with fixed length. 2341 arr_dim = arr.ndim 2342 pad_width = _convert_pad_to_nd(pad_width, arr_dim) 2343 arr = _pad_empty(arr, pad_width) 2344 for i in range(arr_dim): 2345 # function signature: padding_func(tensor, iaxis_pad_width, iaxis, kwargs) 2346 arr = apply_along_axis(func, i, arr, pad_width[i], i, kwargs) 2347 return arr 2348 2349 2350@constexpr 2351def _make_stat_length(shape): 2352 """converts the stat_length values.""" 2353 return tuple((shape[i], shape[i]) for i, _ in enumerate(shape)) 2354 2355 2356@constexpr 2357def _limit_stat_length(stat_length, shape): 2358 """limits the stat_length to current array length along given dimension.""" 2359 return tuple((min(stat_pair[0], shape[i]), min(stat_pair[1], shape[i])) for i, stat_pair in enumerate(stat_length)) 2360 2361 2362@constexpr 2363def _convert_pad_to_nd(pad_values, ndim): 2364 """broadcasts the pad_values to (ndim * 2)""" 2365 if not isinstance(pad_values, (int, list, tuple, Tensor)): 2366 raise TypeError( 2367 "pad_width, stat_length, constant_values or end_values should only be int, list, tuple or tensor") 2368 pad_tensor = _to_tensor(pad_values) 2369 pad_shape = pad_tensor.shape 2370 if not pad_shape: 2371 pad_values = tuple((((pad_values,) * 2) for i in range(ndim))) 2372 elif pad_shape == (1,): 2373 pad_values = tuple((tuple(pad_values) * 2) for i in range(ndim)) 2374 elif pad_shape == (2,): 2375 pad_values = tuple(tuple(pad_values) for i in range(ndim)) 2376 elif pad_shape == (1, 2): 2377 pad_values = tuple(tuple(pad_values[0]) for i in range(ndim)) 2378 elif pad_shape == (ndim, 2): 2379 pad_values = tuple(tuple(pad_pair) for pad_pair in pad_values) 2380 else: 2381 raise ValueError(f"input values must be able to broadcast to {(ndim, 2)}") 2382 return pad_values 2383 2384 2385def pad(arr, pad_width, mode="constant", stat_length=None, constant_values=0, 2386 end_values=0, reflect_type="even", **kwargs): 2387 """ 2388 Pads an array. 2389 2390 Note: 2391 Currently, `median` mode is not supported. `reflect` and `symmetric` mode 2392 only supports GPU backend. 2393 2394 Args: 2395 arr (Union[list, tuple, Tensor]): The array to pad. 2396 pad_width (Union[int, tuple, list]): Number of values padded to the edges of 2397 each axis. :class:`((before_1, after_1), ... (before_N, after_N))` creates 2398 unique pad widths for each axis. :class:`((before, after),)` yields same 2399 before and after pad for each axis. :class:`(pad,)` or int is a shortcut 2400 for :class:`before = after = pad width` for all axes. 2401 mode (string, optional): 2402 One of the following string values: 2403 2404 - constant (default): Pads with a constant value. 2405 - edge: Pads with the edge values of `arr`. 2406 - linear_ramp: Pads with the linear ramp between end_value and the `arr` edge value. 2407 - maximum: Pads with the maximum value of all or part of the vector along each axis. 2408 - mean: Pads with the mean value of all or part of the vector along each axis. 2409 - median: Pads with the median value of all or part of the vector along each axis. 2410 - minimum: Pads with the minimum value of all or part of the vector along each axis. 2411 - reflect: Pads with the reflection of the vector mirrored on the first 2412 and last values of the vector along each axis. 2413 - symmetric: Pads with the reflection of the vector mirrored along the edge 2414 of the `arr`. 2415 - wrap: Pads with the wrap of the vector along the axis. The first values 2416 are used to pad the end and the end values are used to pad the beginning. 2417 - empty: Pads with undefined values. 2418 - <function>: The padding function, if used, should modify and return a new 1-d tensor. 2419 It has the following signature: :class:`padding_func(tensor, iaxis_pad_width, iaxis, kwargs)` 2420 stat_length (Union[tuple, list, int], optional): Used in \'maximum\', \'mean\', 2421 \'median\', and \'minimum\'. Number of values at edge of each axis used 2422 to calculate the statistic value. :class:`((before_1, after_1), ... (before_N, after_N))` 2423 creates unique statistic lengths for each axis. :class:`((before, after),)` 2424 yields same before and after statistic lengths for each axis. :class:`(stat_length,)` 2425 or int is a shortcut for :class:`before = after = statistic length` for all 2426 axes. Default is :class:`None`, to use the entire axis. 2427 constant_values (Union[tuple, list, int], optional): 2428 Used in :class:`constant mode`. The values to set the padded values for each 2429 axis. :class:`((before_1, after_1), ... (before_N, after_N))` creates unique pad 2430 constants for each axis. :class:`((before, after),)` yields same before and 2431 after constants for each axis. :class:`(constant,)` or :class:`constant` is 2432 a shortcut for :class:`before = after = constant` for all axes. Default is 0. 2433 end_values (Union[tuple, list, int], optional): Used in 'linear_ramp'. The values 2434 used for the ending value of the linear_ramp and that will form the edge of 2435 the padded `arr`. :class:`((before_1, after_1), ... (before_N, after_N))` 2436 unique end values for each axis. :class:`((before, after),)` yields same before 2437 and after end values for each axis. :class:`(constant,)` or :class:`constant` 2438 is a shortcut for :class:`before = after = constant` for all axes. Default is 0. 2439 reflect_type(string, optional) can choose between \'even\' and \'odd\'. Used in 2440 \'reflect\', and \'symmetric\'. The \'even\' style is the default with an 2441 unaltered reflection around the edge value. For the \'odd\' style, the extended 2442 part of the `arr` is created by subtracting the reflected values from two times 2443 the edge value. 2444 2445 Returns: 2446 Padded tensor of rank equal to `arr` with shape increased according to `pad_width`. 2447 2448 Raises: 2449 TypeError: if `arr`, `pad_width`, `stat_length`, `constant_values` or `end_values` 2450 have types not specified above. 2451 ValueError: if `mode` cannot be recognized, or if `pad_width`, `stat_length`, 2452 `constant_values`, `end_values` cannot broadcast to :class:`(arr.ndim, 2)`, 2453 or if keyword arguments got unexpected inputs. 2454 NotImplementedError: if mode is function or '/median'/. 2455 2456 Supported Platforms: 2457 ``Ascend`` ``GPU`` ``CPU`` 2458 2459 Examples: 2460 >>> import mindspore.numpy as np 2461 >>> tensor = np.array([1., 2., 3., 4., 5.]) 2462 >>> print(np.pad(tensor, (3, 4))) 2463 [0. 0. 0. 1. 2. 3. 4. 5. 0. 0. 0. 0.] 2464 >>> print(np.pad(tensor, (3, 4), mode="wrap")) 2465 [3. 4. 5. 1. 2. 3. 4. 5. 1. 2. 3. 4.] 2466 >>> print(np.pad(tensor, (3, 4), mode="linear_ramp", end_values=(10, 10))) 2467 [10. 7. 4. 1. 2. 3. 4. 5. 6.25 7.5 8.75 10. ] 2468 """ 2469 arr = _to_tensor(arr) 2470 if arr.ndim == 0: 2471 return arr 2472 pad_width = _convert_pad_to_nd(pad_width, arr.ndim) 2473 stat_func = {"maximum": _reduce_max_keepdims, 2474 "minimum": _reduce_min_keepdims, 2475 "mean": _reduce_mean_keepdims, 2476 "median": "not implemented"} 2477 2478 if mode not in ("constant", "maximum", "minimum", "mean", "median", "edge", 2479 "wrap", "linear_ramp", "symmetric", "reflect", "empty") and \ 2480 not _callable(arr, mode): 2481 _raise_value_error("Input mode not supported.") 2482 2483 if mode == "constant": 2484 constant_values = _convert_pad_to_nd(constant_values, arr.ndim) 2485 return _pad_constant(arr, pad_width, constant_values) 2486 if mode in ("maximum", "minimum", "mean", "median"): 2487 # support median mode once P.Sort/P.Median is supported on GPU/CPU 2488 if mode == "median": 2489 _raise_unimplemented_error("median mode is not supported yet") 2490 return _pad_statistic(arr, pad_width, stat_length, stat_func[mode]) 2491 if mode == "edge": 2492 return _pad_edge(arr, pad_width) 2493 if mode == "wrap": 2494 return _pad_wrap(arr, pad_width) 2495 if mode == "linear_ramp": 2496 return _pad_linear(arr, pad_width, end_values) 2497 if mode == "symmetric": 2498 return _pad_symmetric(arr, pad_width, reflect_type) 2499 if mode == "reflect": 2500 return _pad_reflect(arr, pad_width, reflect_type) 2501 if mode == 'empty': 2502 return _pad_empty(arr, pad_width) 2503 return _pad_func(arr, pad_width, mode, **kwargs) 2504