logic.py 35.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#   Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# 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.

15
import paddle
16
from ..fluid.data_feeder import check_type, check_variable_and_dtype
17
from .layer_function_generator import templatedoc
Z
zhiboniu 已提交
18
from ..static import Variable
W
Weilong Wu 已提交
19
# TODO: define logic functions of a tensor
20 21 22
from ..fluid.framework import _in_eager_mode_
if _in_eager_mode_:
    Tensor = paddle.fluid.framework.core.eager.Tensor
W
Weilong Wu 已提交
23 24
else:
    from ..framework import VarBase as Tensor
25 26 27 28

from ..framework import in_dygraph_mode, _non_static_mode
from ..framework import LayerHelper
from ..fluid.framework import _in_legacy_dygraph
29
# TODO: define logic functions of a tensor
30
from paddle import _C_ops, _legacy_C_ops
31
from paddle.tensor.creation import full
32

33 34
__all__ = []

35

36
def _logical_op(op_name, x, y, out=None, name=None, binary_op=True):
37
    if in_dygraph_mode():
38 39 40 41 42
        op = getattr(_C_ops, op_name)
        if binary_op:
            return op(x, y)
        else:
            return op(x)
43 44 45 46 47 48
    elif _in_legacy_dygraph():
        op = getattr(_legacy_C_ops, op_name)
        if binary_op:
            return op(x, y)
        else:
            return op(x)
49 50 51 52
    check_variable_and_dtype(
        x, "x",
        ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
        op_name)
53
    if y is not None:
54 55 56 57
        check_variable_and_dtype(
            y, "y",
            ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
            op_name)
58 59 60 61 62 63 64 65 66 67 68 69 70 71
    if out is not None:
        check_type(out, "out", Variable, op_name)

    helper = LayerHelper(op_name, **locals())

    if binary_op and x.dtype != y.dtype:
        raise ValueError(
            "(InvalidArgument) The DataType of %s Op's Variable must be consistent, but received %s and %s."
            % (op_name, x.dtype, y.dtype))

    if out is None:
        out = helper.create_variable_for_type_inference(dtype=x.dtype)

    if binary_op:
72 73 74 75 76 77
        helper.append_op(type=op_name,
                         inputs={
                             "X": x,
                             "Y": y
                         },
                         outputs={"Out": out})
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


def logical_and(x, y, out=None, name=None):
    r"""

    ``logical_and`` operator computes element-wise logical AND on ``x`` and ``y``, and returns ``out``. ``out`` is N-dim boolean ``Tensor``.
    Each element of ``out`` is calculated by

    .. math::

        out = x \&\& y

    .. note::
        ``paddle.logical_and`` supports broadcasting. If you want know more about broadcasting, please refer to :ref:`user_guide_broadcasting`.

    Args:
        x (Tensor): the input tensor, it's data type should be one of bool, int8, int16, in32, in64, float32, float64.
        y (Tensor): the input tensor, it's data type should be one of bool, int8, int16, in32, in64, float32, float64.
        out(Tensor): The ``Tensor`` that specifies the output of the operator, which can be any ``Tensor`` that has been created in the program. The default value is None, and a new ``Tensor`` will be created to save the output.
        name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        N-D Tensor. A location into which the result is stored. It's dimension equals with ``x``.

    Examples:
        .. code-block:: python

            import paddle

            x = paddle.to_tensor([True])
            y = paddle.to_tensor([True, False, True, False])
            res = paddle.logical_and(x, y)
            print(res) # [True False True False]
    """
    if in_dygraph_mode():
117
        return _C_ops.logical_and(x, y)
118

119 120 121 122 123 124
    return _logical_op(op_name="logical_and",
                       x=x,
                       y=y,
                       name=name,
                       out=out,
                       binary_op=True)
125 126 127 128 129 130 131 132 133 134 135 136 137 138


