logic.py 19.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.

Z
Zhen Wang 已提交
15
from ..fluid.layer_helper import LayerHelper
16
from ..fluid.data_feeder import check_type, check_variable_and_dtype
Z
Zhen Wang 已提交
17
from ..fluid.layers.layer_function_generator import templatedoc
W
wawltor 已提交
18
from .. import fluid
19
from ..fluid.framework import in_dygraph_mode, Variable
Z
zhulei 已提交
20
from ..framework import VarBase as Tensor
21

22
# TODO: define logic functions of a tensor  
23 24 25 26 27 28 29
from ..fluid.layers import is_empty  # noqa: F401
from ..fluid.layers import logical_and  # noqa: F401
from ..fluid.layers import logical_not  # noqa: F401
from ..fluid.layers import logical_or  # noqa: F401
from ..fluid.layers import logical_xor  # noqa: F401

from paddle.common_ops_import import core
W
wanghuancoder 已提交
30
from paddle import _C_ops
31

32 33
__all__ = []

34

W
wawltor 已提交
35
def equal_all(x, y, name=None):
36 37 38
    """
    This OP returns the truth value of :math:`x == y`. True if two inputs have the same elements, False otherwise.

W
wawltor 已提交
39
    **NOTICE**: The output of this OP has no gradient.
40 41

    Args:
42 43
        x(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
        y(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
W
wawltor 已提交
44 45
        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`.
46 47

    Returns:
W
wawltor 已提交
48
        Tensor: output Tensor, data type is bool, value is [False] or [True].
49 50 51 52 53

    Examples:
        .. code-block:: python

          import paddle
W
wawltor 已提交
54

55 56 57
          x = paddle.to_tensor([1, 2, 3])
          y = paddle.to_tensor([1, 2, 3])
          z = paddle.to_tensor([1, 4, 3])
W
wawltor 已提交
58
          result1 = paddle.equal_all(x, y)
N
Noel 已提交
59
          print(result1) # result1 = [True ]
W
wawltor 已提交
60
          result2 = paddle.equal_all(x, z)
N
Noel 已提交
61
          print(result2) # result2 = [False ]
62
    """
63
    if in_dygraph_mode():
W
wanghuancoder 已提交
64
        return _C_ops.equal_all(x, y)
W
wawltor 已提交
65 66

    helper = LayerHelper("equal_all", **locals())
67 68
    out = helper.create_variable_for_type_inference(dtype='bool')
    helper.append_op(
W
wawltor 已提交
69 70
        type='equal_all', inputs={'X': [x],
                                  'Y': [y]}, outputs={'Out': [out]})
71
    return out
Z
Zhen Wang 已提交
72 73 74


@templatedoc()
75
def allclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None):
Z
Zhen Wang 已提交
76 77 78 79
    """
    ${comment}

    Args:
80 81
        x(Tensor): ${input_comment}.
        y(Tensor): ${other_comment}.
H
huangxu96 已提交
82 83
        rtol(rtoltype, optional): The relative tolerance. Default: :math:`1e-5` .
        atol(atoltype, optional): The absolute tolerance. Default: :math:`1e-8` .
84 85 86
        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 已提交
87 88

    Returns:
89 90 91 92 93 94 95 96
        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.
Z
Zhen Wang 已提交
97 98 99 100 101 102

    Examples:
        .. code-block:: python

          import paddle

103 104
          x = paddle.to_tensor([10000., 1e-07])
          y = paddle.to_tensor([10000.1, 1e-08])
105
          result1 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
Z
Zhen Wang 已提交
106
                                  equal_nan=False, name="ignore_nan")
107 108 109
          np_result1 = result1.numpy()
          # [False]
          result2 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
Z
Zhen Wang 已提交
110
                                      equal_nan=True, name="equal_nan")
111 112 113
          np_result2 = result2.numpy()
          # [False]

114 115
          x = paddle.to_tensor([1.0, float('nan')])
          y = paddle.to_tensor([1.0, float('nan')])
116 117 118 119 120 121 122 123
          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 已提交
124 125
    """

126
    if in_dygraph_mode():
W
wanghuancoder 已提交
127 128 129
        return _C_ops.allclose(x, y, 'rtol',
                               str(rtol), 'atol',
                               str(atol), 'equal_nan', equal_nan)
130 131 132

    check_variable_and_dtype(x, "input", ['float32', 'float64'], 'allclose')
    check_variable_and_dtype(y, "input", ['float32', 'float64'], 'allclose')
Z
Zhen Wang 已提交
133 134 135 136 137 138 139
    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')

