Source code for mindspore.numpy.logic_ops

# Copyright 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.
# ============================================================================
"""logical operations, the function docs are adapted from Numpy API."""


from ..ops import functional as F
from ..ops.primitive import constexpr
from ..common import dtype as mstype
from ..common import Tensor
from .._c_expression import typing

from .math_ops import _apply_tensor_op, absolute
from .array_creations import zeros, ones, empty
from .utils import _check_input_tensor, _to_tensor, _isnan
from .utils_const import _raise_type_error, _is_shape_empty, _infer_out_shape


[docs]def not_equal(x1, x2, dtype=None): """ Returns (x1 != x2) element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): First input tensor to be compared. x2 (Tensor): Second input tensor to be compared. dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are scalars. Raises: TypeError: If the input is not a tensor. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> a = np.asarray([1, 2]) >>> b = np.asarray([[1, 3],[1, 4]]) >>> print(np.not_equal(a, b)) [[False True] [False True]] """ _check_input_tensor(x1, x2) return _apply_tensor_op(F.not_equal, x1, x2, dtype=dtype)
[docs]def less_equal(x1, x2, dtype=None): """ Returns the truth value of ``(x1 <= x2)`` element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): Input array. x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are scalars. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.less_equal(np.array([4, 2, 1]), np.array([2, 2, 2])) >>> print(output) [False True True] """ _check_input_tensor(x1, x2) return _apply_tensor_op(F.tensor_le, x1, x2, dtype=dtype)
[docs]def less(x1, x2, dtype=None): """ Returns the truth value of ``(x1 < x2)`` element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): input array. x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are scalars. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.less(np.array([1, 2]), np.array([2, 2])) >>> print(output) [ True False] """ return _apply_tensor_op(F.tensor_lt, x1, x2, dtype=dtype)
[docs]def greater_equal(x1, x2, dtype=None): """ Returns the truth value of ``(x1 >= x2)`` element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): Input array. x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are scalars. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.greater_equal(np.array([4, 2, 1]), np.array([2, 2, 2])) >>> print(output) [ True True False] """ return _apply_tensor_op(F.tensor_ge, x1, x2, dtype=dtype)
[docs]def greater(x1, x2, dtype=None): """ Returns the truth value of ``(x1 > x2)`` element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): Input array. x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are scalars. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.greater(np.array([4, 2]), np.array([2, 2])) >>> print(output) [ True False] """ return _apply_tensor_op(F.tensor_gt, x1, x2, dtype=dtype)
[docs]def equal(x1, x2, dtype=None): """ Returns the truth value of ``(x1 == x2)`` element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): Input array. x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are scalars. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.equal(np.array([0, 1, 3]), np.arange(3)) >>> print(output) [ True True False] """ return _apply_tensor_op(F.equal, x1, x2, dtype=dtype)
[docs]def isfinite(x, dtype=None): """ Tests element-wise for finiteness (not infinity or not Not a Number). The result is returned as a boolean array. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. On GPU, the supported dtypes are np.float16, and np.float32. Args: x (Tensor): Input values. dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, true where `x` is not positive infinity, negative infinity, or NaN; false otherwise. This is a scalar if `x` is a scalar. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.isfinite(np.array([np.inf, 1., np.nan]).astype('float32')) >>> print(output) [False True False] """ return _apply_tensor_op(F.isfinite, x, dtype=dtype)
[docs]def isnan(x, dtype=None): """ Tests element-wise for NaN and return result as a boolean array. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Only np.float32 is currently supported. Args: x (Tensor): Input values. dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, true where `x` is NaN, false otherwise. This is a scalar if `x` is a scalar. Supported Platforms: ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.isnan(np.array(np.nan, np.float32)) >>> print(output) True >>> output = np.isnan(np.array(np.inf, np.float32)) >>> print(output) False """ return _apply_tensor_op(_isnan, x, dtype=dtype)
def _isinf(x): """Computes isinf without applying keyword arguments.""" shape = F.shape(x) zeros_tensor = zeros(shape, mstype.float32) ones_tensor = ones(shape, mstype.float32) not_inf = F.isfinite(x) is_nan = _isnan(x) res = F.select(not_inf, zeros_tensor, ones_tensor) res = F.select(is_nan, zeros_tensor, res) return F.cast(res, mstype.bool_)
[docs]def isinf(x, dtype=None): """ Tests element-wise for positive or negative infinity. Returns a boolean array of the same shape as `x`, True where ``x == +/-inf``, otherwise False. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Only np.float32 is currently supported. Args: x (Tensor): Input values. dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, true where `x` is positive or negative infinity, false otherwise. This is a scalar if `x` is a scalar. Supported Platforms: ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.isinf(np.array(np.inf, np.float32)) >>> print(output) True >>> output = np.isinf(np.array([np.inf, -np.inf, 1.0, np.nan], np.float32)) >>> print(output) [ True True False False] """ return _apply_tensor_op(_isinf, x, dtype=dtype)
def _is_sign_inf(x, fn): """Tests element-wise for inifinity with sign.""" shape = F.shape(x) zeros_tensor = zeros(shape, mstype.float32) ones_tensor = ones(shape, mstype.float32) not_inf = F.isfinite(x) is_sign = fn(x, zeros_tensor) res = F.select(not_inf, zeros_tensor, ones_tensor) res = F.select(is_sign, res, zeros_tensor) return F.cast(res, mstype.bool_)
[docs]def isposinf(x): """ Tests element-wise for positive infinity, returns result as bool array. Note: Numpy argument `out` is not supported. Only np.float32 is currently supported. Args: x (Tensor): Input values. Returns: Tensor or scalar, true where `x` is positive infinity, false otherwise. This is a scalar if `x` is a scalar. Raises: TypeError: if the input is not a tensor. Supported Platforms: ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.isposinf(np.array([-np.inf, 0., np.inf], np.float32)) >>> print(output) [False False True] """ _check_input_tensor(x) return _is_sign_inf(x, F.tensor_gt)
[docs]def isneginf(x): """ Tests element-wise for negative infinity, returns result as bool array. Note: Numpy argument `out` is not supported. Only np.float32 is currently supported. Args: x (Tensor): Input values. Returns: Tensor or scalar, true where `x` is negative infinity, false otherwise. This is a scalar if `x` is a scalar. Raises: TypeError: if the input is not a tensor. Supported Platforms: ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.isneginf(np.array([-np.inf, 0., np.inf], np.float32)) >>> print(output) [ True False False] """ return _is_sign_inf(x, F.tensor_lt)
@constexpr def _isscalar(x): """Returns True if x is a scalar type""" return isinstance(x, (typing.Number, typing.Int, typing.UInt, typing.Float, typing.Bool, typing.String))
[docs]def isscalar(element): """ Returns True if the type of element is a scalar type. Note: Only object types recognized by the mindspore parser are supported, which includes objects, types, methods and functions defined within the scope of mindspore. Other built-in types are not supported. Args: element (any): Input argument, can be of any type and shape. Returns: Boolean, True if `element` is a scalar type, False if it is not. Raises: TypeError: if the type of `element` is not supported by mindspore parser. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> output = np.isscalar(3.1) >>> print(output) True >>> output = np.isscalar(np.array(3.1)) >>> print(output) False >>> output = np.isscalar(False) >>> print(output) True >>> output = np.isscalar('numpy') >>> print(output) True """ obj_type = F.typeof(element) return not isinstance(obj_type, Tensor) and _isscalar(obj_type)
def isclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False): """ Returns a boolean tensor where two tensors are element-wise equal within a tolerance. The tolerance values are positive, typically very small numbers. The relative difference (:math:`rtol * abs(b)`) and the absolute difference `atol` are added together to compare against the absolute difference between `a` and `b`. Note: For finite values, isclose uses the following equation to test whether two floating point values are equivalent. :math:`absolute(a - b) <= (atol + rtol * absolute(b))` Args: a (Union[Tensor, list, tuple]): Input first tensor to compare. b (Union[Tensor, list, tuple]): Input second tensor to compare. rtol (Number): The relative tolerance parameter (see Note). atol (Number): The absolute tolerance parameter (see Note). equal_nan (bool): Whether to compare ``NaN`` as equal. If True, ``NaN`` in `a` will be considered equal to ``NaN`` in `b` in the output tensor. Returns: A ``bool`` tensor of where `a` and `b` are equal within the given tolerance. Raises: TypeError: If inputs have types not specified above. Supported Platforms: ``GPU`` ``CPU`` Examples: >>> a = np.array([0,1,2,float('inf'),float('inf'),float('nan')]) >>> b = np.array([0,1,-2,float('-inf'),float('inf'),float('nan')]) >>> print(np.isclose(a, b)) [ True True False False True False] >>> print(np.isclose(a, b, equal_nan=True)) [ True True False False True True] """ a, b = _to_tensor(a, b) if not isinstance(rtol, (int, float, bool)) or not isinstance(atol, (int, float, bool)): _raise_type_error("rtol and atol are expected to be numbers.") if not isinstance(equal_nan, bool): _raise_type_error("equal_nan is expected to be bool.") if _is_shape_empty(a.shape) or _is_shape_empty(b.shape): return empty(_infer_out_shape(a.shape, b.shape), dtype=mstype.bool_) rtol = _to_tensor(rtol).astype("float32") atol = _to_tensor(atol).astype("float32") res = absolute(a - b) <= (atol + rtol * absolute(b)) # infs are treated as equal a_posinf = isposinf(a) b_posinf = isposinf(b) a_neginf = isneginf(a) b_neginf = isneginf(b) same_inf = F.logical_or(F.logical_and(a_posinf, b_posinf), F.logical_and(a_neginf, b_neginf)) diff_inf = F.logical_or(F.logical_and(a_posinf, b_neginf), F.logical_and(a_neginf, b_posinf)) res = F.logical_and(F.logical_or(res, same_inf), F.logical_not(diff_inf)) both_nan = F.logical_and(_isnan(a), _isnan(b)) if equal_nan: res = F.logical_or(both_nan, res) else: res = F.logical_and(F.logical_not(both_nan), res) return res def in1d(ar1, ar2, invert=False): """ Tests whether each element of a 1-D array is also present in a second array. Returns a boolean array the same length as `ar1` that is True where an element of `ar1` is in `ar2` and False otherwise. Note: Numpy argument `assume_unique` is not supported since the implementation does not rely on the uniqueness of the input arrays. Args: ar1 (array_like): Input array with shape `(M,)`. ar2 (array_like): The values against which to test each value of `ar1`. invert (boolean, optional): If True, the values in the returned array are inverted (that is, False where an element of `ar1` is in `ar2` and True otherwise). Default is False. Returns: Tensor, with shape `(M,)`. The values ``ar1[in1d]`` are in `ar2`. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> test = np.array([0, 1, 2, 5, 0]) >>> states = [0, 2] >>> mask = np.in1d(test, states) >>> print(mask) [ True False True False True] >>> mask = np.in1d(test, states, invert=True) >>> print(mask) [False True False True False] """ ar1, ar2 = _to_tensor(ar1, ar2) ar1 = F.expand_dims(ar1.ravel(), -1) ar2 = ar2.ravel() included = F.equal(ar1, ar2) # F.reduce_sum only supports float res = F.reduce_sum(included.astype(mstype.float32), -1).astype(mstype.bool_) if invert: res = F.logical_not(res) return res def isin(element, test_elements, invert=False): """ Calculates element in `test_elements`, broadcasting over `element` only. Returns a boolean array of the same shape as `element` that is True where an element of `element` is in `test_elements` and False otherwise. Note: Numpy argument `assume_unique` is not supported since the implementation does not rely on the uniqueness of the input arrays. Args: element (array_like): Input array. test_elements (array_like): The values against which to test each value of `element`. invert (boolean, optional): If True, the values in the returned array are inverted, as if calculating `element` not in `test_elements`. Default is False. Returns: Tensor, has the same shape as `element`. The values ``element[isin]`` are in `test_elements`. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> element = 2*np.arange(4).reshape((2, 2)) >>> test_elements = [1, 2, 4, 8] >>> mask = np.isin(element, test_elements) >>> print(mask) [[False True] [ True False]] >>> mask = np.isin(element, test_elements, invert=True) >>> print(mask) [[ True False] [False True]] """ res = in1d(element, test_elements, invert=invert) return F.reshape(res, F.shape(element)) def logical_not(a, dtype=None): """ Computes the truth value of NOT `a` element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: a (Tensor): The input tensor whose dtype is bool. dtype (:class:`mindspore.dtype`, optional): Default: :class:`None`. Overrides the dtype of the output Tensor. Returns: Tensor or scalar. Boolean result with the same shape as `a` of the NOT operation on elements of `a`. This is a scalar if `a` is a scalar. Raises: TypeError: if the input is not a tensor or its dtype is not bool. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> a = np.array([True, False]) >>> output = np.logical_not(a) >>> print(output) [False True] """ return _apply_tensor_op(F.logical_not, a, dtype=dtype) def logical_or(x1, x2, dtype=None): """ Computes the truth value of `x1` OR `x2` element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): Input tensor. x2 (Tensor): Input tensor. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type bool, unless ``dtype=object`` is passed. This is a scalar if both `x1` and `x2` are scalars. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> x1 = np.array([True, False]) >>> x2 = np.array([False, True]) >>> output = np.logical_or(x1, x2) >>> print(output) [ True True] """ return _apply_tensor_op(F.logical_or, x1, x2, dtype=dtype) def logical_and(x1, x2, dtype=None): """ Computes the truth value of `x1` AND `x2` element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): Input tensor. x2 (Tensor): Input tensor. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar. Boolean result of the logical AND operation applied to the elements of `x1` and `x2`; the shape is determined by broadcasting. This is a scalar if both `x1` and `x2` are scalars. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> x1 = np.array([True, False]) >>> x2 = np.array([False, False]) >>> output = np.logical_and(x1, x2) >>> print(output) [False False] """ return _apply_tensor_op(F.logical_and, x1, x2, dtype=dtype) def logical_xor(x1, x2, dtype=None): """ Computes the truth value of `x1` XOR `x2`, element-wise. Note: Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are not supported. Args: x1 (Tensor): Input tensor. x2 (Tensor): Input tensor. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the output Tensor. Returns: Tensor or scalar. Boolean result of the logical AND operation applied to the elements of `x1` and `x2`; the shape is determined by broadcasting. This is a scalar if both `x1` and `x2` are scalars. Supported Platforms: ``Ascend`` ``GPU`` ``CPU`` Examples: >>> import mindspore.numpy as np >>> x1 = np.array([True, False]) >>> x2 = np.array([False, False]) >>> output = np.logical_xor(x1, x2) >>> print(output) [True False] """ _check_input_tensor(x1) _check_input_tensor(x2) y1 = F.logical_or(x1, x2) y2 = F.logical_or(F.logical_not(x1), F.logical_not(x2)) return _apply_tensor_op(F.logical_and, y1, y2, dtype=dtype)