def logical_or(x, y, out=None, name=None):
    """

    ``logical_or`` operator computes element-wise logical OR on ``x`` and ``y``, and returns ``out``. ``out`` is N-dim boolean ``Tensor``.
    Each element of ``out`` is calculated by

    .. math::

        out = x || y

    .. note::
        ``paddle.logical_or`` supports broadcasting. If you want know more about broadcasting, please refer to :ref:`user_guide_broadcasting`.
139

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    Args:
        x (Tensor): the input tensor, it's data type should be one of bool, int8, int16, in32, in64, float32, float64.
        y (Tensor): the input tensor, it's data type should be one of bool, int8, int16, in32, in64, float32, float64.
        out(Tensor): The ``Variable`` that specifies the output of the operator, which can be any ``Tensor`` that has been created in the program. The default value is None, and a new ``Tensor`` will be created to save the output.
        name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        N-D Tensor. A location into which the result is stored. It's dimension equals with ``x``.

    Examples:
        .. code-block:: python

            import paddle
            import numpy as np

155 156
            x_data = np.array([True, False], dtype=np.bool_).reshape(2, 1)
            y_data = np.array([True, False, True, False], dtype=np.bool_).reshape(2, 2)
157 158 159 160 161 162
            x = paddle.to_tensor(x_data)
            y = paddle.to_tensor(y_data)
            res = paddle.logical_or(x, y)
            print(res) # [[ True  True] [ True False]]
    """
    if in_dygraph_mode():
163
        return _C_ops.logical_or(x, y)
164 165 166 167 168 169
    return _logical_op(op_name="logical_or",
                       x=x,
                       y=y,
                       name=name,
                       out=out,
                       binary_op=True)
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199


def logical_xor(x, y, out=None, name=None):
    r"""

    ``logical_xor`` operator computes element-wise logical XOR on ``x`` and ``y``, and returns ``out``. ``out`` is N-dim boolean ``Tensor``.
    Each element of ``out`` is calculated by

    .. math::

        out = (x || y) \&\& !(x \&\& y)

    .. note::
        ``paddle.logical_xor`` supports broadcasting. If you want know more about broadcasting, please refer to :ref:`user_guide_broadcasting`.

    Args:
        x (Tensor): the input tensor, it's data type should be one of bool, int8, int16, in32, in64, float32, float64.
        y (Tensor): the input tensor, it's data type should be one of bool, int8, int16, in32, in64, float32, float64.
        out(Tensor): The ``Tensor`` that specifies the output of the operator, which can be any ``Tensor`` that has been created in the program. The default value is None, and a new ``Tensor`` will be created to save the output.
        name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        N-D Tensor. A location into which the result is stored. It's dimension equals with ``x``.

    Examples:
        .. code-block:: python

            import paddle
            import numpy as np

200 201
            x_data = np.array([True, False], dtype=np.bool_).reshape([2, 1])
            y_data = np.array([True, False, True, False], dtype=np.bool_).reshape([2, 2])
202 203 204 205 206 207
            x = paddle.to_tensor(x_data)
            y = paddle.to_tensor(y_data)
            res = paddle.logical_xor(x, y)
            print(res) # [[False,  True], [ True, False]]
    """
    if in_dygraph_mode():
208
        return _C_ops.logical_xor(x, y)
209

210 211 212 213 214 215
    return _logical_op(op_name="logical_xor",
                       x=x,
                       y=y,
                       name=name,
                       out=out,
                       binary_op=True)
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246


@templatedoc()
def logical_not(x, out=None, name=None):
    """

    ``logical_not`` operator computes element-wise logical NOT on ``x``, and returns ``out``. ``out`` is N-dim boolean ``Variable``.
    Each element of ``out`` is calculated by

    .. math::

        out = !x

    Args:
        x(Tensor):  Operand of logical_not operator. Must be a Tensor of type bool, int8, int16, in32, in64, float32, or float64.
        out(Tensor): The ``Tensor`` that specifies the output of the operator, which can be any ``Tensor`` that has been created in the program. The default value is None, and a new ``Tensor` will be created to save the output.
        name(str|None): The default value is None. Normally there is no need for users to set this property. For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor: ${out_comment}

    Examples:
        .. code-block:: python

            import paddle

            x = paddle.to_tensor([True, False, True, False])
            res = paddle.logical_not(x)
            print(res) # [False  True False  True]
    """
    if in_dygraph_mode():
247
        return _C_ops.logical_not(x)
248 249 250 251 252 253
    return _logical_op(op_name="logical_not",
                       x=x,
                       y=None,
                       name=name,
                       out=out,
                       binary_op=False)
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287