140
    inputs = {'Input': x, 'Other': y}
Z
Zhen Wang 已提交
141
    outputs = {'Out': out}
142
    attrs = {'rtol': str(rtol), 'atol': str(atol), 'equal_nan': equal_nan}
Z
Zhen Wang 已提交
143 144 145 146
    helper.append_op(
        type='allclose', inputs=inputs, outputs=outputs, attrs=attrs)

    return out
147 148


W
wawltor 已提交
149 150
@templatedoc()
def equal(x, y, name=None):
151
    """
S
swtkiwi 已提交
152

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

W
wawltor 已提交
155
    **NOTICE**: The output of this OP has no gradient.
156 157

    Args:
158 159
        x(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
        y(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
160 161 162 163
        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 已提交
164
        Tensor: output Tensor, it's shape is the same as the input's Tensor,
165 166 167 168 169
        and the data type is bool. The result of this op is stop_gradient. 

    Examples:
        .. code-block:: python

W
wawltor 已提交
170 171
          import paddle

172 173
          x = paddle.to_tensor([1, 2, 3])
          y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
174
          result1 = paddle.equal(x, y)
N
Noel 已提交
175
          print(result1)  # result1 = [True False False]
176
    """
177
    if in_dygraph_mode():
W
wanghuancoder 已提交
178
        return _C_ops.equal(x, y)
179

180 181 182 183
    check_variable_and_dtype(
        x, "x", ["bool", "float32", "float64", "int32", "int64"], "equal")
    check_variable_and_dtype(
        y, "y", ["bool", "float32", "float64", "int32", "int64"], "equal")
