• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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