def is_empty(x, name=None):
    """

    Test whether a Tensor is empty.

    Args:
        x (Tensor): The Tensor to be tested.
        name (str, optional): The default value is ``None`` . Normally users
                            don't have to set this parameter. For more information,
                            please refer to :ref:`api_guide_Name` .

    Returns:
        Tensor: A bool scalar Tensor. True if 'x' is an empty Tensor.

    Examples:
        .. code-block:: python

            import paddle

            input = paddle.rand(shape=[4, 32, 32], dtype='float32')
            res = paddle.is_empty(x=input)
            print("res:", res)
            # ('res:', Tensor: eager_tmp_1
            #    - place: CPUPlace
            #    - shape: [1]
            #    - layout: NCHW
            #    - dtype: bool
            #    - data: [0])

    """
    if in_dygraph_mode():
        return _C_ops.is_empty(x)
288 289
    if _in_legacy_dygraph():
        return _legacy_C_ops.is_empty(x)
290 291 292 293 294 295 296 297

    check_variable_and_dtype(x, 'x', ['float32', 'float64', 'int32', 'int64'],
                             'is_empty')
    check_type(name, "name", (str, type(None)), "is_empty")

    helper = LayerHelper("is_empty", **locals())
    cond = helper.create_variable_for_type_inference(dtype='bool')
    cond.stop_gradient = True
298 299 300
    helper.append_op(type='is_empty',
                     inputs={'X': [x]},
                     outputs={'Out': [cond]})
301 302 303
    return cond


W
wawltor 已提交
304
def equal_all(x, y, name=None):
305
    """
306
    Returns the truth value of :math:`x == y`. True if two inputs have the same elements, False otherwise.
307

308
    Note:
309
        The output has no gradient.
310 311

    Args:
312 313
        x(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
        y(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
W
wawltor 已提交
314 315
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.
316 317

    Returns:
W
wawltor 已提交
318
        Tensor: output Tensor, data type is bool, value is [False] or [True].
319 320 321 322 323

    Examples:
        .. code-block:: python

          import paddle
W
wawltor 已提交
324

325 326 327
          x = paddle.to_tensor([1, 2, 3])
          y = paddle.to_tensor([1, 2, 3])
          z = paddle.to_tensor([1, 4, 3])
W
wawltor 已提交
328
          result1 = paddle.equal_all(x, y)
N
Noel 已提交
329
          print(result1) # result1 = [True ]
W
wawltor 已提交
330
          result2 = paddle.equal_all(x, z)
N
Noel 已提交
331
          print(result2) # result2 = [False ]
332
    """
H
hong 已提交
333
    if in_dygraph_mode():
334
        return _C_ops.equal_all(x, y)
H
hong 已提交
335

Z
zhiboniu 已提交
336
    if paddle.in_dynamic_mode():
337
        return _legacy_C_ops.equal_all(x, y)
W
wawltor 已提交
338 339

    helper = LayerHelper("equal_all", **locals())
340
    out = helper.create_variable_for_type_inference(dtype='bool')
341 342 343 344 345 346
    helper.append_op(type='equal_all',
                     inputs={
                         'X': [x],
                         'Y': [y]
                     },
                     outputs={'Out': [out]})
347
    return out
Z
Zhen Wang 已提交
348 349 350


@templatedoc()
351
def allclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None):
Z
Zhen Wang 已提交
352 353 354 355
    """
    ${comment}

    Args:
356 357
        x(Tensor): ${input_comment}.
        y(Tensor): ${other_comment}.
H
huangxu96 已提交
358 359
        rtol(rtoltype, optional): The relative tolerance. Default: :math:`1e-5` .
        atol(atoltype, optional): The absolute tolerance. Default: :math:`1e-8` .
360 361 362
        equal_nan(equalnantype, optional): ${equal_nan_comment}.
        name (str, optional): Name for the operation. For more information, please
            refer to :ref:`api_guide_Name`. Default: None.
Z
Zhen Wang 已提交
363 364

    Returns:
365 366
        Tensor: ${out_comment}.

Z
Zhen Wang 已提交
367 368 369 370 371
    Examples:
        .. code-block:: python

          import paddle

372 373
          x = paddle.to_tensor([10000., 1e-07])
          y = paddle.to_tensor([10000.1, 1e-08])
374
          result1 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
Z
Zhen Wang 已提交
375
                                  equal_nan=False, name="ignore_nan")
376 377 378
          np_result1 = result1.numpy()
          # [False]
          result2 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
Z
Zhen Wang 已提交
379
                                      equal_nan=True, name="equal_nan")
380 381 382
          np_result2 = result2.numpy()
          # [False]

383 384
          x = paddle.to_tensor([1.0, float('nan')])
          y = paddle.to_tensor([1.0, float('nan')])
385 386 387 388 389 390 391 392
          result1 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
                                  equal_nan=False, name="ignore_nan")
          np_result1 = result1.numpy()
          # [False]
          result2 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
                                      equal_nan=True, name="equal_nan")
          np_result2 = result2.numpy()
          # [True]
Z
Zhen Wang 已提交
393 394
    """