184 185 186 187 188 189 190
    helper = LayerHelper("equal", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')
    out.stop_gradient = True

    helper.append_op(
        type='equal', inputs={'X': [x],
                              'Y': [y]}, outputs={'Out': [out]})
W
wawltor 已提交
191
    return out
192

W
wawltor 已提交
193 194 195 196 197

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

W
wawltor 已提交
199 200 201
    **NOTICE**: The output of this OP has no gradient.

    Args:
202 203
        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 已提交
204 205 206 207 208 209 210
        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:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x`.

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

W
wawltor 已提交
212 213
            import paddle

214 215
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
216
            result1 = paddle.greater_equal(x, y)
N
Noel 已提交
217
            print(result1)  # result1 = [True False True]
W
wawltor 已提交
218
    """
219
    if in_dygraph_mode():
W
wanghuancoder 已提交
220
        return _C_ops.greater_equal(x, y)
221

222 223
    check_variable_and_dtype(x, "x",
                             ["bool", "float32", "float64", "int32", "int64"],
224
                             "greater_equal")
225 226
    check_variable_and_dtype(y, "y",
                             ["bool", "float32", "float64", "int32", "int64"],
227 228 229 230 231 232 233 234 235 236
                             "greater_equal")
    helper = LayerHelper("greater_equal", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')
    out.stop_gradient = True

    helper.append_op(
        type='greater_equal',
        inputs={'X': [x],
                'Y': [y]},
        outputs={'Out': [out]})
W
wawltor 已提交
237 238 239 240 241 242 243
    return out


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

W
wawltor 已提交
245 246 247
    **NOTICE**: The output of this OP has no gradient.

    Args:
248 249
        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 已提交
250 251 252 253 254 255 256
        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:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x` .

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

W
wawltor 已提交
258 259
            import paddle

260 261
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
262
            result1 = paddle.greater_than(x, y)
N
Noel 已提交
263
            print(result1)  # result1 = [False False True]
W
wawltor 已提交
264
    """
265
    if in_dygraph_mode():
W
wanghuancoder 已提交
266
        return _C_ops.greater_than(x, y)
267

268 269
    check_variable_and_dtype(x, "x",
                             ["bool", "float32", "float64", "int32", "int64"],
270
                             "greater_than")
271 272
    check_variable_and_dtype(y, "y",
                             ["bool", "float32", "float64", "int32", "int64"],
273 274 275 276 277 278 279 280 281 282
                             "greater_than")
    helper = LayerHelper("greater_than", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')
    out.stop_gradient = True

    helper.append_op(
        type='greater_than',
        inputs={'X': [x],
                'Y': [y]},
        outputs={'Out': [out]})
W
wawltor 已提交
283 284 285 286 287 288 289
    return out


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

W
wawltor 已提交
291 292 293
    **NOTICE**: The output of this OP has no gradient.

    Args:
294 295
        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 已提交
296 297 298 299 300 301 302 303
        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:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x`.

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

W
wawltor 已提交
305 306
            import paddle

307 308
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
309
            result1 = paddle.less_equal(x, y)
N
Noel 已提交
310
            print(result1)  # result1 = [True True False]
W
wawltor 已提交
311
    """
312
    if in_dygraph_mode():
W
wanghuancoder 已提交
313
        return _C_ops.less_equal(x, y)
314

315 316 317 318
    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")
319 320 321 322 323 324 325
    helper = LayerHelper("less_equal", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')
    out.stop_gradient = True

    helper.append_op(
        type='less_equal', inputs={'X': [x],
                                   'Y': [y]}, outputs={'Out': [out]})
W
wawltor 已提交
326 327 328 329 330 331 332
    return out


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

W
wawltor 已提交
334 335 336
    **NOTICE**: The output of this OP has no gradient.

    Args:
337 338
        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 已提交
339 340 341 342 343 344 345 346
        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:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x`.

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

W
wawltor 已提交
348 349
            import paddle

350 351
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
352
            result1 = paddle.less_than(x, y)
N
Noel 已提交
353
            print(result1)  # result1 = [False True False]
W
wawltor 已提交
354
    """
355
    if in_dygraph_mode():
W
wanghuancoder 已提交
356
        return _C_ops.less_than(x, y)
357

358 359 360 361
    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")
362 363 364 365 366 367 368
    helper = LayerHelper("less_than", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')
    out.stop_gradient = True

    helper.append_op(
        type='less_than', inputs={'X': [x],
                                  'Y': [y]}, outputs={'Out': [out]})
W
wawltor 已提交
369 370 371 372 373 374 375
    return out


@templatedoc()
def not_equal(x, y, name=None):
    """
    This OP returns the truth value of :math:`x != y` elementwise, which is equivalent function to the overloaded operator `!=`.
N
Noel 已提交
376
    
W
wawltor 已提交
377 378 379
    **NOTICE**: The output of this OP has no gradient.

    Args:
380 381
        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 已提交
382 383 384 385 386 387 388 389
        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:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x`.

    Examples:
        .. code-block:: python
390

W
wawltor 已提交
391 392
            import paddle

393 394
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
395
            result1 = paddle.not_equal(x, y)
N
Noel 已提交
396
            print(result1)  # result1 = [False True True]
W
wawltor 已提交
397
    """
398
    if in_dygraph_mode():
W
wanghuancoder 已提交
399
        return _C_ops.not_equal(x, y)
400

401 402 403 404
    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")
405 406 407 408 409 410 411
    helper = LayerHelper("not_equal", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')
    out.stop_gradient = True

    helper.append_op(
        type='not_equal', inputs={'X': [x],
                                  'Y': [y]}, outputs={'Out': [out]})
412
    return out
Z
zhulei 已提交
413 414 415 416 417


def is_tensor(x):
    """

C
chentianyu03 已提交
418
    This function tests whether input object is a paddle.Tensor.
Z
zhulei 已提交
419 420 421 422 423

    Args:
        x (object): Object to test.

    Returns:
C
chentianyu03 已提交
424
        A boolean value. True if 'x' is a paddle.Tensor, otherwise False.
Z
zhulei 已提交
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439

    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
            
    """
C
chentianyu03 已提交
440
    return isinstance(x, Tensor)
441 442 443 444


def _bitwise_op(op_name, x, y, out=None, name=None, binary_op=True):
    if in_dygraph_mode():
W
wanghuancoder 已提交
445
        op = getattr(_C_ops, op_name)
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
        if binary_op:
            return op(x, y)
        else:
            return op(x)

    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:
        helper.append_op(
            type=op_name, inputs={"X": x,
                                  "Y": y}, outputs={"Out": out})
    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}
    
    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_and(x, y)
            print(res)  # [0, 2, 1]
    """
    return _bitwise_op(
        op_name="bitwise_and", x=x, y=y, name=name, out=out, binary_op=True)


@templatedoc()
def bitwise_or(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_or(x, y)
            print(res)  # [-1, -1, -3]
    """
    return _bitwise_op(
        op_name="bitwise_or", x=x, y=y, name=name, out=out, binary_op=True)


@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]
    """
    return _bitwise_op(
        op_name="bitwise_xor", x=x, y=y, name=name, out=out, binary_op=True)


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

    Args:
        x(Tensor):  ${x_comment}
        out(Tensor): ${out_comment}
    
    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]
    """

    return _bitwise_op(
        op_name="bitwise_not", x=x, y=None, name=name, out=out, binary_op=False)