|
- # Copyright 2020-2021 Huawei Technologies Co., Ltd
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- # ============================================================================
- """array operations, the function docs are adapted from Numpy API."""
- import math
- import operator
-
- import numpy as onp
-
- from ..common import Tensor
- from ..common import dtype as mstype
- from ..ops import operations as P
- from ..ops import functional as F
- from ..ops.primitive import constexpr
- from ..nn.layer.basic import tril as nn_tril
- from ..nn.layer.basic import triu as nn_triu
- from .._c_expression import Tensor as Tensor_
-
- from .utils import _check_input_for_asarray, _deep_list, _deep_tensor_to_nparray, \
- _check_input_tensor, _convert_64_to_32, _get_dtype_from_scalar, \
- _expand, _to_tensor, _slice_along_axis, _callable
- from .utils_const import _raise_value_error, _empty, _max, _min, \
- _check_same_type, _is_shape_empty, _check_shape, _check_dtype, _tile_size, _abs, \
- _raise_type_error, _expanded_shape, _check_is_float, _iota, _type_convert, \
- _canonicalize_axis, _list_comprehensions, _ceil, _tuple_slice, _raise_unimplemented_error, \
- _tuple_setitem
- from .array_ops import ravel, concatenate, broadcast_arrays, reshape, broadcast_to, flip, \
- apply_along_axis, where, moveaxis
- from .dtypes import nan, pi
-
- # According to official numpy reference, the dimension of a numpy array must be less
- # than 32
- MAX_NUMPY_DIMS = 32
- # All types that can be accepted as "array_like" parameters in graph mode.
- ARRAY_TYPES = (int, float, bool, list, tuple, Tensor)
-
- _reduce_min_keepdims = P.ReduceMin(True)
- _reduce_max_keepdims = P.ReduceMax(True)
- _reduce_mean_keepdims = P.ReduceMean(True)
-
-
- def array(obj, dtype=None, copy=True, ndmin=0):
- """
- Creates a tensor.
-
- This function creates tensors from an array-like object.
-
- Args:
- obj (Union[int, float, bool, list, tuple]): Input data, in any form that
- can be converted to a `Tensor`. This includes Tensor, list, tuple and numbers.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, can
- be in format of np.int32, or \'int32\'. If dtype is :class:`None`, the data type
- of the new tensor will be inferred from obj. Default is :class:`None`.
- copy (bool): If `True`, then the object is copied. Otherwise, a copy will
- only be made if necessary. Default: `True`.
- ndmin (int): Specifies the minimum number of dimensions that the resulting
- tensor should have. Ones will be pre-pended to the shape as needed to
- meet this requirement. Default: 0
-
- Returns:
- Tensor, generated tensor with the specified dtype.
-
- Raises:
- TypeError: If input arguments have types not specified above.
- ValueError: If input `obj` has different sizes at different dimensions.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.array([1,2,3]))
- [1 2 3]
- """
- if dtype is not None:
- dtype = _check_dtype(dtype)
- res = asarray(obj, dtype)
-
- if ndmin > res.ndim:
- if res.size == 0:
- _raise_value_error("Empty tensor cannot be expanded beyond the current dimension.")
- res = _expand(res, ndmin)
-
- if copy and isinstance(obj, Tensor):
- res = copy_(res)
- elif dtype is not None and dtype != res.dtype:
- res = res.astype(dtype)
-
- return res
-
-
- @constexpr
- def asarray_const(a, dtype=None):
- """Converts the input to tensor. Note here `a` cannot be tensor itself."""
- _check_input_for_asarray(a)
-
- if dtype is not None:
- dtype = _check_dtype(dtype)
-
- if isinstance(a, (float, int, bool)) and dtype is None:
- dtype = _get_dtype_from_scalar(a)
-
- if isinstance(a, (list, tuple)):
- # Convert all tuple/nested tuples to lists
- a = _deep_list(a)
- # Convert all tensor sub-elements to numpy arrays
- a = _deep_tensor_to_nparray(a)
- a = onp.asarray(a)
- if a.dtype is onp.dtype('object'):
- raise ValueError('Input array must have the same size across all dimensions.')
- # If dtype is not specified, we keep consistent with numpy decision
- # only exceptions are: we use int/float32
- if dtype is None:
- dtype = mstype.pytype_to_dtype(a.dtype)
- if dtype == mstype.float64:
- dtype = mstype.float32
- elif dtype == mstype.int64:
- dtype = mstype.int32
-
- if isinstance(a, onp.ndarray) and dtype is None:
- if a.dtype is onp.dtype('object'):
- raise TypeError(f"For Tensor conversion, the input_data is {a} that contains unsupported element.")
- dtype = mstype.pytype_to_dtype(a.dtype)
- a = Tensor.from_numpy(a)
-
- return Tensor(a, dtype=dtype)
-
-
- def asarray(a, dtype=None):
- """
- Converts the input to tensor.
-
- This function converts tensors from an array-like object.
-
- Args:
- a (Union[int, float, bool, list, tuple, Tensor]): Input data, in any form that can
- be converted to a `Tensor`. This includes Tensor, list, tuple and numbers.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, can
- be in format of np.int32, or \'int32\'. If dtype is :class:`None`, the data type
- of the new tensor will be inferred from obj. Default is :class:`None`.
-
- Returns:
- Tensor, generated tensor with the specified dtype.
-
- Raises:
- TypeError: If input arguments have types not specified above.
- ValueError: If input `a` has different sizes at different dimensions.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.asarray([1,2,3]))
- [1 2 3]
- """
- if dtype is not None:
- dtype = _check_dtype(dtype)
- if isinstance(a, Tensor):
- if dtype is None or dtype == a.dtype:
- return a
- return a.astype(dtype)
- return asarray_const(a, dtype)
-
-
- @constexpr
- def asfarray_const(a, dtype=mstype.float32):
- """Converts the input to tensor. Note here `a` cannot be tensor itself."""
- _check_input_for_asarray(a)
- if isinstance(a, (list, tuple)):
- # Convert all tuple/nested tuples to lists
- a = _deep_list(a)
- # Convert all tensor sub-elements to numpy arrays
- a = _deep_tensor_to_nparray(a)
- a = onp.asarray(a)
- if a.dtype is onp.dtype('object'):
- raise ValueError(f"For Tensor conversion, the input_data is {a} that contains unsupported element.")
- a = Tensor.from_numpy(a)
-
- return Tensor(a, dtype)
-
-
- def asfarray(a, dtype=mstype.float32):
- """
- Similar to asarray, converts the input to a float tensor.
-
- If non-float dtype is defined, this function will return a float32 tensor instead.
-
- Args:
- a (Union[int, float, bool, list, tuple, Tensor]): Input data, in any form that can
- be converted to a `Tensor`. This includes Tensor, list, tuple and numbers.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, can
- be in format of np.int32, or \'int32\'. If dtype is :class:`None`, the data type
- of the new tensor will be inferred from `a`. Default is :class:`mindspore.float32`.
-
-
- Returns:
- Tensor, generated tensor with the specified float dtype.
-
- Raises:
- TypeError: If input arguments have types not specified above.
- ValueError: If input `a` has different sizes at different dimensions.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.asfarray([1,2,3]))
- [1. 2. 3.]
- """
- if dtype is None:
- return asarray(a)
-
- dtype = _check_dtype(dtype)
- if dtype not in (mstype.float16, mstype.float32, mstype.float64):
- dtype = mstype.float32
-
- if isinstance(a, Tensor):
- return a.astype(dtype)
-
- return asfarray_const(a, dtype)
-
-
- def copy_(a):
- """
- Returns a tensor copy of the given object.
-
- Args:
- a (Union[int, float, bool, list, tuple, Tensor]): Input data, in any form that can
- be converted to a Tensor. This includes Tensor, list, tuple and numbers.
-
- Returns:
- Tensor, has the same data as `a`.
-
- Raises:
- TypeError: If input `a` has type not specified above.
- ValueError: If input `a` has different sizes at different dimensions.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> x = np.ones((2,2))
- >>> print(np.copy(x))
- [[1. 1.]
- [1. 1.]]
- """
- a = asarray(a)
- return a.copy()
-
-
- def ones(shape, dtype=mstype.float32):
- """
- Returns a new tensor of given shape and type, filled with ones.
-
- Args:
- shape (Union[int, tuple, list]): the shape of the new tensor.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype.
- Default is :class:`mstype.float32`.
-
- Returns:
- Tensor, with the designated `shape` and `dtype`, filled with ones.
-
- Raises:
- TypeError: If input arguments have types not specified above.
- ValueError: If `shape` entries have values :math:`< 0`.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.ones((2,2)))
- [[1. 1.]
- [1. 1.]]
- """
- shape = _check_shape(shape)
- dtype = _check_dtype(dtype)
- if _is_shape_empty(shape):
- return full(shape, 1.0, dtype)
- output = F.fill(dtype, shape, 1)
- return output
-
-
- def zeros(shape, dtype=mstype.float32):
- """
- Returns a new tensor of given shape and type, filled with zeros.
-
- Args:
- shape (Union[int, tuple, list]): the shape of the new tensor.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype.
- Default is :class:`mstype.float32`.
-
- Returns:
- Tensor, with the designated `shape` and `dtype`, filled with zeros.
-
- Raises:
- TypeError: If input arguments have types not specified above.
- ValueError: If `shape` entries have values :math:`< 0`.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.zeros((2,2)))
- [[0. 0.]
- [0. 0.]]
- """
- shape = _check_shape(shape)
- dtype = _check_dtype(dtype)
- if _is_shape_empty(shape):
- return full(shape, 0.0, dtype)
- output = F.fill(dtype, shape, 0)
- return output
-
-
- def full(shape, fill_value, dtype=None):
- """
- Returns a new tensor of given shape and type, filled with `fill_value`.
-
- Args:
- shape (Union[int, tuple(int), list(int)]): Shape of the new tensor, e.g.,
- :math:`(2, 3)` or :math:`2`.
- fill_value (Union[int, float, bool, list, tuple]): Scalar or array_like
- fill value.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype,
- if `dtype` is :class:`None`, the data type of the new tensor will be inferred from
- `fill_value`. Default is :class:`None`.
-
- Returns:
- Tensor, with the designated shape and dtype, filled with `fill_value`.
-
- Raises:
- TypeError: If input arguments have types not specified above.
- ValueError: If `shape` has entries < 0.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.full((2,2), True))
- [[True True]
- [True True]]
- """
- shape = _check_shape(shape)
- if not isinstance(fill_value, ARRAY_TYPES):
- _raise_type_error("fill value should be int, float, bool, list, tuple, Tensor, but got", fill_value)
- if dtype is not None:
- dtype = _check_dtype(dtype)
- else:
- if isinstance(fill_value, (int, float, bool)):
- dtype = _get_dtype_from_scalar(fill_value)
- if isinstance(fill_value, Tensor):
- dtype = fill_value.dtype
-
- if not _is_shape_empty(shape):
- if isinstance(fill_value, (int, float, bool)):
- return F.fill(dtype, shape, fill_value)
- if isinstance(fill_value, (list, tuple)):
- fill_value = asarray_const(fill_value)
- return broadcast_to(fill_value, shape)
- # if shape contains zero, use c.Tensor()
- return _convert_64_to_32(empty_compile(dtype, shape))
-
-
- def arange(start, stop=None, step=None, dtype=None):
- """
- Returns evenly spaced values within a given interval.
-
- Args:
- start(Union[int, float]): Start of interval. The interval includes this value.
- When `stop` is provided as a position argument, `start` must be given, when `stop`
- is a normal argument, `start` can be optional, and default is 0.
- Please see additional examples below.
- stop(Union[int, float], optional): End of interval. The interval does not
- include this value, except in some cases where `step` is not an integer
- and floating point round-off affects the length of out.
- step(Union[int, float], optional): Spacing between values. For any output
- `out`, this is the distance between two adjacent values, :math:`out[i+1] - out[i]`.
- The default step size is 1. If `step` is specified as a position argument,
- `start` must also be given.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype.
- If dtype is None, the data type of the new tensor will be inferred from start,
- stop and step. Default is None.
-
- Returns:
- Tensor with evenly spaced values.
-
- Raises:
- TypeError(PyNative Mode) or RuntimeError(Graph Mode): If input arguments
- have types not specified above, or arguments are not given in the correct
- orders specified above.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.arange(0, 5, 1))
- [0 1 2 3 4]
- >>> print(np.arange(3))
- [0 1 2]
- >>> print(np.arange(start=0, stop=3))
- [0 1 2]
- >>> print(np.arange(0, stop=3, step=0.5))
- [0. 0.5 1. 1.5 2. 2.5]
- >>> print(np.arange(stop=3)) # This will lead to TypeError
- """
- # This implementation was inspired by jax.numpy.arange
- # infer the dtype
- if dtype is None:
- dtype = _get_dtype_from_scalar(start, stop, step)
- if stop is None and step is None: # (start, stop, step) -> (0, start, 1)
- num = _ceil(start)
- out = _iota(mstype.float32, num)
- elif step is None: # (start, stop, step) -> (start, stop, 1)
- num = _ceil(stop - start)
- out = _iota(mstype.float32, num) + start
- elif stop is None: # (start, stop, step) -> (0, start, step)
- num = _ceil((start + 0.0) / step)
- out = _iota(mstype.float32, num) * step
- else:
- num = _ceil((stop - start + 0.0) / step)
- out = _iota(mstype.float32, num) * step + start
- return out.astype(dtype)
-
-
- def _type_checking_for_xspace(start, stop, num, endpoint, dtype):
- """utility parameter checking function for linspace, logspace, geomspace."""
- if not isinstance(start, ARRAY_TYPES):
- _raise_type_error("start should be int, float, bool, list, tuple, Tensor, but got", start)
- if not isinstance(stop, ARRAY_TYPES):
- _raise_type_error("end should be int, float, bool, list, tuple, Tensor, but got", stop)
- if not isinstance(start, Tensor):
- start = _type_convert(Tensor, start).astype(mstype.float32)
- if not isinstance(stop, Tensor):
- stop = _type_convert(Tensor, stop).astype(mstype.float32)
- if not isinstance(num, int):
- _raise_type_error("num should be an integer, but got ", num)
- if not isinstance(endpoint, bool):
- _raise_type_error("endpoint should be an boolean, but got ", endpoint)
- if dtype is not None:
- dtype = _check_dtype(dtype)
- else:
- dtype = mstype.float32
- start, stop = broadcast_arrays(start, stop)
- return start, stop, num, endpoint, dtype
-
-
- def _compute_shapes(start, axis, num, endpoint):
- """Computes shapes for local variables for np.linspace"""
- bounds_shape = start.shape
- bounds_shape = _tuple_slice(bounds_shape, None, axis) + (1,) + _tuple_slice(bounds_shape, axis, None)
- iota_shape = _list_comprehensions(start.ndim+1, 1, True)
- iota_shape = _tuple_slice(iota_shape, None, axis) + (num,) + _tuple_slice(iota_shape, axis+1, None)
- num_tensor = _type_convert(Tensor, num).astype(mstype.float32)
- div = (num_tensor - 1) if endpoint else num_tensor
- return bounds_shape, iota_shape, div
-
-
- def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0):
- """
- Returns evenly spaced values within a given interval.
-
- Args:
- start (Union[int, list(int), tuple(int), tensor]): The starting value of the sequence.
- stop (Union[int, list(int), tuple(int), tensor]): The end value of the sequence,
- unless `endpoint` is set to False. In that case, the sequence consists
- of all but the last of `num + 1` evenly spaced samples, so that `stop`
- is excluded. Note that the step size changes when `endpoint` is False.
- num (int, optional): Number of samples to generate. Default is 50.
- endpoint (bool, optional): If True, `stop` is the last sample. Otherwise, it is
- not included. Default is True.
- retstep (bool, optional): If True, return (`samples`, `step`), where `step` is
- the spacing between samples.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype,
- If `dtype` is None, infer the data type from other input arguments. Default is None.
- axis (int, optional): The axis in the result to store the samples. Relevant
- only if start or stop are array-like. By default :math:`(0)`, the samples will
- be along a new axis inserted at the beginning. Use :math:`-1` to get an axis at the end.
- Default is :math:`0`.
-
- Returns:
- Tensor, with `num` equally spaced samples in the closed interval
- :math:`[start, stop]` or the half-open interval :math:`[start, stop)`
- (depending on whether `endpoint` is True or False).
-
- Step, the size of spacing between samples, only returned if `retstep` is True.
-
- Raises:
- TypeError: If input arguments have types not specified above.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.linspace(0, 5, 6))
- [0. 1. 2. 3. 4. 5.]
- """
- # This implementation was inspired by jax.numpy.linspace and numpy.linspace
- start, stop, num, endpoint, dtype = _type_checking_for_xspace(start, stop, num, endpoint, dtype)
- axis = _canonicalize_axis(axis, start.ndim+1)
- if not isinstance(retstep, bool):
- _raise_type_error("retstep should be an boolean, but got ", retstep)
- bounds_shape, iota_shape, div = _compute_shapes(start, axis, num, endpoint)
- out = None
- delta = None
- if num > 1:
- delta = (stop - start) / div
- # This is similar to how numpy and jax compute linspace
- start_expand = reshape(start, bounds_shape)
- incremental_expand = reshape(_iota(mstype.float32, num), iota_shape)
- delta_expand = reshape(delta, bounds_shape)
- start_expand, incremental_expand, delta_expand = broadcast_arrays(
- start_expand, incremental_expand, delta_expand)
- out = start_expand + (incremental_expand * delta_expand)
- # recover endpoint
- if endpoint:
- out = moveaxis(out, axis, 0)
- out[-1] = stop
- out = moveaxis(out, 0, axis)
- elif num == 1:
- delta = nan if endpoint else stop - start
- out = reshape(start, bounds_shape)
- else: # num == 0
- _raise_value_error("cannot support Tensor with num=0.")
- if retstep:
- return out.astype(dtype), delta
- return out.astype(dtype)
-
-
- def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0):
- """
- Returns numbers spaced evenly on a log scale.
-
- In linear space, the sequence starts at base ** start (base to the power of
- start) and ends with base ** stop (see endpoint below).
-
- Args:
- start (Union[int, list(int), tuple(int), tensor]): ``base ** start`` is the starting
- value of the sequence.
- stop (Union[int, list(int), tuple(int), tensor]): ``base ** stop`` is the final value of
- the sequence, unless `endpoint` is False. In that case, ``num + 1`` values are spaced
- over the interval in log-space, of which all but the last (a sequence of length num)
- are returned.
- num (int, optional): Number of samples to generate. Default is 50.
- endpoint (bool, optional): If True, `stop` is the last sample. Otherwise, it is
- not included. Default is True.
- base (Union[int, float], optional): The base of the log space. The step size
- between the elements in :math:`ln(samples) / ln(base)` (or :math:`log_{base}(samples)`)
- is uniform. Default is :math:`10.0`.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype.
- If `dtype` is None, infer the data type from other input arguments. Default is None.
- axis (int, optional): The axis in the result to store the samples. Relevant
- only if start or stop is array-like. By default (:math:`0`), the samples will
- be along a new axis inserted at the beginning. Use :math:`-1` to get an axis at the end.
- Default is :math:`0`.
-
- Returns:
- Tensor, equally spaced on a log scale.
-
- Raises:
- TypeError: If input arguments have types not specified above.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.logspace(0, 5, 6, base=2.0))
- [ 1. 2. 4. 8. 16. 32.]
- """
- # This implementation was inspired by jax.numpy.linspace and numpy.linspace
- start, stop, num, endpoint, dtype = _type_checking_for_xspace(start, stop, num, endpoint, dtype)
- axis = _canonicalize_axis(axis, start.ndim+1)
- if not isinstance(base, (int, float, bool)):
- _raise_type_error("base should be a number, but got ", base)
- linspace_res = linspace(start, stop, num, endpoint=endpoint, retstep=False, dtype=None, axis=axis)
- return F.tensor_pow(base, linspace_res).astype(dtype)
-
-
- def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0):
- """
- Returns numbers spaced evenly on a log scale (a geometric progression).
-
- This is similar to logspace, but with endpoints specified directly. Each output sample
- is a constant multiple of the previous.
-
- Args:
- start (Union[int, list(int), tuple(int), tensor]): The starting value of the sequence.
- stop (Union[int, list(int), tuple(int), tensor]): The final value of the sequence,
- unless endpoint is False. In that case, num + 1 values are spaced over the
- interval in log-space, of which all but the last (a sequence of length num) are
- returned.
- num (int, optional): Number of samples to generate. Default is 50.
- endpoint (bool, optional): If True, `stop` is the last sample. Otherwise, it is
- not included. Default is True.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype, can
- be in format of np.float32, or `float32`.If `dtype` is None, infer the data
- type from other input arguments. Default is None.
- axis (int, optional): The axis in the result to store the samples. Relevant
- only if start or stop is array-like. By default (0), the samples will
- be along a new axis inserted at the beginning. Use -1 to get an axis at the end.
- Default is 0.
-
- Returns:
- Tensor, with samples equally spaced on a log scale.
-
- Raises:
- TypeError: If input arguments have types not specified above.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> output = np.geomspace(1, 256, num=9)
- >>> print(output)
- [ 1. 2. 4. 8. 16. 32. 64. 128. 256.]
- >>> output = np.geomspace(1, 256, num=8, endpoint=False)
- >>> print(output)
- [ 1. 2. 4. 8. 16. 32. 64. 128.]
- """
- start, stop, num, endpoint, dtype = _type_checking_for_xspace(start, stop, num, endpoint, dtype)
- axis = _canonicalize_axis(axis, start.ndim+1)
- root = num
- if endpoint:
- root -= 1
- bases = F.tensor_pow(F.tensor_div(stop, start), asarray_const(1./(root)))
- exponents = linspace(zeros(F.shape(bases)), F.fill(F.dtype(bases), F.shape(bases), root),
- num, endpoint=endpoint, dtype=dtype, axis=axis)
- shape = F.shape(bases)
- axis = axis + F.rank(bases) + 1 if axis < 0 else axis
- expanded_shape = _tuple_slice(shape, None, axis) + (1,) + _tuple_slice(shape, axis, None)
- bases = F.reshape(bases, expanded_shape)
- start = F.reshape(start, expanded_shape)
- res = F.tensor_mul(F.tensor_pow(bases, exponents), start)
- if dtype is not None:
- res = F.cast(res, dtype)
- return res
-
-
- def eye(N, M=None, k=0, dtype=mstype.float32):
- """
- Returns a 2-D tensor with ones on the diagnoal and zeros elsewhere.
-
- Args:
- N (int): Number of rows in the output, must be larger than 0.
- M (int, optional): Number of columns in the output. If is :class:`None`, defaults to `N`,
- if defined, must be larger than 0. Deault is :class:`None`.
- k (int, optional): Index of the diagonal: 0 (the default) refers to the main
- diagonal, a positive value refers to an upper diagonal, and a negative value
- to a lower diagonal. Default is 0.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype.
- Default is mstype.float32.
-
- Returns:
- A tensor of shape (N, M). A tensor where all elements are equal to zero,
- except for the k-th diagonal, whose values are equal to one.
-
- Raises:
- TypeError: If input arguments have types not specified above.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.eye(2, 2))
- [[1. 0.]
- [0. 1.]]
- """
- dtype = _check_dtype(dtype)
- if M is None:
- M = N
- if not (isinstance(M, int) and isinstance(N, int) and isinstance(k, int)):
- _raise_type_error("Input tensor dimensions should be integers.")
- out = None
- if N == 0 or M == 0:
- # Fill the shape with any value is fine.
- return full((N, M), 0, dtype)
-
- out = F.eye(N, M, dtype)
-
- if k >= M or k <= -N:
- return full((N, M), 0, dtype)
- if k != 0:
- out = out.astype(mstype.float32)
- if k > 0:
- out_left = full((N, k), 0, dtype)
- out_right = out[..., 0:M-k:1]
- return concatenate((out_left, out_right), 1).astype(dtype)
- if k < 0:
- out_upper = full((-k, M), 0, dtype)
- out_lower = out[0:N+k:1, ...]
- return concatenate((out_upper, out_lower), 0).astype(dtype)
- return out
-
-
- def identity(n, dtype=mstype.float32):
- """
- Returns the identity tensor.
-
- Args:
- n (int): Number of rows and columns in the output, must be larger than 0.
- dtype (Union[:class:`mindspore.dtype`, str], optional): Designated tensor dtype,
- default is :class:`mstype.float32`.
-
- Returns:
- A tensor of shape `(n, n)`, where all elements are equal to zero,
- except for the diagonal, whose values are equal to one.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Raises:
- TypeError: If input arguments have types not specified above.
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.identity(2))
- [[1. 0.]
- [0. 1.]]
- """
- if not isinstance(n, int):
- _raise_type_error("Input tensor dimensions should be integers.")
- dtype = _check_dtype(dtype)
- return eye(n, dtype=dtype)
-
-
- @constexpr
- def empty_compile(dtype, shape):
- """Returns an empty Tensor."""
- return Tensor_(dtype, shape)
-
-
- def empty(shape, dtype=mstype.float32):
- """
- Returns a new array of given shape and type, without initializing
- entries.
-
- Note:
- Numpy argument `order` is not supported.
- Object arrays are not supported.
-
- Args:
- shape (Union[int, tuple(int)]): Shape of the empty array, e.g.,
- (2, 3) or 2.
- dtype (:class:`mindspore.dtype`, optional): Desired output data-type for the
- array, e.g, mstype.int8. Default is mstype.float32.
-
- Returns:
- Tensor, array of uninitialized (arbitrary) data of the given
- shape and dtype.
-
- Raises:
- TypeError: if the input shape or dtype is invalid.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> output = np.empty((2, 3))
- >>> print(output)
- # result may vary
- Tensor(shape=[2, 3], dtype=Float32, value=
- <uninitialized>)
- """
- shape = _check_shape(shape)
- dtype = _check_dtype(dtype)
- return empty_compile(dtype, shape)
-
-
- def _get_shape(array_like):
- """Returns the shape of the array like object."""
- if isinstance(array_like, Tensor):
- return array_like.shape
- return asarray_const(array_like).shape
-
-
- def _get_dtype(array_like):
- """Returns the data type of the array like object."""
- if isinstance(array_like, Tensor):
- return array_like.dtype
- return asarray_const(array_like).dtype
-
-
- def _x_like(prototype, dtype, shape, constructor, fill_value=None):
- """
- Returns a tensor with the same shape and type as prototype,
- using constructor.
- """
- if not isinstance(prototype, ARRAY_TYPES):
- _raise_type_error("prototype should be int, float, bool, list, tuple, Tensor, but got", prototype)
- dtype_out = dtype
- shape_out = shape
- if dtype_out is None:
- dtype_out = _get_dtype(prototype)
- if shape_out is None or isinstance(shape_out, (list, tuple)) and not shape_out:
- shape_out = _get_shape(prototype)
- if fill_value is not None:
- return constructor(shape_out, fill_value, dtype_out)
- return constructor(shape_out, dtype_out)
-
-
- def empty_like(prototype, dtype=None, shape=None):
- """
- Returns a new array with the same shape and type as a given array.
-
- Note:
- Input array must have the same size across a dimension.
- If `prototype` is not a Tensor, dtype is float32 by default if not provided.
-
- Args:
- prototype (Union[Tensor, list, tuple]): The shape and data-type of `prototype`
- define these same attributes of the returned array.
- dtype (:class:`mindspore.dtype`, optional): Overrides the data type of the
- result.
- shape (int or sequence of ints, optional): Overrides the shape
- of the result.
-
- Returns:
- Tensor, array of uninitialized (arbitrary) data with the same
- shape and type as `prototype`.
-
- Raises:
- ValueError: if `prototype` is not a Tensor, list or tuple.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> a = np.ones((4,1,2))
- >>> output = np.empty_like(a)
- >>> print(output)
- # result may vary
- Tensor(shape=[4, 1, 2], dtype=Float32, value=
- <uninitialized>)
- """
- return _x_like(prototype, dtype, shape, empty)
-
-
- def ones_like(a, dtype=None, shape=None):
- """
- Returns an array of ones with the same shape and type as a given array.
-
- Note:
- Input array must have the same size across a dimension.
- If `a` is not a Tensor, dtype is float32 by default if not provided.
-
- Args:
- a (Union[Tensor, list, tuple]): The shape and data-type of a define these same
- attributes of the returned array.
- dtype (:class:`mindspore.dtype`, optional): Overrides the data type of the
- result.
- shape (int or sequence of ints, optional): Overrides the shape
- of the result.
-
- Returns:
- Tensor, array of ones with the same shape and type as `a`.
-
- Raises:
- ValueError: if `a` is not a Tensor, list or tuple.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> a = np.ones((4,1,2))
- >>> output = np.ones_like(a)
- >>> print(output)
- [[[1. 1.]]
- [[1. 1.]]
- [[1. 1.]]
- [[1. 1.]]]
- """
- return _x_like(a, dtype, shape, ones)
-
-
- def zeros_like(a, dtype=None, shape=None):
- """
- Returns an array of zeros with the same shape and type as a given array.
-
- Note:
- Input array must have the same size across a dimension.
- If `a` is not a Tensor, dtype is float32 by default if not provided.
-
- Args:
- a (Union[Tensor, list, tuple]): The shape and data-type of a define these same
- attributes of the returned array.
- dtype (:class:`mindspore.dtype`, optional): Overrides the data type of the
- result.
- shape (int or sequence of ints, optional): Overrides the shape
- of the result.
-
- Returns:
- Tensor, array of zeros with the same shape and type as `a`.
-
- Raises:
- ValueError: if `a` is not a Tensor, list or tuple.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> a = np.ones((4,1,2))
- >>> output = np.zeros_like(a)
- >>> print(output)
- [[[0. 0.]]
- [[0. 0.]]
- [[0. 0.]]
- [[0. 0.]]]
- """
- return _x_like(a, dtype, shape, zeros)
-
-
- def full_like(a, fill_value, dtype=None, shape=None):
- """
- Returns a full array with the same shape and type as a given array.
-
- Note:
- Input array must have the same size across a dimension.
- If `a` is not a Tensor, dtype is float32 by default if not provided.
-
- Args:
- a (Union[Tensor, list, tuple]): The shape and data-type of `a` define these same
- attributes of the returned array.
- fill_value (scalar): Fill value.
- dtype (:class:`mindspore.dtype`, optional): Overrides the data type of the
- result.
- shape (int or sequence of ints, optional): Overrides the shape
- of the result.
-
- Returns:
- Tensor, array of fill_value with the same shape and type as `a`.
-
- Raises:
- ValueError: if `a` is not a Tensor, list or tuple.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> a = np.ones((4,1,2))
- >>> output = np.full_like(a, 0.5)
- >>> print(output)
- [[[0.5 0.5]]
- [[0.5 0.5]]
- [[0.5 0.5]]
- [[0.5 0.5]]]
- """
- return _x_like(a, dtype, shape, full, fill_value=fill_value)
-
-
- def tri(N, M=None, k=0, dtype=mstype.float32):
- """
- Returns a tensor with ones at and below the given diagonal and zeros elsewhere.
-
- Args:
- N(int): Number of rows in the array.
- M(int, optional): Number of columns in the array. By default, `M` is taken
- equal to N.
- k(int, optional): The sub-diagonal at and below which the array is filled.
- :math:`k = 0` is the main diagonal, while :math:`k < 0` is below it, and :math:`k > 0` is above.
- The default is 0.
- dtype(:class:`mindspore.dtype`, optional): Data type of the returned array. The default
- is :class:`mindspore.dtype`.
-
- Returns:
- Tensor with shape `(N, M)`, with its lower triangle filled with
- ones and zeros elsewhere; in other words :math:`T[i,j] = 1` for :math:`j <= i + k`,
- :math:`0` otherwise.
-
- Raises:
- TypeError: If input arguments have types not specified above.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> output = np.tri(3, 3, 1)
- >>> print(output)
- [[1. 1. 0.]
- [1. 1. 1.]
- [1. 1. 1.]]
- """
- if M is None:
- M = N
- return nn_tril((N, M), dtype, k)
-
-
- def tril(m, k=0):
- """
- Returns a lower triangle of a tensor.
-
- Returns a copy of a tensor with elements above the `k-th` diagonal zeroed.
-
- Args:
- m (Union[Tensor, list, tuple]): The shape and data-type of `m` define these same
- attributes of the returned tensor.
- k (int, optional): Diagonal above which to zero elements. :math:`k = 0` (the default)
- is the main diagonal, :math:`k < 0` is below it and :math:`k > 0` is above.
-
- Returns:
- Lower triangle of `m`, of same shape and data-type as `m`.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Raises:
- TypeError: If input arguments have types not specified above.
- ValueError: If input `m`\'s rank :math:`< 1`.
-
- Examples:
- >>> import mindspore.numpy as np
- >>> output = np.tril(np.ones((3, 3)))
- >>> print(output)
- [[1. 0. 0.]
- [1. 1. 0.]
- [1. 1. 1.]]
- """
- if not isinstance(m, Tensor):
- m = asarray_const(m)
- dtype = m.dtype
- m = m.astype(mstype.float32)
- assist = nn_tril(m.shape, mstype.float32, k)
- return F.tensor_mul(assist, m).astype(dtype)
-
-
- def triu(m, k=0):
- """
- Returns an upper triangle of a tensor.
-
- Returns a copy of a tensor with elements below the `k-th` diagonal zeroed.
-
- Args:
- m (Union[Tensor, list, tuple]): The shape and data-type of `m` define these same
- attributes of the returned tensor.
- k (int, optional): Diagonal below which to zero elements. :math:`k = 0` (the default)
- is the main diagonal, :math:`k < 0` is below it and :math:`k > 0` is above.
-
- Returns:
- Upper triangle of `m`, of same shape and data-type as `m`.
-
- Raises:
- TypeError: If input arguments have types not specified above.
- ValueError: If input `m`\'s rank < 1.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> output = np.triu(np.ones((3, 3)))
- >>> print(output)
- [[1. 1. 1.]
- [0. 1. 1.]
- [0. 0. 1.]]
- """
- if not isinstance(m, Tensor):
- m = asarray_const(m)
- dtype = m.dtype
- m = m.astype(mstype.float32)
- assist = nn_triu(m.shape, mstype.float32, k)
- return F.tensor_mul(assist, m).astype(dtype)
-
-
- def diagonal(a, offset=0, axis1=0, axis2=1):
- """
- Returns specified diagonals.
-
- If `a` is 2-D, returns the diagonal of `a` with the given offset, i.e., the
- collection of elements of the form ``a[i, i+offset]``. If `a` has more than two
- dimensions, then the axes specified by `axis1` and `axis2` are used to determine
- the 2-D sub-array whose diagonal is returned. The shape of the resulting
- array can be determined by removing `axis1` and `axis2` and appending an index
- to the right equal to the size of the resulting diagonals.
-
- Args:
- a (Tensor): Array from which the diagonals are taken.
- offset (int, optional): Offset of the diagonal from the main diagonal.
- Can be positive or negative. Defaults to main diagonal.
- axis1 (int, optional): Axis to be used as the first axis of the 2-D
- sub-arrays from which the diagonals should be taken. Defaults to
- first axis (0).
- axis2 (int, optional): Axis to be used as the second axis of the 2-D
- sub-arrays from which the diagonals should be taken. Defaults to
- second axis.
-
- Returns:
- Tensor, if `a` is 2-D, then `a` 1-D array containing the diagonal. If
- ``a.ndim > 2``, then the dimensions specified by `axis1` and `axis2` are removed,
- and a new axis inserted at the end corresponding to the diagonal.
-
- Raises:
- ValueError: if the input tensor has less than two dimensions.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> a = np.arange(4).reshape(2,2).astype(np.float32)
- >>> print(a)
- [[0. 1.]
- [2. 3.]]
- >>> output = np.diagonal(a)
- >>> print(output)
- [0. 3.]
- >>> output = np.diagonal(a, 1)
- >>> print(output)
- [1.]
- >>> a = np.arange(8).reshape(2, 2, 2).astype(np.float32)
- >>> print(a)
- [[[0. 1.]
- [2. 3.]]
- [[4. 5.]
- [6. 7.]]]
- >>> output = np.diagonal(a, 0, 0, 1)
- >>> print(output)
- [[0. 6.]
- [1. 7.]]
- """
- return a.diagonal(offset=offset, axis1=axis1, axis2=axis2)
-
-
- def trace(a, offset=0, axis1=0, axis2=1, dtype=None):
- """
- Returns the sum along diagonals of the array.
-
- If `a` is 2-D, the sum along its diagonal with the given offset is returned,
- i.e., the sum of elements ``a[i,i+offset]`` for all `i`.
- If `a` has more than two dimensions, then the axes specified by `axis1` and
- `axis2` are used to determine the 2-D sub-arrays whose traces are returned.
- The shape of the resulting array is the same as that of a with `axis1` and
- `axis2` removed.
-
- Note:
- On GPU, the supported dtypes are np.float16, and np.float32.
- On CPU, the supported dtypes are np.float16, np.float32, and np.float64.
-
- Args:
- a (Tensor): Array from which the diagonals are taken.
- offset (int, optional): Offset of the diagonal from the main diagonal.
- Can be positive or negative. Defaults to main diagonal.
- axis1 (int, optional): Axis to be used as the first axis of the 2-D
- sub-arrays from which the diagonals should be taken. Defaults to
- first axis (0).
- axis2 (int, optional): Axis to be used as the second axis of the 2-D
- sub-arrays from which the diagonals should be taken. Defaults to
- second axis.
- dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
- output Tensor.
-
- Returns:
- Tensor, sum_along_diagonals. If `a` is 2-D, the sum along the diagonal
- is returned. If `a` has larger dimensions, then an array of sums along
- diagonals is returned.
-
- Raises:
- ValueError: if the input tensor has less than two dimensions.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> output = np.trace(np.eye(3))
- >>> print(output)
- 3.0
- >>> a = np.arange(8).reshape((2,2,2))
- >>> output = np.trace(a)
- >>> print(output)
- [6 8]
- >>> a = np.arange(24).reshape((2,2,2,3))
- >>> output = np.trace(a).shape
- >>> print(output)
- (2, 3)
- """
- return a.trace(offset=offset, axis1=axis1, axis2=axis2, dtype=dtype)
-
-
- def _index(i, size, cartesian=True):
- """If cartesian=True, index 0 is swapped with index 1."""
- if cartesian:
- if i == 1:
- return 0
- if i == 0 and size >= 2:
- return 1
- return i
-
-
- def meshgrid(*xi, sparse=False, indexing='xy'):
- """
- Returns coordinate matrices from coordinate vectors.
-
- Make `N-D` coordinate arrays for vectorized evaluations of `N-D`
- scalar/vector fields over `N-D` grids, given one-dimensional
- coordinate arrays `x1, x2,…, xn`.
-
- Note:
- Numpy argument copy is not supported, and a copy is always
- returned.
-
- Args:
- *xi (Tensor): 1-D arrays representing the coordinates
- of a grid.
- indexing (‘xy’, ‘ij’, optional): Cartesian (‘xy’, default) or
- matrix (‘ij’) indexing of output. In the 2-D case with
- inputs of length `M` and `N`, the outputs are of shape `(N, M)`
- for ‘xy’ indexing and `(M, N)` for ‘ij’ indexing. In the 3-D
- case with inputs of length `M`, `N` and `P`, outputs are of shape
- `(N, M, P)` for ‘xy’ indexing and `(M, N, P)` for ‘ij’ indexing.
- sparse (bool, optional): If True a sparse grid is returned in
- order to conserve memory. Default is False.
-
- Returns:
- Tuple of tensors, for vectors `x1, x2,…, xn` with lengths
- ``Ni=len(xi)``, return `(N1, N2, N3,...Nn)` shaped arrays if
- ``indexing=’ij’`` or `(N2, N1, N3,...Nn)` shaped arrays if
- ``indexing=’xy’`` with the elements of `xi` repeated to fill the matrix
- along the first dimension for `x1`, the second for `x2` and so on.
-
- Raises:
- TypeError: if the input is not a tensor, or sparse is not boolean, or
- indexing is not 'xy' or 'ij'.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> x = np.linspace(0, 1, 3)
- >>> y = np.linspace(0, 1, 2)
- >>> xv, yv = np.meshgrid(x, y)
- >>> print(xv)
- [[0. 0.5 1. ]
- [0. 0.5 1. ]]
- >>> print(yv)
- [[0. 0. 0.]
- [1. 1. 1.]]
- >>> xv, yv = np.meshgrid(x, y, sparse=True)
- >>> print(xv)
- [[0. 0.5 1. ]]
- >>> print(yv)
- [[0.]
- [1.]]
- """
- _check_input_tensor(*xi)
- if not isinstance(sparse, bool):
- _raise_type_error('argument sparse should be boolean')
- if indexing not in ('xy', 'ij'):
- _raise_type_error("Valid values for `indexing` are 'xy' and 'ij'.")
-
- shape_out = ()
- for x in xi:
- shape_out += (x.size,)
- if _is_shape_empty(shape_out):
- return ones(shape_out)
-
- grids = []
- for x in xi:
- if F.rank(x) == 1:
- grids.append(x)
- else:
- grids.append(ravel(x))
- ndim = len(grids)
-
- cartesian = indexing == 'xy'
- shape_out = ()
- for i in range(len(grids)):
- grid_index = _index(i, ndim, cartesian=cartesian)
- shape_out += (F.shape(grids[grid_index])[0],)
-
- res = []
- for i, x in enumerate(grids):
- grid_index = _index(i, ndim, cartesian=cartesian)
- shape_expanded = _expanded_shape(ndim, shape_out[grid_index], grid_index)
- x = x.reshape(shape_expanded)
- if not sparse:
- x = F.tile(x, _tile_size(shape_expanded, shape_out, ndim))
- res.append(x)
- return res
-
-
- class NdGrid:
- """
- Construct a multi-dimensional "meshgrid".
-
- ``grid = NdGrid()`` creates an instance which will return a mesh-grid
- when indexed.
- If instantiated with an argument of ``sparse=True``, the mesh-grid is
- open (or not fleshed out) so that only one-dimension of each
- returned argument is greater than 1.
-
- Args:
- sparse (bool): Whether the grid is sparse or not. Default is
- False.
-
- Returns:
- Tensor or tuple of tensor, a meshgrid. If ``sparse=False``, returns
- tensors are all of the same dimensions; and if ``sparse=True``,
- returns tensors with only one dimension not equal to `1`.
- """
- def __init__(self, sparse=False):
- self.sparse = sparse
-
- def __getitem__(self, keys):
- if isinstance(keys, slice):
- keys = (keys,)
-
- xi = []
- for k in keys:
- if not isinstance(k.start, int) or not isinstance(k.stop, int):
- _raise_type_error('slice indices must be integers')
- if k.step:
- step = k.step
- else:
- step = 1
- if isinstance(step, complex):
- v = linspace(k.start, k.stop, int(abs(step)))
- else:
- v = arange(k.start, k.stop, step)
- xi.append(v)
- grids = meshgrid(*xi, sparse=self.sparse, indexing='ij')
-
- if len(grids) == 1:
- return grids[0]
- if self.sparse:
- return grids
-
- if isinstance(grids, Tensor_):
- return grids
- expanded = []
- for grid in grids:
- expanded.append(F.expand_dims(grid, 0))
- res = concatenate(tuple(expanded))
- return res
-
-
- class MGridClass(NdGrid):
- """
- mgrid is an :class:`NdGrid` instance with ``sparse=False``.
-
- The dimension and number of the output arrays are equal to the number
- of indexing dimensions. If the step length is not a complex number,
- then the stop is not inclusive. However, if the step length is a complex
- number (e.g. 5j), then the integer part of its magnitude is interpreted
- as specifying the number of points to create between the start and
- stop values, where the stop value is inclusive.
-
- Note:
- Not supported in graph mode.
- Unlike Numpy, if the step length is a complex number with a real
- component, the step length is handled as equivalent to
- ``int(abs(step))``.
-
- Returns:
- Tensor or tuple of tensor, a meshgrid.
-
- Raises:
- TypeError: if slicing indices are not integers.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> from mindspore.numpy import mgrid
- >>> output = mgrid[0:5, 0:5]
- >>> print(output)
- [[[0 0 0 0 0]
- [1 1 1 1 1]
- [2 2 2 2 2]
- [3 3 3 3 3]
- [4 4 4 4 4]]
- [[0 1 2 3 4]
- [0 1 2 3 4]
- [0 1 2 3 4]
- [0 1 2 3 4]
- [0 1 2 3 4]]]
- >>> output = mgrid[-1:1:5j]
- >>> print(output)
- [-1. -0.5 0. 0.5 1. ]
- """
- def __init__(self):
- super(MGridClass, self).__init__(sparse=False)
-
-
- class OGridClass(NdGrid):
- """
- ogrid is an :class:`NdGrid` instance with ``sparse=True``.
-
- The dimension and number of the output arrays are equal to the number
- of indexing dimensions. If the step length is not a complex number,
- then the stop is not inclusive. However, if the step length is a complex
- number (e.g. 5j), then the integer part of its magnitude is interpreted
- as specifying the number of points to create between the start and
- stop values, where the stop value is inclusive.
-
- Note:
- Not supported in graph mode.
- Unlike Numpy, if the step length is a complex number with a real
- component, the step length is handled as equivalent to
- ``int(abs(step))``.
-
- Raises:
- TypeError: if slicing indices are not integers.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> from mindspore.numpy import ogrid
- >>> output = ogrid[0:5,0:5]
- >>> print(output)
- [Tensor(shape=[5, 1], dtype=Int32, value=
- [[0],
- [1],
- [2]
- [3],
- [4]]), Tensor(shape=[1, 5], dtype=Int32, value=
- [[0, 1, 2, 3, 4]])]
- >>> output = ogrid[-1:1:5j]
- >>> print(output)
- [-1. -0.5 0. 0.5 1. ]
- """
- def __init__(self):
- super(OGridClass, self).__init__(sparse=True)
-
-
- mgrid = MGridClass()
-
-
- ogrid = OGridClass()
-
-
- def diag(v, k=0):
- """
- Extracts a diagonal or construct a diagonal array.
-
- Args:
- v (Tensor): If `v` is a 2-D array, return a copy of its `k-th` diagonal.
- If `v` is a 1-D array, return a 2-D array with v on the `k-th` diagonal.
- k (int, optional): Diagonal in question. The default is 0. Use ``k>0`` for
- diagonals above the main diagonal, and ``k<0`` for diagonals below the
- main diagonal.
-
- Returns:
- Tensor, the extracted diagonal or constructed diagonal array.
-
- Raises:
- ValueError: if input is not 1-D or 2-D.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> x = np.arange(9).reshape((3,3))
- >>> print(x)
- [[0 1 2]
- [3 4 5]
- [6 7 8]]
- >>> output = np.diag(x)
- >>> print(output)
- [0 4 8]
- >>> output = np.diag(x, k=1)
- >>> print(output)
- [1 5]
- >>> output = np.diag(x, k=-1)
- >>> print(output)
- [3 7]
- """
- ndim = F.rank(v)
- if ndim == 1:
- return diagflat(v, k=k)
- if ndim == 2:
- shape = F.shape(v)
- dtype = F.dtype(v)
- if _is_shape_empty(shape):
- return _empty(dtype, (0,))
- e = eye(shape[0], shape[1], k, dtype)
- prod = F.tensor_mul(v, e)
-
- cast_type = dtype
- if not _check_is_float(dtype):
- # reduce sum only supports float types
- cast_type = mstype.float32
- prod = F.cast(prod, cast_type)
-
- res = F.reduce_sum(prod, 1)
- res = res[_max(0, -k): _min(shape[0], _max(0, shape[1] - k))]
-
- if not _check_same_type(cast_type, dtype):
- res = F.cast(res, dtype)
-
- return res
- return _raise_value_error("Input must be 1- or 2-d.")
-
-
- def diagflat(v, k=0):
- """
- Creates a two-dimensional array with the flattened input as a diagonal.
-
- Note:
- On GPU, the supported dtypes are np.float16, and np.float32.
-
- Args:
- v (Tensor): Input data, which is flattened and set as the `k-th` diagonal
- of the output.
- k (int, optional): Diagonal to set; 0, the default, corresponds to the
- “main” diagonal, a positive (negative) `k` giving the number of the
- diagonal above (below) the main.
-
- Returns:
- Tensor, The 2-D output array.
-
- Raises:
- TypeError: if the input is not a tensor.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> output = np.diagflat(np.asarray([[1,2], [3,4]]))
- >>> print(output)
- [[1 0 0 0]
- [0 2 0 0]
- [0 0 3 0]
- [0 0 0 4]]
- >>> output = np.diagflat(np.asarray([1,2]), 1)
- >>> print(output)
- [[0 1 0]
- [0 0 2]
- [0 0 0]]
- """
- _check_input_tensor(v)
- dtype = F.dtype(v)
- k_abs = _abs(k)
- if _is_shape_empty(F.shape(v)):
- return zeros((k_abs, k_abs), dtype)
-
- v = ravel(v)
- size = F.shape(v)[0]
- e = eye(size, size, 0, dtype)
- res = F.tensor_mul(v, e)
-
- if k != 0:
- pad_y = zeros((size, k_abs), dtype)
- pad_x = zeros((k_abs, size + k_abs), dtype)
- if k < 0:
- res = concatenate((res, pad_y), axis=1)
- res = concatenate((pad_x, res), axis=0)
- else:
- res = concatenate((pad_y, res), axis=1)
- res = concatenate((res, pad_x), axis=0)
- return res
-
-
- def diag_indices(n, ndim=2):
- """
- Returns the indices to access the main diagonal of an array.
-
- This returns a tuple of indices that can be used to access the main
- diagonal of an array a with ``a.ndim >= 2`` dimensions and shape `(n, n, …, n)`.
- For ``a.ndim = 2`` this is the usual diagonal, for ``a.ndim > 2`` this is the set
- of indices to access ``a[i, i, ..., i]`` for ``i = [0..n-1]``.
-
- Args:
- n (int): The size, along each dimension, of the arrays for which
- the returned indices can be used.
- ndim (int, optional): The number of dimensions.
-
- Returns:
- Tuple of Tensor.
-
- Raises:
- TypeError: if input are not integers.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> output = np.diag_indices(5, 3)
- >>> print(output)
- (Tensor(shape=[5], dtype=Int32, value= [0, 1, 2, 3, 4]),
- Tensor(shape=[5], dtype=Int32, value= [0, 1, 2, 3, 4]),
- Tensor(shape=[5], dtype=Int32, value= [0, 1, 2, 3, 4]))
- """
- if not isinstance(n, int) or not isinstance(ndim, int):
- _raise_type_error('input must be integers')
- return _list_comprehensions(ndim, arange(start=0, stop=n), True)
-
-
- def ix_(*args):
- r"""
- Constructs an open mesh from multiple sequences.
-
- This function takes `N` 1-D sequences and returns `N` outputs with `N`
- dimensions each, such that the shape is 1 in all but one dimension
- and the dimension with the non-unit shape value cycles through all
- N dimensions.
- Using ix\_ one can quickly construct index arrays that will index
- the cross product. ``a[np.ix_([1,3],[2,5])]`` returns the array
- ``[[a[1,2] a[1,5]], [a[3,2] a[3,5]]]``.
-
- Note:
- Boolean masks are not supported.
-
- Args:
- *args (Tensor): 1-D sequences.
-
- Returns:
- Tuple of Tensor, `N` arrays with `N` dimensions each, with `N` the
- number of input sequences. Together these arrays form an open
- mesh.
-
- Raises:
- TypeError: if the input is not a tensor.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> ixgrid = np.ix_(np.array([0, 1]), np.array([2, 4]))
- >>> print(ixgrid)
- (Tensor(shape=[2, 1], dtype=Int32, value=
- [[0],
- [1]]), Tensor(shape=[1, 2], dtype=Int32, value=
- [[2, 4]]))
- """
- _check_input_tensor(*args)
- ndim = len(args)
- res = ()
- for i, arr in enumerate(args):
- if F.rank(arr) != 1:
- return _raise_value_error('Cross index must be 1 dimensional')
- res += (F.reshape(arr, _expanded_shape(ndim, arr.size, i)),)
- return res
-
-
- def vander(x, N=None, increasing=False):
- """
- Generates a Vandermonde matrix.
-
- The columns of the output matrix are powers of the input vector. The order of
- the powers is determined by the increasing boolean argument. Specifically, when
- increasing is `False`, the i-th output column is the input vector raised element-wise
- to the power of :math:`N - i - 1`. Such a matrix with a geometric progression in each row
- is named for Alexandre-Theophile Vandermonde.
-
- Args:
- x (Union[list, tuple, Tensor]): 1-D input array.
- N (int, optional): Number of columns in the output. If N is not specified, a
- square array is returned (``N = len(x)``).
- increasing (bool, optional): Order of the powers of the columns. If True, the
- powers increase from left to right, if False (the default) they are reversed.
-
- Returns:
- Vandermonde matrix. If `increasing` is `False`, the first column is :math:`x^{(N-1)}`,
- the second :math:`x^{(N-2)}` and so forth. If `increasing` is `True`, the columns are
- :math:`x^0, x^1, ..., x^{(N-1)}`.
-
- Raises:
- TypeError: If inputs have types not specified above.
- ValueError: If `x` is not 1-D, or `N` < 0.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.vander([1., 2., 3., 4., 5.]))
- [[ 1. 1. 1. 1. 1.]
- [ 16. 8. 4. 2. 1.]
- [ 81. 27. 9. 3. 1.]
- [256. 64. 16. 4. 1.]
- [625. 125. 25. 5. 1.]]
- """
- if isinstance(x, (list, tuple)):
- x = asarray_const(x)
- elif not isinstance(x, Tensor):
- _raise_type_error("Input x must be list, tuple or Tensor, but got ", x)
- if x.ndim != 1:
- _raise_value_error("Input x must be 1-D, but got dimension=", x.ndim)
- N = N or x.size
- if not isinstance(N, int):
- _raise_type_error("Input N must be an integer.")
- if N <= 0:
- _raise_value_error("Input N must > 0.")
- if not isinstance(increasing, bool):
- _raise_type_error("increasing must be a bool.")
- exponent = _iota(x.dtype, N, increasing)
- x = F.expand_dims(x, 1)
- exponent = F.expand_dims(exponent, 0)
- return F.tensor_pow(x, exponent)
-
-
- def indices(dimensions, dtype=mstype.int32, sparse=False):
- """
- Returns an array representing the indices of a grid.
-
- Computes an array where the subarrays contain index values 0, 1, …
- varying only along the corresponding axis.
-
- Args:
- dimensions (tuple or list of ints): The shape of the grid.
- dtype (:class:`mindspore.dtype`, optional): Data type of the result.
- sparse (boolean, optional): Defaults to False. Return a sparse
- representation of the grid instead of a dense representation.
-
- Returns:
- Tensor or tuple of Tensor, If `sparse` is False, returns one array
- of grid indices, ``grid.shape = (len(dimensions),) + tuple(dimensions)``.
- If sparse is True, returns a tuple of arrays, with
- ``grid[i].shape = (1, ..., 1, dimensions[i], 1, ..., 1)`` with
- ``dimensions[i]`` in the `ith` place
-
- Raises:
- TypeError: if input dimensions is not a tuple or list.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> grid = np.indices((2, 3))
- >>> print(grid)
- [Tensor(shape=[2, 3], dtype=Int32, value=
- [[0, 0, 0],
- [1, 1, 1]]), Tensor(shape=[2, 3], dtype=Int32, value=
- [[0, 1, 2],
- [0, 1, 2]])]
- """
- if not isinstance(dimensions, (tuple, list)):
- _raise_type_error('Shape of the grid must be tuple or list')
- grids = ()
- for d in dimensions:
- grids += (arange(d, dtype=dtype),)
- return meshgrid(*grids, sparse=sparse, indexing='ij')
-
-
- def _check_window_size(x):
- """Returns True if window size is greater than 1."""
- if not isinstance(x, int):
- _raise_type_error('the number fo points should be an int')
- return x > 1
-
-
- def bartlett(M):
- """
- Returns the Bartlett window.
- The Bartlett window is very similar to a triangular window, except that the
- end points are at zero. It is often used in signal processing for tapering a
- signal, without generating too much ripple in the frequency domain.
-
- Args:
- M (int): Number of points in the output window. If zero or less, an empty
- array is returned.
-
- Returns:
- Tensor, the triangular window, with the maximum value normalized to one
- (the value one appears only if the number of samples is odd), with the
- first and last samples equal to zero.
-
- Raises:
- TypeError: if `M` is not an int.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.bartlett(12))
- [0. 0.18181819 0.36363637 0.5454545 0.72727275 0.9090909
- 0.9090909 0.72727275 0.5454545 0.36363637 0.18181819 0. ]
- """
- if not _check_window_size(M):
- return ones(_max(0, M))
- n = _iota(mstype.float32, M)
- m_minus_one = _to_tensor(M - 1)
- return _to_tensor(1) - F.absolute(_to_tensor(2)*n - m_minus_one)/m_minus_one
-
-
- def blackman(M):
- """
- Returns the Blackman window.
- The Blackman window is a taper formed by using the first three terms of a
- summation of cosines. It was designed to have close to the minimal leakage
- possible. It is close to optimal, only slightly worse than a Kaiser window.
-
- Args:
- M (int): Number of points in the output window. If zero or less, an empty
- array is returned.
-
- Returns:
- Tensor, the window, with the maximum value normalized to one (the value
- one appears only if the number of samples is odd).
-
- Raises:
- TypeError: if `M` is not an int.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.blackman(12))
- [-1.4901161e-08 3.2606430e-02 1.5990365e-01 4.1439798e-01
- 7.3604518e-01 9.6704674e-01 9.6704674e-01 7.3604518e-01
- 4.1439798e-01 1.5990365e-01 3.2606430e-02 -1.4901161e-08]
- """
- if not _check_window_size(M):
- return ones(_max(0, M))
- n_doubled = arange(1 - M, M, 2, dtype=mstype.float32)
- return (_to_tensor(0.42) + _to_tensor(0.5)*F.cos(_to_tensor(pi/(M - 1))*n_doubled) +
- _to_tensor(0.08)*F.cos(_to_tensor(2*pi/(M - 1))*n_doubled))
-
-
- def hamming(M):
- """
- Returns the Hamming window.
- The Hamming window is a taper formed by using a weighted cosine.
-
- Args:
- M (int): Number of points in the output window. If zero or less, an empty
- array is returned.
-
- Returns:
- Tensor, the window, with the maximum value normalized to one (the value
- one appears only if the number of samples is odd).
-
- Raises:
- TypeError: if `M` is not an int.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.hamming(12))
- [0.08000001 0.15302339 0.34890914 0.6054648 0.841236 0.9813669
- 0.9813668 0.8412359 0.6054647 0.34890908 0.15302327 0.08000001]
- """
- if not _check_window_size(M):
- return ones(_max(0, M))
- n = _iota(mstype.float32, M)
- return _to_tensor(0.54) - _to_tensor(0.46)*F.cos(_to_tensor(2*pi/(M - 1))*n)
-
-
- def hanning(M):
- """
- Returns the Hanning window.
- The Hanning window is a taper formed by using a weighted cosine.
-
- Args:
- M (int): Number of points in the output window. If zero or less, an empty
- array is returned.
-
- Returns:
- Tensor, the window, with the maximum value normalized to one (the value
- one appears only if the number of samples is odd).
-
- Raises:
- TypeError: if `M` is not an int.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.hanning(12))
- [0. 0.07937324 0.29229254 0.5711574 0.8274304 0.9797465
- 0.97974646 0.82743025 0.5711573 0.29229245 0.07937312 0. ]
- """
- if not _check_window_size(M):
- return ones(_max(0, M))
- n = _iota(mstype.float32, M)
- return _to_tensor(0.5) - _to_tensor(0.5)*F.cos(_to_tensor(2*pi/(M - 1))*n)
-
-
- @constexpr
- def tri_indices(n, k=0, m=None, upper=True):
- """Returns triu/tril indices in o(nm) time."""
- if not isinstance(n, (int, float, bool)):
- raise TypeError("Input n must be a number.")
- if not isinstance(k, (int, float, bool)):
- raise TypeError("Input k must be a number.")
- if m is None:
- m = n
- elif not isinstance(m, (int, float, bool)):
- raise TypeError("Input m must be a number.")
- if upper:
- compare = operator.ge
- else:
- compare = operator.le
- x_coordinate = []
- y_coordinate = []
- # math.ceil is used to match numpy's behaviour
- for i in range(math.ceil(n)):
- curr_limit = i + k
- for j in range(math.ceil(m)):
- if compare(j, curr_limit):
- x_coordinate.append(i)
- y_coordinate.append(j)
- return asarray_const(x_coordinate), asarray_const(y_coordinate)
-
-
- def triu_indices(n, k=0, m=None):
- """
- Returns the indices for the upper-triangle of an (n, m) array.
-
- Args:
- n (int): The size of the arrays for which the returned indices will be valid.
- k (int, optional): Diagonal offset.
- m (int, optional): The column dimension of the arrays for which the returned
- arrays will be valid. By default `m` is taken equal to `n`.
-
- Returns:
- The indices for the triangle. The returned tuple contains two tensors, each
- with the indices along one dimension of the tensor.
-
- Raises:
- TypeError: if `n`, `k`, `m` are not numbers.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.triu_indices(3))
- (Tensor(shape=[6], dtype=Int32, value= [0, 0, 0, 1, 1, 2]),
- Tensor(shape=[6], dtype=Int32, value= [0, 1, 2, 1, 2, 2]))
- """
- return tri_indices(n, k, m, True)
-
-
- def tril_indices(n, k=0, m=None):
- """
- Returns the indices for the lower-triangle of an (n, m) array.
-
- Args:
- n (int): The size of the arrays for which the returned indices will be valid.
- k (int, optional): Diagonal offset.
- m (int, optional): The column dimension of the arrays for which the returned
- arrays will be valid. By default `m` is taken equal to `n`.
-
- Returns:
- The indices for the triangle. The returned tuple contains two tensors, each
- with the indices along one dimension of the tensor.
-
- Raises:
- TypeError: if `n`, `k`, `m` are not numbers.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> print(np.tril_indices(3))
- (Tensor(shape=[6], dtype=Int32, value= [0, 1, 1, 2, 2, 2]),
- Tensor(shape=[6], dtype=Int32, value= [0, 0, 1, 0, 1, 2]))
- """
- return tri_indices(n, k, m, False)
-
-
- def triu_indices_from(arr, k=0):
- """
- Returns the indices for the upper-triangle of `arr`.
-
- Args:
- arr (Union[Tensor, list, tuple]): 2-dimensional array.
- k (int, optional): Diagonal offset.
-
- Returns:
- triu_indices_from, tuple of 2 tensor, shape(N)
- Indices for the upper-triangle of `arr`.
-
- Raises:
- TypeError: if `arr` cannot be converted to tensor, or `k` is not a number.
- ValueError: if `arr` cannot be converted to a 2-dimensional tensor.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> tensor = np.ones((3,3))
- >>> print(np.triu_indices_from(tensor))
- (Tensor(shape=[6], dtype=Int32, value= [0, 0, 0, 1, 1, 2]),
- Tensor(shape=[6], dtype=Int32, value= [0, 1, 2, 1, 2, 2]))
- """
- arr = asarray(arr)
- if arr.ndim != 2:
- _raise_value_error("input array must be 2-d")
- return triu_indices(arr.shape[-2], k=k, m=arr.shape[-1])
-
-
- def tril_indices_from(arr, k=0):
- """
- Returns the indices for the lower-triangle of `arr`.
-
- Args:
- arr (Union[Tensor, list, tuple]): 2-dimensional array.
- k (int, optional): Diagonal offset.
-
- Returns:
- triu_indices_from, tuple of 2 tensor, shape(N)
- Indices for the upper-triangle of `arr`.
-
- Raises:
- TypeError: if `arr` cannot be converted to tensor, or `k` is not a number.
- ValueError: if `arr` cannot be converted to a 2-dimensional tensor.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> tensor = np.ones((3,3))
- >>> print(np.tril_indices_from(tensor))
- (Tensor(shape=[6], dtype=Int32, value= [0, 1, 1, 2, 2, 2]),
- Tensor(shape=[6], dtype=Int32, value= [0, 0, 1, 0, 1, 2]))
- """
- arr = asarray(arr)
- if arr.ndim != 2:
- _raise_value_error("input array must be 2-d")
- return tril_indices(arr.shape[-2], k=k, m=arr.shape[-1])
-
-
- def histogram_bin_edges(a, bins=10, range=None, weights=None): # pylint: disable=redefined-builtin
- """
- Function to calculate only the edges of the bins used by the histogram function.
-
- Note:
- String values for `bins` is not supported.
-
- Args:
- a (Union[int, float, bool, list, tuple, Tensor]): Input data. The histogram
- is computed over the flattened array.
- bins ((Union[int, tuple, list, Tensor])): If `bins` is an int, it defines the number
- of equal-width bins in the given range (10, by default). If `bins` is a
- sequence, it defines the bin edges, including the rightmost edge,
- allowing for non-uniform bin widths.
- range((float, float), optional): The lower and upper range of the bins. If
- not provided, `range` is simply ``(a.min(), a.max())``. Values outside
- the range are ignored. The first element of the range must be less than
- or equal to the second. Default is None.
- weights(Union[int, float, bool, list, tuple, Tensor], optional): An array of weights,
- of the same shape as `a`. Each value in `a` only contributes its associated weight
- towards the bin count (instead of 1). This is currently not used by any of the bin
- estimators, but may be in the future. Default is None.
-
- Returns:
- Tensor, the edges to pass into `histogram`.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Raises:
- TypeError: if `bins` is an array and not one-dimensional.
-
- Examples:
- >>> import mindspore.numpy as np
- >>> arr = np.array([0, 0, 0, 1, 2, 3, 3, 4, 5])
- >>> print(np.histogram_bin_edges(arr, bins=2))
- [0. 2.5 5. ]
- """
- a = _to_tensor(a)
- if weights is not None:
- weights = _to_tensor(weights)
- if F.shape(a) != F.shape(weights):
- _raise_value_error('weights should have the same shape as a')
- if isinstance(bins, (tuple, list, Tensor)):
- bins = _to_tensor(bins)
- if F.rank(bins) != 1:
- _raise_value_error('`bins` must be 1d, when an array')
- return bins
- if isinstance(bins, str):
- # linspace does not support Tensor for num
- _raise_unimplemented_error('string value for `bins` not implemented')
- a = a.ravel().astype(mstype.float32)
- if range is None:
- start = F.reduce_min(a)
- end = F.reduce_max(a)
- else:
- if not isinstance(range, (list, tuple)) or len(range) != 2:
- _raise_value_error('`range` should take the form (start, end)')
- start, end = range
- if start > end:
- _raise_value_error('max must be larger than min in range parameter')
- start, end = _to_tensor(start, end)
- no_range = (end - start) == 0
- start = where(no_range, start - 0.5, start)
- end = where(no_range, end + 0.5, end)
- return linspace(start, end, bins + 1)
-
-
- def _pad_empty(arr, pad_width):
- """
- pads the array with constant values, used in mode: "empty"
- """
- dtype = arr.dtype
- for i in range(arr.ndim):
- shape = arr.shape
- pad_before = ()
- pad_after = ()
- # To avoid any memory issues, we don't make tensor with 0s in their shapes
- if pad_width[i][0] > 0:
- pad_before += (empty(_tuple_setitem(shape, i, pad_width[i][0]), dtype=dtype),)
- if pad_width[i][1] > 0:
- pad_after += (empty(_tuple_setitem(shape, i, pad_width[i][1]), dtype=dtype),)
- tensor_with_pad = pad_before + (arr,) + pad_after
- arr = concatenate(tensor_with_pad, axis=i)
- return arr
-
-
- def _pad_constant(arr, pad_width, value):
- """
- pads the array with constant values, used in mode: "constant"
- """
- dtype = arr.dtype
- for i in range(arr.ndim):
- shape = arr.shape
- pad_before = ()
- pad_after = ()
- # To avoid any memory issues, we don't make tensor with 0s in their shapes
- if pad_width[i][0] > 0:
- pad_before += (full(_tuple_setitem(shape, i, pad_width[i][0]), value[i][0], dtype=dtype),)
- if pad_width[i][1] > 0:
- pad_after += (full(_tuple_setitem(shape, i, pad_width[i][1]), value[i][1], dtype=dtype),)
- tensor_with_pad = pad_before + (arr,) + pad_after
- arr = concatenate(tensor_with_pad, axis=i)
- return arr
-
-
- def _pad_statistic(arr, pad_width, stat_length, stat_op):
- """
- pads the array with values calculated along the given axis, used in mode: "maximum",
- "minimum", "mean"
- """
- ndim = arr.ndim
- shape = arr.shape
- if stat_length is None:
- stat_length = _make_stat_length(shape)
- else:
- stat_length = _convert_pad_to_nd(stat_length, ndim)
- stat_length = _limit_stat_length(stat_length, shape)
- for i in range(ndim):
- pad_before = stat_op(_slice_along_axis(arr, i, 0, stat_length[i][0]), i)
- pad_before = (F.tile(pad_before, _tuple_setitem((1,)*ndim, i, pad_width[i][0])),)
- pad_after = stat_op(_slice_along_axis(arr, i, shape[i]-stat_length[i][1], shape[i]), i)
- pad_after = (F.tile(pad_after, _tuple_setitem((1,)*ndim, i, pad_width[i][1])),)
- tensor_with_pad = pad_before + (arr,) + pad_after
- arr = concatenate(tensor_with_pad, axis=i)
- return arr
-
-
- def _pad_edge(arr, pad_width):
- """pad_edge is equivalent to pad_statistic with stat_lenght=1, used in mode:"edge"."""
- def identity_op(arr, axis):
- return arr
- return _pad_statistic(arr, pad_width, 1, identity_op)
-
-
- def _pad_wrap(arr, pad_width):
- """The behaviour of wrap mode is consistent with jax.numpy, used in mode:"wrap"."""
- ndim = arr.ndim
- shape = arr.shape
- for i in range(ndim):
- padsize_before = pad_width[i][0] % shape[i]
- padsize_after = pad_width[i][1] % shape[i]
- total_repeats = pad_width[i][0] // shape[i] + 1 + pad_width[i][1] // shape[i]
- tensor_with_pad = ()
- # To avoid any memory issues, we don't make tensor with 0s in their shapes
- if padsize_before > 0:
- tensor_with_pad += (_slice_along_axis(arr, i, shape[i]-padsize_before, shape[i]),)
- tensor_with_pad += (F.tile(arr, _tuple_setitem((1,)*ndim, i, total_repeats)),)
- if padsize_after > 0:
- tensor_with_pad += (_slice_along_axis(arr, i, 0, padsize_after),)
- arr = concatenate(tensor_with_pad, axis=i)
- return arr
-
-
- def _pad_linear(arr, pad_width, end_values):
- """Pads the arr with linear range values, used in mode: "linear_ramp"."""
- ndim = arr.ndim
- shape = arr.shape
- dtype = arr.dtype
- end_values = _convert_pad_to_nd(end_values, ndim)
- for i in range(ndim):
- left_value = _slice_along_axis(arr, i, 0, 1)
- right_value = _slice_along_axis(arr, i, shape[i]-1, shape[i])
- pad_before = ()
- pad_after = ()
- if pad_width[i][0] > 0:
- pad_before = (linspace(end_values[i][0], left_value, num=pad_width[i][0],
- endpoint=False, dtype=dtype, axis=i).squeeze(i+1),)
- if pad_width[i][1] > 0:
- pad_after = linspace(right_value, end_values[i][1], num=pad_width[i][1]+1,
- endpoint=True, dtype=dtype, axis=i).squeeze(i+1)
- pad_after = (_slice_along_axis(pad_after, i, 1, pad_width[i][1]+1),)
- tensor_with_pad = pad_before + (arr,) + pad_after
- arr = concatenate(tensor_with_pad, axis=i)
- return arr
-
-
- def _add_pads_before(arr, pad_args, mode):
- """handle pads before the array"""
- idx, array_length, times_to_pad_before, additional_pad_before, reflect_type = pad_args
- curr_pad = None
- endpoint_adder = None
- edge_before = _slice_along_axis(arr, idx, 0, 1)
- if mode == "reflect":
- endpoint_adder = 1
- else:
- endpoint_adder = 0
- # Deal with paddings before the original array
- for times in range(times_to_pad_before):
- if times < times_to_pad_before - 1:
- endpoint = array_length
- else:
- endpoint = additional_pad_before + endpoint_adder
- if endpoint != endpoint_adder:
- curr_pad = _slice_along_axis(arr, idx, endpoint_adder, endpoint)
- curr_pad = flip(curr_pad, axis=idx)
- if reflect_type == "odd":
- curr_pad = 2 * edge_before - curr_pad
- arr = P.Concat(idx)((curr_pad, arr))
- edge_before = _slice_along_axis(arr, idx, 0, 1)
- return arr
-
-
- def _add_pads_after(arr, pad_args, mode):
- """handle pads after the array"""
- idx, array_length, times_to_pad_after, additional_pad_after, reflect_type = pad_args
- curr_pad = None
- endpoint_adder = None
- edge_end = _slice_along_axis(arr, idx, arr.shape[idx]-1, arr.shape[idx])
- if mode == "reflect":
- endpoint_adder = 1
- else:
- endpoint_adder = 0
- # Deal with paddings after the original array
- for times in range(times_to_pad_after):
- if times < times_to_pad_after - 1:
- startpoint = arr.shape[idx] - array_length
- else:
- startpoint = arr.shape[idx] - additional_pad_after - endpoint_adder
- if startpoint != arr.shape[idx] - endpoint_adder:
- curr_pad = _slice_along_axis(arr, idx, startpoint, arr.shape[idx] - endpoint_adder)
- curr_pad = flip(curr_pad, axis=idx)
- if reflect_type == "odd":
- curr_pad = 2 * edge_end - curr_pad
- arr = P.Concat(idx)((arr, curr_pad))
- edge_end = _slice_along_axis(arr, idx, arr.shape[idx]-1, arr.shape[idx])
- return arr
-
-
- def _pad_symmetric(arr, pad_width, reflect_type):
- """pad the array with symmetric paddings"""
- for i in range(arr.ndim):
- array_length = arr.shape[i]
-
- has_pad_before = (pad_width[i][0] > 0)
- has_pad_after = (pad_width[i][1] > 0)
-
- times_to_pad_before = pad_width[i][0] // array_length + 1
- additional_pad_before = pad_width[i][0] % array_length
- times_to_pad_after = pad_width[i][1] // array_length + 1
- additional_pad_after = pad_width[i][1] % array_length
- if has_pad_before:
- # Deal with paddings before the original array
- pad_args = (i, array_length, times_to_pad_before, additional_pad_before, reflect_type)
- arr = _add_pads_before(arr, pad_args, "symmetric")
- if has_pad_after:
- # Deal with paddings after the original array
- pad_args = (i, array_length, times_to_pad_after, additional_pad_after, reflect_type)
- arr = _add_pads_after(arr, pad_args, "symmetric")
- return arr
-
-
- def _pad_reflect(arr, pad_width, reflect_type):
- """
- pad the array with reflect paddings, this is very similar to symmetric paddings,
- but differs at how edges are selected.
- """
- for i in range(arr.ndim):
- array_length = arr.shape[i]
- if array_length == 1:
- total_repeats = pad_width[i][0] + pad_width[i][1] + 1
- arr = F.tile(arr, _tuple_setitem((1,)*arr.ndim, i, total_repeats))
- else:
- has_pad_before = (pad_width[i][0] > 0)
- has_pad_after = (pad_width[i][1] > 0)
-
- pad_size = array_length - 1
- times_to_pad_before = pad_width[i][0] // pad_size + 1
- additional_pad_before = pad_width[i][0] % pad_size
- times_to_pad_after = pad_width[i][1] // pad_size + 1
- additional_pad_after = pad_width[i][1] % pad_size
- if has_pad_before:
- # Deal with paddings before the original array
- pad_args = (i, array_length, times_to_pad_before, additional_pad_before, reflect_type)
- arr = _add_pads_before(arr, pad_args, "reflect")
- if has_pad_after:
- # Deal with paddings after the original array
- pad_args = (i, array_length, times_to_pad_after, additional_pad_after, reflect_type)
- arr = _add_pads_after(arr, pad_args, "reflect")
- return arr
-
-
- def _pad_func(arr, pad_width, func, **kwargs):
- """applies padding function over different axis."""
- # first creates a padded array with fixed length.
- arr_dim = arr.ndim
- pad_width = _convert_pad_to_nd(pad_width, arr_dim)
- arr = _pad_empty(arr, pad_width)
- for i in range(arr_dim):
- # function signature: padding_func(tensor, iaxis_pad_width, iaxis, kwargs)
- arr = apply_along_axis(func, i, arr, pad_width[i], i, kwargs)
- return arr
-
-
- @constexpr
- def _make_stat_length(shape):
- """converts the stat_length values."""
- return tuple((shape[i], shape[i]) for i, _ in enumerate(shape))
-
-
- @constexpr
- def _limit_stat_length(stat_length, shape):
- """limits the stat_length to current array length along given dimension."""
- return tuple((min(stat_pair[0], shape[i]), min(stat_pair[1], shape[i])) for i, stat_pair in enumerate(stat_length))
-
-
- @constexpr
- def _convert_pad_to_nd(pad_values, ndim):
- """broadcasts the pad_values to (ndim * 2)"""
- if not isinstance(pad_values, (int, list, tuple, Tensor)):
- raise TypeError(
- "pad_width, stat_length, constant_values or end_values should only be int, list, tuple or tensor")
- pad_tensor = _to_tensor(pad_values)
- pad_shape = pad_tensor.shape
- if not pad_shape:
- pad_values = tuple((((pad_values,) * 2) for i in range(ndim)))
- elif pad_shape == (1,):
- pad_values = tuple((tuple(pad_values) * 2) for i in range(ndim))
- elif pad_shape == (2,):
- pad_values = tuple(tuple(pad_values) for i in range(ndim))
- elif pad_shape == (1, 2):
- pad_values = tuple(tuple(pad_values[0]) for i in range(ndim))
- elif pad_shape == (ndim, 2):
- pad_values = tuple(tuple(pad_pair) for pad_pair in pad_values)
- else:
- raise ValueError(f"input values must be able to broadcast to {(ndim, 2)}")
- return pad_values
-
-
- def pad(arr, pad_width, mode="constant", stat_length=None, constant_values=0,
- end_values=0, reflect_type="even", **kwargs):
- """
- Pads an array.
-
- Note:
- Currently, `median` mode is not supported. `reflect` and `symmetric` mode
- only supports GPU backend.
-
- Args:
- arr (Union[list, tuple, Tensor]): The array to pad.
- pad_width (Union[int, tuple, list]): Number of values padded to the edges of
- each axis. :class:`((before_1, after_1), ... (before_N, after_N))` creates
- unique pad widths for each axis. :class:`((before, after),)` yields same
- before and after pad for each axis. :class:`(pad,)` or int is a shortcut
- for :class:`before = after = pad width` for all axes.
- mode (string, optional):
- One of the following string values:
-
- - constant (default): Pads with a constant value.
- - edge: Pads with the edge values of `arr`.
- - linear_ramp: Pads with the linear ramp between end_value and the `arr` edge value.
- - maximum: Pads with the maximum value of all or part of the vector along each axis.
- - mean: Pads with the mean value of all or part of the vector along each axis.
- - median: Pads with the median value of all or part of the vector along each axis.
- - minimum: Pads with the minimum value of all or part of the vector along each axis.
- - reflect: Pads with the reflection of the vector mirrored on the first
- and last values of the vector along each axis.
- - symmetric: Pads with the reflection of the vector mirrored along the edge
- of the `arr`.
- - wrap: Pads with the wrap of the vector along the axis. The first values
- are used to pad the end and the end values are used to pad the beginning.
- - empty: Pads with undefined values.
- - <function>: The padding function, if used, should modify and return a new 1-d tensor.
- It has the following signature: :class:`padding_func(tensor, iaxis_pad_width, iaxis, kwargs)`
- stat_length (Union[tuple, list, int], optional): Used in \'maximum\', \'mean\',
- \'median\', and \'minimum\'. Number of values at edge of each axis used
- to calculate the statistic value. :class:`((before_1, after_1), ... (before_N, after_N))`
- creates unique statistic lengths for each axis. :class:`((before, after),)`
- yields same before and after statistic lengths for each axis. :class:`(stat_length,)`
- or int is a shortcut for :class:`before = after = statistic length` for all
- axes. Default is :class:`None`, to use the entire axis.
- constant_values (Union[tuple, list, int], optional):
- Used in :class:`constant mode`. The values to set the padded values for each
- axis. :class:`((before_1, after_1), ... (before_N, after_N))` creates unique pad
- constants for each axis. :class:`((before, after),)` yields same before and
- after constants for each axis. :class:`(constant,)` or :class:`constant` is
- a shortcut for :class:`before = after = constant` for all axes. Default is 0.
- end_values (Union[tuple, list, int], optional): Used in 'linear_ramp'. The values
- used for the ending value of the linear_ramp and that will form the edge of
- the padded `arr`. :class:`((before_1, after_1), ... (before_N, after_N))`
- unique end values for each axis. :class:`((before, after),)` yields same before
- and after end values for each axis. :class:`(constant,)` or :class:`constant`
- is a shortcut for :class:`before = after = constant` for all axes. Default is 0.
- reflect_type(string, optional) can choose between \'even\' and \'odd\'. Used in
- \'reflect\', and \'symmetric\'. The \'even\' style is the default with an
- unaltered reflection around the edge value. For the \'odd\' style, the extended
- part of the `arr` is created by subtracting the reflected values from two times
- the edge value.
-
- Returns:
- Padded tensor of rank equal to `arr` with shape increased according to `pad_width`.
-
- Raises:
- TypeError: if `arr`, `pad_width`, `stat_length`, `constant_values` or `end_values`
- have types not specified above.
- ValueError: if `mode` cannot be recognized, or if `pad_width`, `stat_length`,
- `constant_values`, `end_values` cannot broadcast to :class:`(arr.ndim, 2)`,
- or if keyword arguments got unexpected inputs.
- NotImplementedError: if mode is function or '/median'/.
-
- Supported Platforms:
- ``Ascend`` ``GPU`` ``CPU``
-
- Examples:
- >>> import mindspore.numpy as np
- >>> tensor = np.array([1., 2., 3., 4., 5.])
- >>> print(np.pad(tensor, (3, 4)))
- [0. 0. 0. 1. 2. 3. 4. 5. 0. 0. 0. 0.]
- >>> print(np.pad(tensor, (3, 4), mode="wrap"))
- [3. 4. 5. 1. 2. 3. 4. 5. 1. 2. 3. 4.]
- >>> print(np.pad(tensor, (3, 4), mode="linear_ramp", end_values=(10, 10)))
- [10. 7. 4. 1. 2. 3. 4. 5. 6.25 7.5 8.75 10. ]
- """
- arr = _to_tensor(arr)
- if arr.ndim == 0:
- return arr
- pad_width = _convert_pad_to_nd(pad_width, arr.ndim)
- stat_func = {"maximum": _reduce_max_keepdims,
- "minimum": _reduce_min_keepdims,
- "mean": _reduce_mean_keepdims,
- "median": "not implemented"}
-
- if mode not in ("constant", "maximum", "minimum", "mean", "median", "edge",
- "wrap", "linear_ramp", "symmetric", "reflect", "empty") and \
- not _callable(arr, mode):
- _raise_value_error("Input mode not supported.")
-
- if mode == "constant":
- constant_values = _convert_pad_to_nd(constant_values, arr.ndim)
- return _pad_constant(arr, pad_width, constant_values)
- if mode in ("maximum", "minimum", "mean", "median"):
- # support median mode once P.Sort/P.Median is supported on GPU/CPU
- if mode == "median":
- _raise_unimplemented_error("median mode is not supported yet")
- return _pad_statistic(arr, pad_width, stat_length, stat_func[mode])
- if mode == "edge":
- return _pad_edge(arr, pad_width)
- if mode == "wrap":
- return _pad_wrap(arr, pad_width)
- if mode == "linear_ramp":
- return _pad_linear(arr, pad_width, end_values)
- if mode == "symmetric":
- return _pad_symmetric(arr, pad_width, reflect_type)
- if mode == "reflect":
- return _pad_reflect(arr, pad_width, reflect_type)
- if mode == 'empty':
- return _pad_empty(arr, pad_width)
- return _pad_func(arr, pad_width, mode, **kwargs)
|