395
    if in_dygraph_mode():
396 397
        # NOTE(dev): Pass tol as Tensor to fix precision loss problem, because
        # C++ backend will cast it into float32 if passing float from python.
398 399
        as_tensor = lambda x: paddle.to_tensor(
            [x], dtype='float64', place='cpu')
400 401
        return _C_ops.allclose(x, y, as_tensor(rtol), as_tensor(atol),
                               equal_nan)
402
    if _in_legacy_dygraph():
403 404
        return _legacy_C_ops.allclose(x, y, 'rtol', str(rtol), 'atol',
                                      str(atol), 'equal_nan', equal_nan)
405 406
    check_variable_and_dtype(x, "input", ['float32', 'float64'], 'allclose')
    check_variable_and_dtype(y, "input", ['float32', 'float64'], 'allclose')
Z
Zhen Wang 已提交
407 408 409 410 411 412 413
    check_type(rtol, 'rtol', float, 'allclose')
    check_type(atol, 'atol', float, 'allclose')
    check_type(equal_nan, 'equal_nan', bool, 'allclose')

    helper = LayerHelper("allclose", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')

414
    inputs = {'Input': x, 'Other': y}
Z
Zhen Wang 已提交
415
    outputs = {'Out': out}
416
    attrs = {'rtol': str(rtol), 'atol': str(atol), 'equal_nan': equal_nan}
417 418 419 420
    helper.append_op(type='allclose',
                     inputs=inputs,
                     outputs=outputs,
                     attrs=attrs)
Z
Zhen Wang 已提交
421 422

    return out
423 424


W
wawltor 已提交
425 426
@templatedoc()
def equal(x, y, name=None):
427
    """
S
swtkiwi 已提交
428

429
    This layer returns the truth value of :math:`x == y` elementwise.
N
Noel 已提交
430

431
    Note:
432
        The output has no gradient.
433 434

    Args:
435 436
        x(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
        y(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
437 438 439 440
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.

    Returns:
W
wawltor 已提交
441
        Tensor: output Tensor, it's shape is the same as the input's Tensor,
442
        and the data type is bool. The result of this op is stop_gradient.
443 444 445 446

    Examples:
        .. code-block:: python

W
wawltor 已提交
447 448
          import paddle

449 450
          x = paddle.to_tensor([1, 2, 3])
          y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
451
          result1 = paddle.equal(x, y)
N
Noel 已提交
452
          print(result1)  # result1 = [True False False]
453
    """
454 455
    if not isinstance(y, (int, bool, float, Variable)):
        raise TypeError(
456 457
            "Type of input args must be float, bool, int or Tensor, but received type {}"
            .format(type(y)))
458 459 460
    if not isinstance(y, Variable):
        y = full(shape=[1], dtype=x.dtype, fill_value=y)

J
Jiabin Yang 已提交
461
    if in_dygraph_mode():
462
        default_axis = -1
463
        return _C_ops.equal(x, y, default_axis)
J
Jiabin Yang 已提交
464 465
    else:
        if _in_legacy_dygraph():
466
            return _legacy_C_ops.equal(x, y)
J
Jiabin Yang 已提交
467 468 469 470 471 472 473 474 475 476 477
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "equal")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "equal")
            helper = LayerHelper("equal", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

478 479 480 481 482 483
            helper.append_op(type='equal',
                             inputs={
                                 'X': [x],
                                 'Y': [y]
                             },
                             outputs={'Out': [out]})
J
Jiabin Yang 已提交
484
            return out
485

W
wawltor 已提交
486 487 488 489

@templatedoc()
def greater_equal(x, y, name=None):
    """
490
    Returns the truth value of :math:`x >= y` elementwise, which is equivalent function to the overloaded operator `>=`.
N
Noel 已提交
491

492
    Note:
493
        The output has no gradient.
W
wawltor 已提交
494 495

    Args:
496 497
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
498 499 500
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.
    Returns:
501
        Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
W
wawltor 已提交
502 503 504

    Examples:
        .. code-block:: python
N
Noel 已提交
505

W
wawltor 已提交
506 507
            import paddle

508 509
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
510
            result1 = paddle.greater_equal(x, y)
N
Noel 已提交
511
            print(result1)  # result1 = [True False True]
W
wawltor 已提交
512
    """
J
Jiabin Yang 已提交
513
    if in_dygraph_mode():
514
        default_axis = -1
515
        return _C_ops.greater_equal(x, y, default_axis)
J
Jiabin Yang 已提交
516 517
    else:
        if _in_legacy_dygraph():
518
            return _legacy_C_ops.greater_equal(x, y)
J
Jiabin Yang 已提交
519 520 521 522 523 524 525 526 527 528 529
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "greater_equal")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "greater_equal")
            helper = LayerHelper("greater_equal", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

530 531 532 533 534 535
            helper.append_op(type='greater_equal',
                             inputs={
                                 'X': [x],
                                 'Y': [y]
                             },
                             outputs={'Out': [out]})
J
Jiabin Yang 已提交
536
            return out
W
wawltor 已提交
537 538 539 540 541


@templatedoc()
def greater_than(x, y, name=None):
    """
542
    Returns the truth value of :math:`x > y` elementwise, which is equivalent function to the overloaded operator `>`.
N
Noel 已提交
543

544
    Note:
545
        The output has no gradient.
W
wawltor 已提交
546 547

    Args:
548 549
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
550 551 552
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.
    Returns:
553
        Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
W
wawltor 已提交
554 555 556

    Examples:
        .. code-block:: python
N
Noel 已提交
557

W
wawltor 已提交
558 559
            import paddle

560 561
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
562
            result1 = paddle.greater_than(x, y)
N
Noel 已提交
563
            print(result1)  # result1 = [False False True]
W
wawltor 已提交
564
    """
J
Jiabin Yang 已提交
565
    if in_dygraph_mode():
566
        return _C_ops.greater_than(x, y, -1)
J
Jiabin Yang 已提交
567 568
    else:
        if _in_legacy_dygraph():
569
            return _legacy_C_ops.greater_than(x, y)
J
Jiabin Yang 已提交
570 571 572 573 574 575 576 577 578 579 580
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "greater_than")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "greater_than")
            helper = LayerHelper("greater_than", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

581 582 583 584 585 586
            helper.append_op(type='greater_than',
                             inputs={
                                 'X': [x],
                                 'Y': [y]
                             },
                             outputs={'Out': [out]})
J
Jiabin Yang 已提交
587
            return out
W
wawltor 已提交
588 589 590 591 592


@templatedoc()
def less_equal(x, y, name=None):
    """
593
    Returns the truth value of :math:`x <= y` elementwise, which is equivalent function to the overloaded operator `<=`.
N
Noel 已提交
594

595
    Note:
596
        The output has no gradient.
W
wawltor 已提交
597 598

    Args:
599 600
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
601 602 603 604
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.

    Returns:
605
        Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
W
wawltor 已提交
606 607 608

    Examples:
        .. code-block:: python
N
Noel 已提交
609

W
wawltor 已提交
610 611
            import paddle

612 613
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
614
            result1 = paddle.less_equal(x, y)
N
Noel 已提交
615
            print(result1)  # result1 = [True True False]
W
wawltor 已提交
616
    """
J
Jiabin Yang 已提交
617
    if in_dygraph_mode():
0
0x45f 已提交
618
        axis = -1
619
        return _C_ops.less_equal(x, y, axis)
J
Jiabin Yang 已提交
620 621
    else:
        if _in_legacy_dygraph():
622
            return _legacy_C_ops.less_equal(x, y)
J
Jiabin Yang 已提交
623 624 625 626 627 628 629 630 631 632 633
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "less_equal")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "less_equal")
            helper = LayerHelper("less_equal", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

634 635 636 637 638 639
            helper.append_op(type='less_equal',
                             inputs={
                                 'X': [x],
                                 'Y': [y]
                             },
                             outputs={'Out': [out]})
J
Jiabin Yang 已提交
640
            return out
W
wawltor 已提交
641 642 643 644 645


@templatedoc()
def less_than(x, y, name=None):
    """
646
    Returns the truth value of :math:`x < y` elementwise, which is equivalent function to the overloaded operator `<`.
N
Noel 已提交
647

648
    Note:
649
        The output has no gradient.
W
wawltor 已提交
650 651

    Args:
652 653
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
654 655 656 657
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.

    Returns:
658
        Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
W
wawltor 已提交
659 660 661

    Examples:
        .. code-block:: python
N
Noel 已提交
662

W
wawltor 已提交
663 664
            import paddle

665 666
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
667
            result1 = paddle.less_than(x, y)
N
Noel 已提交
668
            print(result1)  # result1 = [False True False]
W
wawltor 已提交
669
    """
J
Jiabin Yang 已提交
670
    if in_dygraph_mode():
671
        default_axis = -1
672
        return _C_ops.less_than(x, y, default_axis)
J
Jiabin Yang 已提交
673 674
    else:
        if _in_legacy_dygraph():
675
            return _legacy_C_ops.less_than(x, y)
J
Jiabin Yang 已提交
676 677 678 679 680 681 682 683 684 685 686
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "less_than")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "less_than")
            helper = LayerHelper("less_than", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

687 688 689 690 691 692
            helper.append_op(type='less_than',
                             inputs={
                                 'X': [x],
                                 'Y': [y]
                             },
                             outputs={'Out': [out]})
J
Jiabin Yang 已提交
693
            return out
W
wawltor 已提交
694 695 696 697 698


@templatedoc()
def not_equal(x, y, name=None):
    """
699
    Returns the truth value of :math:`x != y` elementwise, which is equivalent function to the overloaded operator `!=`.
700 701

    Note:
702
        The output has no gradient.
W
wawltor 已提交
703 704

    Args:
705 706
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
707 708 709 710
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.

    Returns:
711
        Tensor: The output shape is same as input :attr:`x`. The output data type is bool.
W
wawltor 已提交
712 713 714

    Examples:
        .. code-block:: python
715

W
wawltor 已提交
716 717
            import paddle

718 719
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
720
            result1 = paddle.not_equal(x, y)
N
Noel 已提交
721
            print(result1)  # result1 = [False True True]
W
wawltor 已提交
722
    """
J
Jiabin Yang 已提交
723
    if in_dygraph_mode():
0
0x45f 已提交
724
        axis = -1
725
        return _C_ops.not_equal(x, y, axis)
J
Jiabin Yang 已提交
726 727
    else:
        if _in_legacy_dygraph():
728
            return _legacy_C_ops.not_equal(x, y)
J
Jiabin Yang 已提交
729 730 731 732 733 734 735 736 737 738 739
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "not_equal")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "not_equal")
            helper = LayerHelper("not_equal", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

740 741 742 743 744 745
            helper.append_op(type='not_equal',
                             inputs={
                                 'X': [x],
                                 'Y': [y]
                             },
                             outputs={'Out': [out]})
J
Jiabin Yang 已提交
746
            return out
Z
zhulei 已提交
747 748 749 750 751


def is_tensor(x):
    """

C
Chen Long 已提交
752
    Tests whether input object is a paddle.Tensor.
Z
zhulei 已提交
753 754 755 756 757

    Args:
        x (object): Object to test.

    Returns:
C
Chen Long 已提交
758
        A boolean value. True if ``x`` is a paddle.Tensor, otherwise False.
Z
zhulei 已提交
759 760 761 762 763 764 765 766 767 768 769 770 771

    Examples:
        .. code-block:: python

            import paddle

            input1 = paddle.rand(shape=[2, 3, 5], dtype='float32')
            check = paddle.is_tensor(input1)
            print(check)  #True

            input3 = [1, 4]
            check = paddle.is_tensor(input3)
            print(check)  #False
772

Z
zhulei 已提交
773
    """
H
hong 已提交
774
    return isinstance(x, (Tensor, paddle.fluid.core.eager.Tensor))
775 776 777


def _bitwise_op(op_name, x, y, out=None, name=None, binary_op=True):
778
    if in_dygraph_mode():
W
wanghuancoder 已提交
779
        op = getattr(_C_ops, op_name)
780 781 782 783
        if binary_op:
            return op(x, y)
        else:
            return op(x)
784 785 786 787 788 789
    elif _in_legacy_dygraph():
        op = getattr(_legacy_C_ops, op_name)
        if binary_op:
            return op(x, y)
        else:
            return op(x)
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807

    check_variable_and_dtype(
        x, "x", ["bool", "uint8", "int8", "int16", "int32", "int64"], op_name)
    if y is not None:
        check_variable_and_dtype(
            y, "y", ["bool", "uint8", "int8", "int16", "int32", "int64"],
            op_name)
    if out is not None:
        check_type(out, "out", Variable, op_name)

    helper = LayerHelper(op_name, **locals())
    if binary_op:
        assert x.dtype == y.dtype

    if out is None:
        out = helper.create_variable_for_type_inference(dtype=x.dtype)

    if binary_op:
808 809 810 811 812 813
        helper.append_op(type=op_name,
                         inputs={
                             "X": x,
                             "Y": y
                         },
                         outputs={"Out": out})
814 815 816 817 818 819 820 821 822 823
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


@templatedoc()
def bitwise_and(x, y, out=None, name=None):
    """
    ${comment}
824

825 826 827 828 829 830 831
    Args:
        x (Tensor): ${x_comment}
        y (Tensor): ${y_comment}
        out(Tensor): ${out_comment}

    Returns:
        Tensor: ${out_comment}
832

833 834 835 836 837 838 839 840 841
    Examples:
        .. code-block:: python

            import paddle
            x = paddle.to_tensor([-5, -1, 1])
            y = paddle.to_tensor([4,  2, -3])
            res = paddle.bitwise_and(x, y)
            print(res)  # [0, 2, 1]
    """
0
0x45f 已提交
842
    if in_dygraph_mode() and out is None:
843
        return _C_ops.bitwise_and(x, y)
844 845 846 847 848 849
    return _bitwise_op(op_name="bitwise_and",
                       x=x,
                       y=y,
                       name=name,
                       out=out,
                       binary_op=True)
850 851 852 853 854 855


@templatedoc()
def bitwise_or(x, y, out=None, name=None):
    """
    ${comment}
856

857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873
    Args:
        x (Tensor): ${x_comment}
        y (Tensor): ${y_comment}
        out(Tensor): ${out_comment}

    Returns:
        Tensor: ${out_comment}

    Examples:
        .. code-block:: python

            import paddle
            x = paddle.to_tensor([-5, -1, 1])
            y = paddle.to_tensor([4,  2, -3])
            res = paddle.bitwise_or(x, y)
            print(res)  # [-1, -1, -3]
    """
0
0x45f 已提交
874
    if in_dygraph_mode() and out is None:
875
        return _C_ops.bitwise_or(x, y)
H
hong 已提交
876

877 878 879 880 881 882
    return _bitwise_op(op_name="bitwise_or",
                       x=x,
                       y=y,
                       name=name,
                       out=out,
                       binary_op=True)
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906


@templatedoc()
def bitwise_xor(x, y, out=None, name=None):
    """
    ${comment}

    Args:
        x (Tensor): ${x_comment}
        y (Tensor): ${y_comment}
        out(Tensor): ${out_comment}

    Returns:
        Tensor: ${out_comment}

    Examples:
        .. code-block:: python

            import paddle
            x = paddle.to_tensor([-5, -1, 1])
            y = paddle.to_tensor([4,  2, -3])
            res = paddle.bitwise_xor(x, y)
            print(res) # [-1, -3, -4]
    """
0
0x45f 已提交
907
    if in_dygraph_mode() and out is None:
908
        return _C_ops.bitwise_xor(x, y)
909 910 911 912 913 914
    return _bitwise_op(op_name="bitwise_xor",
                       x=x,
                       y=y,
                       name=name,
                       out=out,
                       binary_op=True)
915 916 917 918 919 920 921 922 923 924


@templatedoc()
def bitwise_not(x, out=None, name=None):
    """
    ${comment}

    Args:
        x(Tensor):  ${x_comment}
        out(Tensor): ${out_comment}
925

926 927 928 929 930 931 932 933 934 935 936
    Returns:
        Tensor: ${out_comment}

    Examples:
        .. code-block:: python

            import paddle
            x = paddle.to_tensor([-5, -1, 1])
            res = paddle.bitwise_not(x)
            print(res) # [4, 0, -2]
    """
0
0x45f 已提交
937
    if in_dygraph_mode() and out is None:
938
        return _C_ops.bitwise_not(x)
939

940 941 942 943 944 945
    return _bitwise_op(op_name="bitwise_not",
                       x=x,
                       y=None,
                       name=name,
                       out=out,
                       binary_op=False)
A
andyjpaddle 已提交
946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999


@templatedoc()
def isclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None):
    """
    ${comment}

    Args:
        x(Tensor): ${input_comment}.
        y(Tensor): ${other_comment}.
        rtol(rtoltype, optional): The relative tolerance. Default: :math:`1e-5` .
        atol(atoltype, optional): The absolute tolerance. Default: :math:`1e-8` .
        equal_nan(equalnantype, optional): ${equal_nan_comment}.
        name (str, optional): Name for the operation. For more information, please
            refer to :ref:`api_guide_Name`. Default: None.

    Returns:
        Tensor: ${out_comment}.

    Raises:
        TypeError: The data type of ``x`` must be one of float32, float64.
        TypeError: The data type of ``y`` must be one of float32, float64.
        TypeError: The type of ``rtol`` must be float.
        TypeError: The type of ``atol`` must be float.
        TypeError: The type of ``equal_nan`` must be bool.

    Examples:
        .. code-block:: python

          import paddle

          x = paddle.to_tensor([10000., 1e-07])
          y = paddle.to_tensor([10000.1, 1e-08])
          result1 = paddle.isclose(x, y, rtol=1e-05, atol=1e-08,
                                  equal_nan=False, name="ignore_nan")
          np_result1 = result1.numpy()
          # [True, False]
          result2 = paddle.isclose(x, y, rtol=1e-05, atol=1e-08,
                                      equal_nan=True, name="equal_nan")
          np_result2 = result2.numpy()
          # [True, False]

          x = paddle.to_tensor([1.0, float('nan')])
          y = paddle.to_tensor([1.0, float('nan')])
          result1 = paddle.isclose(x, y, rtol=1e-05, atol=1e-08,
                                  equal_nan=False, name="ignore_nan")
          np_result1 = result1.numpy()
          # [True, False]
          result2 = paddle.isclose(x, y, rtol=1e-05, atol=1e-08,
                                      equal_nan=True, name="equal_nan")
          np_result2 = result2.numpy()
          # [True, True]
    """

