• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2021 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15"""logical operations, the function docs are adapted from Numpy API."""
16
17
18from ..ops import functional as F
19from ..common import dtype as mstype
20from ..common import Tensor
21
22from .math_ops import _apply_tensor_op, absolute
23from .array_creations import zeros, ones, empty, asarray
24from .utils import _check_input_tensor, _to_tensor, _isnan
25from .utils_const import _raise_type_error, _is_shape_empty, _infer_out_shape, _check_same_type, \
26    _check_axis_type, _canonicalize_axis, _can_broadcast, _isscalar
27
28
29def not_equal(x1, x2, dtype=None):
30    """
31    Returns (x1 != x2) element-wise.
32
33    Note:
34        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
35        and `extobj` are not supported.
36
37    Args:
38        x1 (Tensor): First input tensor to be compared.
39        x2 (Tensor): Second input tensor to be compared.
40        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
41            output Tensor.
42
43    Returns:
44       Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type
45       bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are
46       scalars.
47
48    Raises:
49        TypeError: If the input is not a tensor.
50
51    Supported Platforms:
52        ``Ascend`` ``GPU`` ``CPU``
53
54    Examples:
55        >>> import mindspore.numpy as np
56        >>> a = np.asarray([1, 2])
57        >>> b = np.asarray([[1, 3],[1, 4]])
58        >>> print(np.not_equal(a, b))
59        [[False  True]
60        [False  True]]
61    """
62    _check_input_tensor(x1, x2)
63    return _apply_tensor_op(F.not_equal, x1, x2, dtype=dtype)
64
65
66def less_equal(x1, x2, dtype=None):
67    """
68    Returns the truth value of ``(x1 <= x2)`` element-wise.
69
70    Note:
71        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
72        and `extobj` are not supported.
73
74    Args:
75        x1 (Tensor): Input array.
76        x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be
77            broadcastable to a common shape (which becomes the shape of the output).
78        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
79            output Tensor.
80
81    Returns:
82       Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type
83       bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are
84       scalars.
85
86    Supported Platforms:
87        ``Ascend`` ``GPU`` ``CPU``
88
89    Examples:
90        >>> import mindspore.numpy as np
91        >>> output = np.less_equal(np.array([4, 2, 1]), np.array([2, 2, 2]))
92        >>> print(output)
93        [False  True  True]
94    """
95    _check_input_tensor(x1, x2)
96    return _apply_tensor_op(F.tensor_le, x1, x2, dtype=dtype)
97
98
99def less(x1, x2, dtype=None):
100    """
101    Returns the truth value of ``(x1 < x2)`` element-wise.
102
103    Note:
104        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
105        and `extobj` are not supported.
106
107    Args:
108        x1 (Tensor): input array.
109        x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be
110            broadcastable to a common shape (which becomes the shape of the output).
111        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
112            output Tensor.
113
114    Returns:
115       Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type
116       bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are
117       scalars.
118
119    Supported Platforms:
120        ``Ascend`` ``GPU`` ``CPU``
121
122    Examples:
123        >>> import mindspore.numpy as np
124        >>> output = np.less(np.array([1, 2]), np.array([2, 2]))
125        >>> print(output)
126        [ True False]
127    """
128    return _apply_tensor_op(F.tensor_lt, x1, x2, dtype=dtype)
129
130
131def greater_equal(x1, x2, dtype=None):
132    """
133    Returns the truth value of ``(x1 >= x2)`` element-wise.
134
135    Note:
136        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
137        and `extobj` are not supported.
138
139    Args:
140        x1 (Tensor): Input array.
141        x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be
142            broadcastable to a common shape (which becomes the shape of the output).
143        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
144            output Tensor.
145
146    Returns:
147       Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type
148       bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are
149       scalars.
150
151    Supported Platforms:
152        ``Ascend`` ``GPU`` ``CPU``
153
154    Examples:
155        >>> import mindspore.numpy as np
156        >>> output = np.greater_equal(np.array([4, 2, 1]), np.array([2, 2, 2]))
157        >>> print(output)
158        [ True  True False]
159    """
160    return _apply_tensor_op(F.tensor_ge, x1, x2, dtype=dtype)
161
162
163def greater(x1, x2, dtype=None):
164    """
165    Returns the truth value of ``(x1 > x2)`` element-wise.
166
167    Note:
168        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
169        and `extobj` are not supported.
170
171    Args:
172        x1 (Tensor): Input array.
173        x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be
174            broadcastable to a common shape (which becomes the shape of the output).
175        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
176            output Tensor.
177
178    Returns:
179       Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type
180       bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are
181       scalars.
182
183    Supported Platforms:
184        ``Ascend`` ``GPU`` ``CPU``
185
186    Examples:
187        >>> import mindspore.numpy as np
188        >>> output = np.greater(np.array([4, 2]), np.array([2, 2]))
189        >>> print(output)
190        [ True False]
191    """
192    return _apply_tensor_op(F.tensor_gt, x1, x2, dtype=dtype)
193
194
195def equal(x1, x2, dtype=None):
196    """
197    Returns the truth value of ``(x1 == x2)`` element-wise.
198
199    Note:
200        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
201        and `extobj` are not supported.
202
203    Args:
204        x1 (Tensor): Input array.
205        x2 (Tensor): Input array. If ``x1.shape != x2.shape``, they must be
206            broadcastable to a common shape (which becomes the shape of the output).
207        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
208            output Tensor.
209
210    Returns:
211       Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type
212       bool, unless `dtype` is passed. This is a scalar if both `x1` and `x2` are
213       scalars.
214
215    Supported Platforms:
216        ``Ascend`` ``GPU`` ``CPU``
217
218    Examples:
219        >>> import mindspore.numpy as np
220        >>> output = np.equal(np.array([0, 1, 3]), np.arange(3))
221        >>> print(output)
222        [ True  True False]
223    """
224    return _apply_tensor_op(F.equal, x1, x2, dtype=dtype)
225
226
227def isfinite(x, dtype=None):
228    """
229    Tests element-wise for finiteness (not infinity or not Not a Number).
230
231    The result is returned as a boolean array.
232
233    Note:
234        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
235        and `extobj` are not supported.
236        On GPU, the supported dtypes are np.float16, and np.float32.
237
238    Args:
239        x (Tensor): Input values.
240        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
241            output Tensor.
242
243    Returns:
244       Tensor or scalar, true where `x` is not positive infinity, negative infinity,
245       or NaN; false otherwise. This is a scalar if `x` is a scalar.
246
247    Supported Platforms:
248        ``Ascend`` ``GPU`` ``CPU``
249
250    Examples:
251        >>> import mindspore.numpy as np
252        >>> output = np.isfinite(np.array([np.inf, 1., np.nan]).astype('float32'))
253        >>> print(output)
254        [False  True False]
255    """
256    return _apply_tensor_op(F.isfinite, x, dtype=dtype)
257
258
259def isnan(x, dtype=None):
260    """
261    Tests element-wise for NaN and return result as a boolean array.
262
263    Note:
264        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
265        and `extobj` are not supported.
266        Only np.float32 is currently supported.
267
268    Args:
269        x (Tensor): Input values.
270        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
271            output Tensor.
272
273    Returns:
274       Tensor or scalar, true where `x` is NaN, false otherwise. This is a scalar if
275       `x` is a scalar.
276
277    Supported Platforms:
278        ``GPU`` ``CPU``
279
280    Examples:
281        >>> import mindspore.numpy as np
282        >>> output = np.isnan(np.array(np.nan, np.float32))
283        >>> print(output)
284        True
285        >>> output = np.isnan(np.array(np.inf, np.float32))
286        >>> print(output)
287        False
288    """
289    return _apply_tensor_op(_isnan, x, dtype=dtype)
290
291
292def _isinf(x):
293    """Computes isinf without applying keyword arguments."""
294    shape = F.shape(x)
295    zeros_tensor = zeros(shape, mstype.float32)
296    ones_tensor = ones(shape, mstype.float32)
297    not_inf = F.isfinite(x)
298    is_nan = _isnan(x)
299    res = F.select(not_inf, zeros_tensor, ones_tensor)
300    res = F.select(is_nan, zeros_tensor, res)
301    return F.cast(res, mstype.bool_)
302
303
304def isinf(x, dtype=None):
305    """
306    Tests element-wise for positive or negative infinity.
307
308    Returns a boolean array of the same shape as `x`, True where ``x == +/-inf``, otherwise False.
309
310    Note:
311        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
312        and `extobj` are not supported.
313        Only np.float32 is currently supported.
314
315    Args:
316        x (Tensor): Input values.
317        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
318            output Tensor.
319
320    Returns:
321       Tensor or scalar, true where `x` is positive or negative infinity, false
322       otherwise. This is a scalar if `x` is a scalar.
323
324    Supported Platforms:
325        ``GPU`` ``CPU``
326
327    Examples:
328        >>> import mindspore.numpy as np
329        >>> output = np.isinf(np.array(np.inf, np.float32))
330        >>> print(output)
331        True
332        >>> output = np.isinf(np.array([np.inf, -np.inf, 1.0, np.nan], np.float32))
333        >>> print(output)
334        [ True  True False False]
335    """
336    return _apply_tensor_op(_isinf, x, dtype=dtype)
337
338
339def _is_sign_inf(x, fn):
340    """Tests element-wise for inifinity with sign."""
341    shape = F.shape(x)
342    zeros_tensor = zeros(shape, mstype.float32)
343    ones_tensor = ones(shape, mstype.float32)
344    not_inf = F.isfinite(x)
345    is_sign = fn(x, zeros_tensor)
346    res = F.select(not_inf, zeros_tensor, ones_tensor)
347    res = F.select(is_sign, res, zeros_tensor)
348    return F.cast(res, mstype.bool_)
349
350
351def isposinf(x):
352    """
353    Tests element-wise for positive infinity, returns result as bool array.
354
355    Note:
356        Numpy argument `out` is not supported.
357        Only np.float32 is currently supported.
358
359    Args:
360        x (Tensor): Input values.
361
362    Returns:
363       Tensor or scalar, true where `x` is positive infinity, false otherwise.
364       This is a scalar if `x` is a scalar.
365
366    Raises:
367        TypeError: if the input is not a tensor.
368
369    Supported Platforms:
370        ``GPU`` ``CPU``
371
372    Examples:
373        >>> import mindspore.numpy as np
374        >>> output = np.isposinf(np.array([-np.inf, 0., np.inf, np.nan], np.float32))
375        >>> print(output)
376        [False False  True False]
377    """
378    _check_input_tensor(x)
379    return _is_sign_inf(x, F.tensor_gt)
380
381
382def isneginf(x):
383    """
384    Tests element-wise for negative infinity, returns result as bool array.
385
386    Note:
387        Numpy argument `out` is not supported.
388        Only np.float32 is currently supported.
389
390    Args:
391        x (Tensor): Input values.
392
393    Returns:
394       Tensor or scalar, true where `x` is negative infinity, false otherwise.
395       This is a scalar if `x` is a scalar.
396
397    Raises:
398        TypeError: if the input is not a tensor.
399
400    Supported Platforms:
401        ``GPU`` ``CPU``
402
403    Examples:
404        >>> import mindspore.numpy as np
405        >>> output = np.isneginf(np.array([-np.inf, 0., np.inf, np.nan], np.float32))
406        >>> print(output)
407        [ True False False False]
408    """
409    return _is_sign_inf(x, F.tensor_lt)
410
411
412def isscalar(element):
413    """
414    Returns True if the type of element is a scalar type.
415
416    Note:
417        Only object types recognized by the mindspore parser are supported,
418        which includes objects, types, methods and functions defined within
419        the scope of mindspore. Other built-in types are not supported.
420
421    Args:
422        element (any): Input argument, can be of any type and shape.
423
424    Returns:
425        Boolean, True if `element` is a scalar type, False if it is not.
426
427    Raises:
428        TypeError: if the type of `element` is not supported by mindspore parser.
429
430    Supported Platforms:
431        ``Ascend`` ``GPU`` ``CPU``
432
433    Examples:
434        >>> import mindspore.numpy as np
435        >>> output = np.isscalar(3.1)
436        >>> print(output)
437        True
438        >>> output = np.isscalar(np.array(3.1))
439        >>> print(output)
440        False
441        >>> output = np.isscalar(False)
442        >>> print(output)
443        True
444        >>> output = np.isscalar('numpy')
445        >>> print(output)
446        True
447    """
448    obj_type = F.typeof(element)
449    return not isinstance(obj_type, Tensor) and _isscalar(obj_type)
450
451
452def isclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False):
453    """
454    Returns a boolean tensor where two tensors are element-wise equal within a tolerance.
455
456    The tolerance values are positive, typically very small numbers. The relative
457    difference (:math:`rtol * abs(b)`) and the absolute difference `atol` are added together
458    to compare against the absolute difference between `a` and `b`.
459
460    Note:
461        For finite values, isclose uses the following equation to test whether two
462        floating point values are equivalent.
463        :math:`absolute(a - b) <= (atol + rtol * absolute(b))`
464        On Ascend, input arrays containing inf or NaN are not supported.
465
466    Args:
467        a (Union[Tensor, list, tuple]): Input first tensor to compare.
468        b (Union[Tensor, list, tuple]): Input second tensor to compare.
469        rtol (numbers.Number): The relative tolerance parameter (see Note).
470        atol (numbers.Number): The absolute tolerance parameter (see Note).
471        equal_nan (bool): Whether to compare ``NaN`` as equal. If True, ``NaN`` in
472            `a` will be considered equal to ``NaN`` in `b` in the output tensor.
473
474    Returns:
475        A ``bool`` tensor of where `a` and `b` are equal within the given tolerance.
476
477    Raises:
478        TypeError: If inputs have types not specified above.
479
480    Supported Platforms:
481        ``Ascend`` ``GPU`` ``CPU``
482
483    Examples:
484        >>> a = np.array([0,1,2,float('inf'),float('inf'),float('nan')])
485        >>> b = np.array([0,1,-2,float('-inf'),float('inf'),float('nan')])
486        >>> print(np.isclose(a, b))
487        [ True  True False False  True False]
488        >>> print(np.isclose(a, b, equal_nan=True))
489        [ True  True False False  True  True]
490    """
491    a, b = _to_tensor(a, b)
492    if not isinstance(rtol, (int, float, bool)) or not isinstance(atol, (int, float, bool)):
493        _raise_type_error("rtol and atol are expected to be numbers.")
494    if not isinstance(equal_nan, bool):
495        _raise_type_error("equal_nan is expected to be bool.")
496
497    if _is_shape_empty(a.shape) or _is_shape_empty(b.shape):
498        return empty(_infer_out_shape(a.shape, b.shape), dtype=mstype.bool_)
499    rtol = _to_tensor(rtol).astype("float32")
500    atol = _to_tensor(atol).astype("float32")
501    res = absolute(a - b) <= (atol + rtol * absolute(b))
502    # infs are treated as equal
503    a_posinf = isposinf(a)
504    b_posinf = isposinf(b)
505    a_neginf = isneginf(a)
506    b_neginf = isneginf(b)
507    same_inf = F.logical_or(F.logical_and(a_posinf, b_posinf), F.logical_and(a_neginf, b_neginf))
508    diff_inf = F.logical_or(F.logical_and(a_posinf, b_neginf), F.logical_and(a_neginf, b_posinf))
509    res = F.logical_and(F.logical_or(res, same_inf), F.logical_not(diff_inf))
510    both_nan = F.logical_and(_isnan(a), _isnan(b))
511    if equal_nan:
512        res = F.logical_or(both_nan, res)
513    else:
514        res = F.logical_and(F.logical_not(both_nan), res)
515    return res
516
517
518def in1d(ar1, ar2, invert=False):
519    """
520    Tests whether each element of a 1-D array is also present in a second array.
521
522    Returns a boolean array the same length as `ar1` that is True where an element
523    of `ar1` is in `ar2` and False otherwise.
524
525    Note:
526        Numpy argument `assume_unique` is not supported since the implementation does
527        not rely on the uniqueness of the input arrays.
528
529    Args:
530        ar1 (Union[int, float, bool, list, tuple, Tensor]): Input array with shape `(M,)`.
531        ar2 (Union[int, float, bool, list, tuple, Tensor]): The values against which
532            to test each value of `ar1`.
533        invert (boolean, optional): If True, the values in the returned array are
534            inverted (that is, False where an element of `ar1` is in `ar2` and True
535            otherwise). Default is False.
536
537    Returns:
538       Tensor, with shape `(M,)`. The values ``ar1[in1d]`` are in `ar2`.
539
540    Supported Platforms:
541        ``Ascend`` ``GPU`` ``CPU``
542
543    Examples:
544        >>> test = np.array([0, 1, 2, 5, 0])
545        >>> states = [0, 2]
546        >>> mask = np.in1d(test, states)
547        >>> print(mask)
548        [ True False  True False  True]
549        >>> mask = np.in1d(test, states, invert=True)
550        >>> print(mask)
551        [False  True False  True False]
552    """
553    ar1, ar2 = _to_tensor(ar1, ar2)
554    ar1 = F.expand_dims(ar1.ravel(), -1)
555    ar2 = ar2.ravel()
556    included = F.equal(ar1, ar2)
557    # F.reduce_sum only supports float
558    res = F.reduce_sum(included.astype(mstype.float32), -1).astype(mstype.bool_)
559    if invert:
560        res = F.logical_not(res)
561    return res
562
563
564def isin(element, test_elements, invert=False):
565    """
566    Calculates element in `test_elements`, broadcasting over `element` only. Returns a
567    boolean array of the same shape as `element` that is True where an element of
568    `element` is in `test_elements` and False otherwise.
569
570    Note:
571        Numpy argument `assume_unique` is not supported since the implementation does
572        not rely on the uniqueness of the input arrays.
573
574    Args:
575        element (Union[int, float, bool, list, tuple, Tensor]): Input array.
576        test_elements (Union[int, float, bool, list, tuple, Tensor]): The values against
577            which to test each value of `element`.
578        invert (boolean, optional): If True, the values in the returned array are
579            inverted, as if calculating `element` not in `test_elements`. Default is False.
580
581    Returns:
582       Tensor, has the same shape as `element`. The values ``element[isin]`` are in
583       `test_elements`.
584
585    Supported Platforms:
586        ``Ascend`` ``GPU`` ``CPU``
587
588    Examples:
589        >>> element = 2*np.arange(4).reshape((2, 2))
590        >>> test_elements = [1, 2, 4, 8]
591        >>> mask = np.isin(element, test_elements)
592        >>> print(mask)
593        [[False  True]
594        [ True False]]
595        >>> mask = np.isin(element, test_elements, invert=True)
596        >>> print(mask)
597        [[ True False]
598        [False  True]]
599    """
600    element = _to_tensor(element)
601    res = in1d(element, test_elements, invert=invert)
602    return F.reshape(res, F.shape(element))
603
604
605def logical_not(a, dtype=None):
606    """
607    Computes the truth value of NOT `a` element-wise.
608
609    Note:
610        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and `extobj` are
611        not supported.
612
613    Args:
614        a (Tensor): The input tensor whose dtype is bool.
615        dtype (:class:`mindspore.dtype`, optional): Default: :class:`None`. Overrides the dtype of the
616            output Tensor.
617
618    Returns:
619        Tensor or scalar.
620        Boolean result with the same shape as `a` of the NOT operation on elements of `a`.
621        This is a scalar if `a` is a scalar.
622
623    Raises:
624        TypeError: if the input is not a tensor or its dtype is not bool.
625
626    Supported Platforms:
627        ``Ascend`` ``GPU`` ``CPU``
628
629    Examples:
630        >>> import mindspore.numpy as np
631        >>> a = np.array([True, False])
632        >>> output = np.logical_not(a)
633        >>> print(output)
634        [False  True]
635    """
636    return _apply_tensor_op(F.logical_not, a, dtype=dtype)
637
638
639def logical_or(x1, x2, dtype=None):
640    """
641    Computes the truth value of `x1` OR `x2` element-wise.
642
643    Note:
644        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
645        and `extobj` are not supported.
646
647    Args:
648        x1 (Tensor): Input tensor.
649        x2 (Tensor): Input tensor. If ``x1.shape != x2.shape``, they must be
650            broadcastable to a common shape (which becomes the shape of the output).
651        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
652            output Tensor.
653
654    Returns:
655       Tensor or scalar, element-wise comparison of `x1` and `x2`. Typically of type
656       bool, unless ``dtype=object`` is passed. This is a scalar if both `x1` and `x2` are
657       scalars.
658
659    Supported Platforms:
660        ``Ascend`` ``GPU`` ``CPU``
661
662    Examples:
663        >>> import mindspore.numpy as np
664        >>> x1 = np.array([True, False])
665        >>> x2 = np.array([False, True])
666        >>> output = np.logical_or(x1, x2)
667        >>> print(output)
668        [ True  True]
669    """
670    return _apply_tensor_op(F.logical_or, x1, x2, dtype=dtype)
671
672
673def logical_and(x1, x2, dtype=None):
674    """
675    Computes the truth value of `x1` AND `x2` element-wise.
676
677    Note:
678        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
679        and `extobj` are not supported.
680
681    Args:
682        x1 (Tensor): Input tensor.
683        x2 (Tensor): Input tensor. If ``x1.shape != x2.shape``, they must be
684            broadcastable to a common shape (which becomes the shape of the output).
685        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
686            output Tensor.
687
688    Returns:
689        Tensor or scalar.
690        Boolean result of the logical AND operation applied to the elements of `x1` and `x2`;
691        the shape is determined by broadcasting. This is a scalar if both `x1` and `x2` are scalars.
692
693    Supported Platforms:
694        ``Ascend`` ``GPU`` ``CPU``
695
696    Examples:
697        >>> import mindspore.numpy as np
698        >>> x1 = np.array([True, False])
699        >>> x2 = np.array([False, False])
700        >>> output = np.logical_and(x1, x2)
701        >>> print(output)
702        [False False]
703    """
704    return _apply_tensor_op(F.logical_and, x1, x2, dtype=dtype)
705
706
707def logical_xor(x1, x2, dtype=None):
708    """
709    Computes the truth value of `x1` XOR `x2`, element-wise.
710
711    Note:
712        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`,
713        and `extobj` are not supported.
714
715    Args:
716        x1 (Tensor): Input tensor.
717        x2 (Tensor): Input tensor. If ``x1.shape != x2.shape``, they must be
718            broadcastable to a common shape (which becomes the shape of the output).
719        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
720            output Tensor.
721
722    Returns:
723        Tensor or scalar.
724        Boolean result of the logical AND operation applied to the elements of `x1` and `x2`;
725        the shape is determined by broadcasting. This is a scalar if both `x1` and `x2` are scalars.
726
727    Supported Platforms:
728        ``Ascend`` ``GPU`` ``CPU``
729
730    Examples:
731        >>> import mindspore.numpy as np
732        >>> x1 = np.array([True, False])
733        >>> x2 = np.array([False, False])
734        >>> output = np.logical_xor(x1, x2)
735        >>> print(output)
736        [True False]
737    """
738    _check_input_tensor(x1)
739    _check_input_tensor(x2)
740    y1 = F.logical_or(x1, x2)
741    y2 = F.logical_or(F.logical_not(x1), F.logical_not(x2))
742    return _apply_tensor_op(F.logical_and, y1, y2, dtype=dtype)
743
744
745def array_equal(a1, a2, equal_nan=False):
746    """
747    Returns `True` if input arrays have same shapes and all elements equal.
748
749    Note:
750        In mindspore, a bool tensor is returned instead, since in Graph mode, the
751        value cannot be traced and computed at compile time.
752
753        Since on Ascend, :class:`nan` is treated differently, currently the argument
754        `equal_nan` is not supported on Ascend.
755
756    Args:
757        a1/a2 (Union[int, float, bool, list, tuple, Tensor]): Input arrays.
758        equal_nan (bool): Whether to compare NaN’s as equal.
759
760    Returns:
761        Scalar bool tensor, value is `True` if inputs are equal, `False` otherwise.
762
763    Raises:
764        TypeError: If inputs have types not specified above.
765
766    Supported Platforms:
767        ``GPU`` ``CPU`` ``Ascend``
768
769    Examples:
770        >>> import mindspore.numpy as np
771        >>> a = [0,1,2]
772        >>> b = [[0,1,2], [0,1,2]]
773        >>> print(np.array_equal(a,b))
774        False
775    """
776    a1 = asarray(a1)
777    a2 = asarray(a2)
778    if not isinstance(equal_nan, bool):
779        _raise_type_error("equal_nan must be bool.")
780    if a1.shape == a2.shape:
781        res = equal(a1, a2)
782        if equal_nan:
783            res = logical_or(res, logical_and(isnan(a1), isnan(a2)))
784        return res.all()
785    return _to_tensor(False)
786
787
788def array_equiv(a1, a2):
789    """
790    Returns `True` if input arrays are shape consistent and all elements equal.
791
792    Shape consistent means they are either the same shape, or one input array can
793    be broadcasted to create the same shape as the other one.
794
795    Note:
796        In mindspore, a bool tensor is returned instead, since in Graph mode, the
797        value cannot be traced and computed at compile time.
798
799    Args:
800        a1/a2 (Union[int, float, bool, list, tuple, Tensor]): Input arrays.
801
802    Returns:
803        Scalar bool tensor, value is `True` if inputs are equivalent, `False` otherwise.
804
805    Raises:
806        TypeError: If inputs have types not specified above.
807
808    Supported Platforms:
809        ``Ascend`` ``GPU`` ``CPU``
810
811    Examples:
812        >>> import mindspore.numpy as np
813        >>> a = [0,1,2]
814        >>> b = [[0,1,2], [0,1,2]]
815        >>> print(np.array_equiv(a,b))
816        True
817    """
818    a1 = asarray(a1)
819    a2 = asarray(a2)
820    if _can_broadcast(a1.shape, a2.shape):
821        return equal(a1, a2).all()
822    return _to_tensor(False)
823
824
825def signbit(x, dtype=None):
826    """
827    Returns element-wise True where signbit is set (less than zero).
828
829    Note:
830        Numpy arguments `out`, `where`, `casting`, `order`, `subok`, `signature`, and
831        `extobj` are not supported.
832
833    Args:
834        x (Union[int, float, bool, list, tuple, Tensor]): The input value(s).
835        dtype (:class:`mindspore.dtype`, optional): defaults to None. Overrides the dtype of the
836            output Tensor.
837
838    Returns:
839        Tensor.
840
841    Raises:
842        TypeError: If input is not array_like or `dtype` is not `None` or `bool`.
843
844    Supported Platforms:
845        ``Ascend`` ``GPU`` ``CPU``
846
847    Examples:
848        >>> import mindspore.numpy as np
849        >>> x = np.array([1, -2.3, 2.1]).astype('float32')
850        >>> output = np.signbit(x)
851        >>> print(output)
852        [False  True False]
853    """
854    if dtype is not None and not _check_same_type(dtype, mstype.bool_):
855        _raise_type_error("Casting was not allowed for signbit.")
856    x = _to_tensor(x)
857    res = F.less(x, 0)
858    if dtype is not None and not _check_same_type(F.dtype(res), dtype):
859        res = F.cast(res, dtype)
860    return res
861
862
863def sometrue(a, axis=None, keepdims=False):
864    """
865    Tests whether any array element along a given axis evaluates to True.
866
867    Returns single boolean unless axis is not None
868
869    Args:
870        a (Union[int, float, bool, list, tuple, Tensor]): Input tensor or object that can be converted to an array.
871        axis (Union[None, int, tuple(int)]): Axis or axes along which a logical OR reduction is
872            performed. Default: None.
873            If None, perform a logical OR over all the dimensions of the input array.
874            If negative, it counts from the last to the first axis.
875            If tuple of integers, a reduction is performed on multiple axes, instead of a single axis or
876            all the axes as before.
877        keepdims (bool): Default: False.
878            If True, the axes which are reduced are left in the result as dimensions with size one.
879            With this option, the result will broadcast correctly against the input array.
880            If the default value is passed, then keepdims will not be passed through to the any method of
881            sub-classes of ndarray, however any non-default value will be. If the sub-class’ method does not
882            implement keepdims any exceptions will be raised.
883
884    Returns:
885        Returns single boolean unless axis is not None
886
887    Raises:
888        TypeError: If input is not array_like or `axis` is not int or tuple of integers or
889            `keepdims` is not integer or `initial` is not scalar.
890        ValueError: If any axis is out of range or duplicate axes exist.
891
892    Supported Platforms:
893        ``Ascend`` ``GPU`` ``CPU``
894
895    Examples:
896        >>> import mindspore.numpy as np
897        >>> x = np.array([1, -2.3, 2.1]).astype('float32')
898        >>> output = np.sometrue(x)
899        >>> print(output)
900        True
901    """
902    if not isinstance(keepdims, int):
903        _raise_type_error("integer argument expected, but got ", keepdims)
904    if axis is not None:
905        _check_axis_type(axis, True, True, False)
906        axis = _canonicalize_axis(axis, a.ndim)
907    a = _to_tensor(a)
908    keepdims = keepdims not in (0, False)
909    return F.not_equal(a, 0).any(axis, keepdims)
910