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