1000
    if in_dygraph_mode():
1001 1002
        # NOTE(dev): Pass tol as Tensor to fix precision loss problem, because
        # C++ backend will cast it into float32 if passing float from python.
1003 1004
        as_tensor = lambda x: paddle.to_tensor(
            [x], dtype='float64', place='cpu')
1005
        return _C_ops.isclose(x, y, as_tensor(rtol), as_tensor(atol), equal_nan)
1006
    if _in_legacy_dygraph():
1007 1008
        return _legacy_C_ops.isclose(x, y, 'rtol', str(rtol), 'atol', str(atol),
                                     'equal_nan', equal_nan)
A
andyjpaddle 已提交
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021

    check_variable_and_dtype(x, "input", ['float32', 'float64'], 'isclose')
    check_variable_and_dtype(y, "input", ['float32', 'float64'], 'isclose')
    check_type(rtol, 'rtol', float, 'isclose')
    check_type(atol, 'atol', float, 'isclose')
    check_type(equal_nan, 'equal_nan', bool, 'isclose')

    helper = LayerHelper("isclose", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')

    inputs = {'Input': x, 'Other': y}
    outputs = {'Out': out}
    attrs = {'rtol': str(rtol), 'atol': str(atol), 'equal_nan': equal_nan}
1022 1023 1024 1025
    helper.append_op(type='isclose',
                     inputs=inputs,
                     outputs=outputs,
                     attrs=attrs)
A
andyjpaddle 已提交
1026
    return out