random.py 41.6 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
# TODO: define random functions
S
silingtong123 已提交
16

Z
zhiboniu 已提交
17 18
from ..framework import core
from ..framework import convert_np_dtype_to_dtype_, dygraph_only
19
from ..framework import LayerHelper
20 21 22 23 24 25
from ..fluid.data_feeder import (
    check_variable_and_dtype,
    check_type,
    check_dtype,
    check_shape,
)
26 27
from ..fluid.layers import utils
import paddle
28
from paddle import _C_ops, _legacy_C_ops
Z
zhiboniu 已提交
29
from paddle.static import Variable
30 31 32 33 34
from paddle.fluid.framework import (
    in_dygraph_mode,
    _in_legacy_dygraph,
    _current_expected_place,
)
S
silingtong123 已提交
35

36 37
__all__ = []

S
silingtong123 已提交
38

L
Leo Chen 已提交
39
def bernoulli(x, name=None):
40
    r"""
L
Leo Chen 已提交
41

42
    For each element :math:`x_i` in input ``x``, take a sample from the Bernoulli distribution, also called two-point distribution, with success probability :math:`x_i`. The Bernoulli distribution with success probability :math:`x_i` is a discrete probability distribution with probability mass function
L
Leo Chen 已提交
43

44
    .. math::
45 46
        p(y)=\begin{cases}
            x_i,&y=1\\
47 48
            1-x_i,&y=0
        \end{cases}.
L
Leo Chen 已提交
49 50

    Args:
51 52 53
        x (Tensor): The input Tensor, it's data type should be float32, float64.
        name (str, optional): For details, please refer to :ref:`api_guide_Name`. Generally, no setting is required. Default: None.

54
    Returns:
55
        Tensor: A Tensor filled samples from Bernoulli distribution, whose shape and dtype are same as ``x``.
L
Leo Chen 已提交
56 57 58 59

    Examples:
        .. code-block:: python

60
            import paddle
L
Leo Chen 已提交
61

L
Leo Chen 已提交
62
            paddle.set_device('cpu')  # on CPU device
63
            paddle.seed(100)
L
Leo Chen 已提交
64

65
            x = paddle.rand([2,3])
L
Leo Chen 已提交
66 67 68
            print(x)
            # [[0.55355281, 0.20714243, 0.01162981],
            #  [0.51577556, 0.36369765, 0.26091650]]
L
Leo Chen 已提交
69

70
            out = paddle.bernoulli(x)
L
Leo Chen 已提交
71 72 73
            print(out)
            # [[1., 0., 1.],
            #  [0., 1., 0.]]
L
Leo Chen 已提交
74 75 76

    """

H
hong 已提交
77
    if in_dygraph_mode():
78
        return _C_ops.bernoulli(x)
H
hong 已提交
79 80

    if _in_legacy_dygraph():
81
        return _legacy_C_ops.bernoulli(x)
L
Leo Chen 已提交
82 83 84 85 86

    check_variable_and_dtype(x, "x", ["float32", "float64"], "bernoulli")

    helper = LayerHelper("randint", **locals())
    out = helper.create_variable_for_type_inference(
87 88 89 90 91
        dtype=x.dtype
    )  # maybe set out to int32 ?
    helper.append_op(
        type='bernoulli', inputs={"X": x}, outputs={'Out': out}, attrs={}
    )
92
    out.stop_gradient = True
L
Leo Chen 已提交
93 94 95
    return out


96
def poisson(x, name=None):
97
    r"""
98
    Returns a tensor filled with random number from a Poisson Distribution.
99 100 101

    .. math::

102
        out_i \sim Poisson (lambda = x_i)
103 104

    Args:
105
        x(Tensor):  A tensor with rate parameter of poisson Distribution. The data type
106 107 108 109
            should be float32, float64.
        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`.
110
    Returns:
111 112 113 114 115 116
        Tensor: A Tensor filled with random number with the same shape and dtype as ``x``.

    Examples:
        .. code-block:: python

            import paddle
117
            paddle.set_device('cpu')
118
            paddle.seed(100)
119 120 121

            x = paddle.uniform([2,3], min=1.0, max=5.0)
            out = paddle.poisson(x)
122 123
            #[[2., 5., 0.],
            # [5., 1., 3.]]
124 125

    """
H
hong 已提交
126
    if in_dygraph_mode():
127
        return _C_ops.poisson(x)
128

Z
zhiboniu 已提交
129
    if paddle.in_dynamic_mode():
130
        return _legacy_C_ops.poisson(x)
131 132 133 134 135

    check_variable_and_dtype(x, "x", ["float32", "float64"], "poisson")

    helper = LayerHelper("poisson", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
136 137 138
    helper.append_op(
        type='poisson', inputs={'X': x}, outputs={'Out': out}, attrs={}
    )
139 140 141
    return out


P
pangyoki 已提交
142 143
def multinomial(x, num_samples=1, replacement=False, name=None):
    """
144
    Returns a Tensor filled with random values sampled from a Multinomical
P
pangyoki 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
    distribution. The input ``x`` is a tensor with probabilities for generating the
    random number. Each element in ``x`` should be larger or equal to 0, but not all
    0. ``replacement`` indicates whether it is a replaceable sample. If ``replacement``
    is True, a category can be sampled more than once.

    Args:
        x(Tensor):  A tensor with probabilities for generating the random number. The data type
            should be float32, float64.
        num_samples(int, optional): Number of samples, default is 1.
        replacement(bool, optional): Whether it is a replaceable sample, default is False.
        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: A Tensor filled with sampled category index after ``num_samples`` times samples.

    Examples:
        .. code-block:: python

164 165
            import paddle

C
cnn 已提交
166
            paddle.seed(100) # on CPU device
167
            x = paddle.rand([2,4])
168
            print(x)
169 170 171
            # [[0.5535528  0.20714243 0.01162981 0.51577556]
            # [0.36369765 0.2609165  0.18905126 0.5621971 ]]

C
cnn 已提交
172
            paddle.seed(200) # on CPU device
173
            out1 = paddle.multinomial(x, num_samples=5, replacement=True)
174
            print(out1)
175 176 177 178 179 180 181
            # [[3 3 0 0 0]
            # [3 3 3 1 0]]

            # out2 = paddle.multinomial(x, num_samples=5)
            # InvalidArgumentError: When replacement is False, number of samples
            #  should be less than non-zero categories

C
cnn 已提交
182
            paddle.seed(300) # on CPU device
183
            out3 = paddle.multinomial(x, num_samples=3)
184
            print(out3)
185 186
            # [[3 0 1]
            # [3 1 0]]
P
pangyoki 已提交
187 188 189

    """

190
    assert (
191
        not core.is_compiled_with_rocm()
192
    ), "multinomial op is not supported on ROCM yet."
193

H
hong 已提交
194
    if in_dygraph_mode():
195
        return _C_ops.multinomial(x, num_samples, replacement)
H
hong 已提交
196 197

    if _in_legacy_dygraph():
198 199 200
        return _legacy_C_ops.multinomial(
            x, 'num_samples', num_samples, 'replacement', replacement
        )
P
pangyoki 已提交
201 202 203 204 205

    check_variable_and_dtype(x, "x", ["float32", "float64"], "multinomial")

    helper = LayerHelper("multinomial", **locals())
    out = helper.create_variable_for_type_inference(
206 207 208 209 210 211 212 213
        dtype=convert_np_dtype_to_dtype_('int64')
    )
    helper.append_op(
        type='multinomial',
        inputs={"X": x},
        outputs={'Out': out},
        attrs={'num_samples': num_samples, 'replacement': replacement},
    )
214
    out.stop_gradient = True
P
pangyoki 已提交
215 216 217
    return out


218
def gaussian(shape, mean=0.0, std=1.0, dtype=None, name=None):
219
    """
220
    Returns a Tensor filled with random values sampled from a Gaussian
221 222 223
    distribution, with ``shape`` and ``dtype``.

    Args:
224
        shape (list|tuple|Tensor): The shape of the output Tensor. If ``shape``
225 226 227 228
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64).
229 230
        mean (float|int, optional): Mean of the output tensor, default is 0.0.
        std (float|int, optional): Standard deviation of the output tensor, default
231
            is 1.0.
232 233
        seed (int, optional): Random seed of generator.
        dtype (str|np.dtype, optional): The data type of the output Tensor.
234 235 236
            Supported data types: float32, float64.
            Default is None, use global default dtype (see ``get_default_dtype``
            for details).
237
        name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.
238 239 240

    Returns:
        Tensor: A Tensor filled with random values sampled from a Gaussian
241
        distribution, with ``shape`` and ``dtype``.
242
    """
243 244 245
    op_type_for_check = 'gaussian/standard_normal/randn/normal'
    seed = 0

246 247 248 249
    if dtype is None:
        dtype = paddle.framework.get_default_dtype()
        if dtype not in ['float32', 'float64']:
            raise TypeError(
250 251 252 253
                "{} only supports [float32, float64], but the default dtype is {}".format(
                    op_type_for_check, dtype
                )
            )
254 255 256
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)

257 258 259
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
260
        return _C_ops.gaussian(
261 262
            shape, float(mean), float(std), seed, dtype, place
        )
263 264

    if _in_legacy_dygraph():
265
        shape = utils.convert_shape_to_list(shape)
266 267 268 269 270 271 272 273 274 275 276 277
        return _legacy_C_ops.gaussian_random(
            'shape',
            shape,
            'mean',
            float(mean),
            'std',
            float(std),
            'seed',
            seed,
            'dtype',
            dtype,
        )
278

279
    check_shape(shape, op_type_for_check)
280 281 282 283 284 285 286 287
    check_dtype(dtype, 'dtype', ['float32', 'float64'], op_type_for_check)

    inputs = {}
    attrs = {
        'mean': mean,
        'std': std,
        'seed': seed,
        'dtype': dtype,
288
        'use_mkldnn': False,
289
    }
290 291 292
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type=op_type_for_check
    )
293

294
    helper = LayerHelper('gaussian', **locals())
295
    out = helper.create_variable_for_type_inference(dtype)
296 297 298
    helper.append_op(
        type='gaussian_random', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
299 300 301 302 303 304
    out.stop_gradient = True
    return out


def standard_normal(shape, dtype=None, name=None):
    """
305
    Returns a Tensor filled with random values sampled from a standard
306 307 308 309
    normal distribution with mean 0 and standard deviation 1, with ``shape``
    and ``dtype``.

    Args:
310
        shape (list|tuple|Tensor): The shape of the output Tensor. If ``shape``
311 312 313 314
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64).
315
        dtype (str|np.dtype, optional): The data type of the output Tensor.
316 317 318
            Supported data types: float32, float64.
            Default is None, use global default dtype (see ``get_default_dtype``
            for details).
319 320 321 322 323 324 325 326 327 328 329 330 331 332
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor: A Tensor filled with random values sampled from a standard
        normal distribution with mean 0 and standard deviation 1, with
        ``shape`` and ``dtype``.

    Examples:
        .. code-block:: python

            import paddle

            # example 1: attr shape is a list which doesn't contain Tensor.
333
            out1 = paddle.standard_normal(shape=[2, 3])
334 335 336 337
            # [[-2.923464  ,  0.11934398, -0.51249987],  # random
            #  [ 0.39632758,  0.08177969,  0.2692008 ]]  # random

            # example 2: attr shape is a list which contains Tensor.
Z
zhupengyang 已提交
338 339
            dim1 = paddle.to_tensor([2], 'int64')
            dim2 = paddle.to_tensor([3], 'int32')
340
            out2 = paddle.standard_normal(shape=[dim1, dim2, 2])
341 342 343 344 345 346 347 348
            # [[[-2.8852394 , -0.25898588],  # random
            #   [-0.47420555,  0.17683524],  # random
            #   [-0.7989969 ,  0.00754541]],  # random
            #  [[ 0.85201347,  0.32320443],  # random
            #   [ 1.1399018 ,  0.48336947],  # random
            #   [ 0.8086993 ,  0.6868893 ]]]  # random

            # example 3: attr shape is a Tensor, the data type must be int64 or int32.
349
            shape_tensor = paddle.to_tensor([2, 3])
Z
zhupengyang 已提交
350
            out3 = paddle.standard_normal(shape_tensor)
351 352 353 354
            # [[-2.878077 ,  0.17099959,  0.05111201]  # random
            #  [-0.3761474, -1.044801  ,  1.1870178 ]]  # random

    """
355
    return gaussian(shape=shape, mean=0.0, std=1.0, dtype=dtype, name=name)
356 357


Z
zhupengyang 已提交
358 359
def randn(shape, dtype=None, name=None):
    """
360
    Returns a Tensor filled with random values sampled from a standard
Z
zhupengyang 已提交
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
    normal distribution with mean 0 and standard deviation 1, with ``shape``
    and ``dtype``.

    Args:
        shape (list|tuple|Tensor): The shape of the output Tensor. If ``shape``
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64).
        dtype (str|np.dtype, optional): The data type of the output Tensor.
            Supported data types: float32, float64.
            Default is None, use global default dtype (see ``get_default_dtype``
            for details).
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor: A Tensor filled with random values sampled from a standard
        normal distribution with mean 0 and standard deviation 1, with
        ``shape`` and ``dtype``.

    Examples:
        .. code-block:: python

            import paddle

            # example 1: attr shape is a list which doesn't contain Tensor.
            out1 = paddle.randn(shape=[2, 3])
            # [[-2.923464  ,  0.11934398, -0.51249987],  # random
            #  [ 0.39632758,  0.08177969,  0.2692008 ]]  # random

            # example 2: attr shape is a list which contains Tensor.
            dim1 = paddle.to_tensor([2], 'int64')
            dim2 = paddle.to_tensor([3], 'int32')
            out2 = paddle.randn(shape=[dim1, dim2, 2])
            # [[[-2.8852394 , -0.25898588],  # random
            #   [-0.47420555,  0.17683524],  # random
            #   [-0.7989969 ,  0.00754541]],  # random
            #  [[ 0.85201347,  0.32320443],  # random
            #   [ 1.1399018 ,  0.48336947],  # random
            #   [ 0.8086993 ,  0.6868893 ]]]  # random

            # example 3: attr shape is a Tensor, the data type must be int64 or int32.
            shape_tensor = paddle.to_tensor([2, 3])
            out3 = paddle.randn(shape_tensor)
            # [[-2.878077 ,  0.17099959,  0.05111201]  # random
            #  [-0.3761474, -1.044801  ,  1.1870178 ]]  # random
    """
    return standard_normal(shape, dtype, name)
410 411 412 413


def normal(mean=0.0, std=1.0, shape=None, name=None):
    """
414
    Returns a Tensor filled with random values sampled from a normal
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
    distribution with ``mean`` and ``std`` (standard deviation) .

    If ``mean`` is a Tensor, the output Tensor has the same shape and data type as ``mean``.
    If ``mean`` is not a Tensor and ``std`` is a Tensor, the output Tensor has the same shape and data type as ``std``.
    If ``mean`` and ``std`` are not a Tensor, the output Tensor has the same shape as ``shape``, with data type float32.

    If ``mean`` and ``std`` are Tensor, the num of elements of ``mean`` and ``std`` should be the same.

    Args:
        mean (float|Tensor, optional): The mean of the output Tensor's normal distribution.
            If ``mean`` is float, all elements of the output Tensor shared the same mean.
            If ``mean`` is a Tensor(data type supports float32, float64), it has per-element means.
            Default is 0.0
        std (float|Tensor, optional): The  standard deviation of the output Tensor's normal distribution.
            If ``std`` is float, all elements of the output Tensor shared the same standard deviation.
            If ``std`` is a Tensor(data type supports float32, float64), it has per-element standard deviations.
            Defaule is 1.0
        shape (list|tuple|Tensor, optional): The shape of the output Tensor. If ``shape``
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64). If ``mean`` or ``std`` is a Tensor, the shape of the output
            Tensor is the same as ``mean`` or ``std`` , attr ``shape`` is ignored.
            Default is None
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        A Tensor filled with random values sampled from a normal distribution with ``mean`` and ``std`` .

    Examples:
        .. code-block:: python

            import paddle

            out1 = paddle.normal(shape=[2, 3])
            # [[ 0.17501129  0.32364586  1.561118  ]  # random
            #  [-1.7232178   1.1545963  -0.76156676]]  # random

454
            mean_tensor = paddle.to_tensor([1.0, 2.0, 3.0])
455 456 457
            out2 = paddle.normal(mean=mean_tensor)
            # [ 0.18644847 -1.19434458  3.93694787]  # random

458
            std_tensor = paddle.to_tensor([1.0, 2.0, 3.0])
459 460 461 462
            out3 = paddle.normal(mean=mean_tensor, std=std_tensor)
            # [1.00780561 3.78457445 5.81058198]  # random

    """
Z
zhiboniu 已提交
463
    if not paddle.in_dynamic_mode():
464 465 466 467
        check_type(mean, 'mean', (int, float, Variable), 'normal')
        check_type(std, 'std', (int, float, Variable), 'normal')
        if isinstance(mean, Variable):
            check_dtype(
468 469 470 471 472
                mean.dtype,
                'mean',
                ['float32', 'float64'],
                'normal',
                "If mean is Tensor, it's data type only support float32, float64.",
473 474 475
            )
        if isinstance(std, Variable):
            check_dtype(
476 477 478 479 480
                std.dtype,
                'std',
                ['float32', 'float64'],
                'normal',
                "If std is Tensor, it's data type only support float32, float64.",
481 482
            )
        if shape is not None:
483
            check_shape(shape, 'normal')
484 485 486 487 488 489 490 491 492 493 494 495 496 497

    if isinstance(mean, Variable):
        if isinstance(std, Variable):
            if std.dtype != mean.dtype:
                std = paddle.cast(std, mean.dtype)
            mean_shape = paddle.shape(mean)
            std = paddle.reshape(std, mean_shape)
        else:
            std = float(std)
        out = standard_normal(paddle.shape(mean), mean.dtype, name)
    elif isinstance(std, Variable):
        mean = float(mean)
        out = standard_normal(paddle.shape(std), std.dtype, name)
    else:
498
        return gaussian(shape=shape, mean=mean, std=std, name=name)
499 500

    out = out * std + mean
Z
zhiboniu 已提交
501
    if not paddle.in_dynamic_mode():
502 503 504 505
        out.stop_grediant = True
    return out


506
def uniform(shape, dtype=None, min=-1.0, max=1.0, seed=0, name=None):
P
pangyoki 已提交
507
    """
508
    Returns a Tensor filled with random values sampled from a uniform
P
pangyoki 已提交
509 510 511
    distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.

    Examples:
李灿 已提交
512

Z
zhupengyang 已提交
513
    .. code-block:: text
李灿 已提交
514

P
pangyoki 已提交
515 516 517 518 519 520 521 522 523 524 525
        Input:
          shape = [1, 2]
        Output:
          result=[[0.8505902, 0.8397286]]

    Args:
        shape(list|tuple|Tensor): The shape of the output Tensor. If ``shape``
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64).
526 527 528 529
        dtype(str|np.dtype, optional): The data type of the output Tensor.
            Supported data types: float32, float64.
            Default is None, use global default dtype (see ``get_default_dtype``
            for details).
P
pangyoki 已提交
530 531 532 533
        min(float|int, optional): The lower bound on the range of random values
            to generate, ``min`` is included in the range. Default is -1.0.
        max(float|int, optional): The upper bound on the range of random values
            to generate, ``max`` is excluded in the range. Default is 1.0.
J
JYChen 已提交
534
        seed(int, optional): Random seed used for generating samples. If seed is 0,
535
            it will use the seed of the global default generator (which can be set by paddle.seed).
J
JYChen 已提交
536
            Note that if seed is not 0, this operator will always generate the same random numbers every
P
pangyoki 已提交
537
            time. Default is 0.
538 539
        name(str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.
P
pangyoki 已提交
540 541 542 543 544 545 546

    Returns:
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.

    Examples:
        .. code-block:: python
547
          :name: code-example1
548

P
pangyoki 已提交
549 550 551 552
            import paddle

            # example 1:
            # attr shape is a list which doesn't contain Tensor.
Z
zhupengyang 已提交
553 554 555 556
            out1 = paddle.uniform(shape=[3, 4])
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357], # random
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249], # random
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]] # random
P
pangyoki 已提交
557 558 559

            # example 2:
            # attr shape is a list which contains Tensor.
Z
zhupengyang 已提交
560 561 562 563 564
            dim1 = paddle.to_tensor([2], 'int64')
            dim2 = paddle.to_tensor([3], 'int32')
            out2 = paddle.uniform(shape=[dim1, dim2])
            # [[-0.9951253,   0.30757582, 0.9899647 ], # random
            #  [ 0.5864527,   0.6607096,  -0.8886161]] # random
P
pangyoki 已提交
565 566 567

            # example 3:
            # attr shape is a Tensor, the data type must be int64 or int32.
568
            shape_tensor = paddle.to_tensor([2, 3])
Z
zhupengyang 已提交
569 570 571
            out3 = paddle.uniform(shape_tensor)
            # [[-0.8517412,  -0.4006908,   0.2551912 ], # random
            #  [ 0.3364414,   0.36278176, -0.16085452]] # random
P
pangyoki 已提交
572
    """
573 574 575 576
    if dtype is None:
        dtype = paddle.framework.get_default_dtype()
        if dtype not in ['float32', 'float64']:
            raise TypeError(
577 578 579 580
                "uniform/rand only supports [float32, float64], but the default dtype is {}".format(
                    dtype
                )
            )
581

P
pangyoki 已提交
582 583 584
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)

585 586
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
587 588 589 590 591 592 593 594
        return _C_ops.uniform_random(
            shape,
            dtype,
            float(min),
            float(max),
            seed,
            _current_expected_place(),
        )
595 596

    if _in_legacy_dygraph():
597
        shape = utils.convert_shape_to_list(shape)
598 599 600 601 602 603 604 605 606 607 608 609
        return _legacy_C_ops.uniform_random(
            'shape',
            shape,
            'min',
            float(min),
            'max',
            float(max),
            'seed',
            seed,
            'dtype',
            dtype,
        )
P
pangyoki 已提交
610

611 612
    check_type(shape, 'shape', (list, tuple, Variable), 'uniform/rand')
    check_dtype(dtype, 'dtype', ('float32', 'float64'), 'uniform/rand')
613 614
    check_type(min, 'min', (float, int, Variable), 'uniform/rand')
    check_type(max, 'max', (float, int, Variable), 'uniform/rand')
P
pangyoki 已提交
615 616 617

    inputs = dict()
    attrs = {'seed': seed, 'min': min, 'max': max, 'dtype': dtype}
618 619 620
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='uniform/rand'
    )
P
pangyoki 已提交
621

622
    helper = LayerHelper("uniform", **locals())
P
pangyoki 已提交
623
    out = helper.create_variable_for_type_inference(dtype)
624 625 626
    helper.append_op(
        type="uniform_random", inputs=inputs, attrs=attrs, outputs={"Out": out}
    )
627
    out.stop_gradient = True
P
pangyoki 已提交
628 629 630
    return out


J
JYChen 已提交
631 632 633
@dygraph_only
def uniform_(x, min=-1.0, max=1.0, seed=0, name=None):
    """
634
    This is the inplace version of OP ``uniform``, which returns a Tensor filled
J
JYChen 已提交
635 636
    with random values sampled from a uniform distribution. The output Tensor will
    be inplaced with input ``x``. Please refer to :ref:`api_tensor_uniform`.
637

J
JYChen 已提交
638 639 640 641 642 643
    Args:
        x(Tensor): The input tensor to be filled with random values.
        min(float|int, optional): The lower bound on the range of random values
            to generate, ``min`` is included in the range. Default is -1.0.
        max(float|int, optional): The upper bound on the range of random values
            to generate, ``max`` is excluded in the range. Default is 1.0.
644 645
        seed(int, optional): Random seed used for generating samples. If seed is 0,
            it will use the seed of the global default generator (which can be set by paddle.seed).
J
JYChen 已提交
646 647 648 649 650 651 652 653 654 655
            Note that if seed is not 0, this operator will always generate the same random numbers every
            time. Default is 0.
        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 input tensor x filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``).
    Examples:
        .. code-block:: python
656

J
JYChen 已提交
657 658 659 660 661 662 663 664 665
            import paddle
            # example:
            x = paddle.ones(shape=[3, 4])
            x.uniform_()
            print(x)
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357], # random
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249], # random
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]] # random
    """
666
    if in_dygraph_mode():
667
        return _C_ops.uniform_random_inplace_(x, min, max, seed, 0, 0, 1.0)
668
    else:
669 670 671
        return _legacy_C_ops.uniform_random_inplace_(
            x, 'min', min, 'max', max, 'seed', seed
        )
J
JYChen 已提交
672 673


674
def randint(low=0, high=None, shape=[1], dtype=None, name=None):
S
silingtong123 已提交
675
    """
676
    Returns a Tensor filled with random integers from a discrete uniform
677 678
    distribution in the range [``low``, ``high``), with ``shape`` and ``dtype``.
    If ``high`` is None (the default), the range is [0, ``low``).
S
silingtong123 已提交
679 680

    Args:
681
        low (int, optional): The lower bound on the range of random values to generate.
682 683
            The ``low`` is included in the range. If ``high`` is None, the
            range is [0, ``low``). Default is 0.
684
        high (int, optional): The upper bound on the range of random values to
685 686
            generate, the ``high`` is excluded in the range. Default is None
            (see above for behavior if high = None). Default is None.
687
        shape (list|tuple|Tensor, optional): The shape of the output Tensor. If ``shape``
688 689 690 691
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64). Default is [1].
692
        dtype (str|np.dtype, optional): The data type of the
693 694
            output tensor. Supported data types: int32, int64. If ``dytpe``
            is None, the data type is int64. Default is None.
695
        name (str, optional): The default value is None.  Normally there is no
696 697
            need for user to set this property.  For more information, please
            refer to :ref:`api_guide_Name`.
S
silingtong123 已提交
698

699
    Returns:
700 701
        Tensor: A Tensor filled with random integers from a discrete uniform
        distribution in the range [``low``, ``high``), with ``shape`` and ``dtype``.
S
silingtong123 已提交
702 703 704

    Examples:
        .. code-block:: python
705

706
            import paddle
707

708 709
            # example 1:
            # attr shape is a list which doesn't contain Tensor.
710
            out1 = paddle.randint(low=-5, high=5, shape=[3])
711 712 713 714
            # [0, -3, 2]  # random

            # example 2:
            # attr shape is a list which contains Tensor.
Z
zhupengyang 已提交
715 716 717
            dim1 = paddle.to_tensor([2], 'int64')
            dim2 = paddle.to_tensor([3], 'int32')
            out2 = paddle.randint(low=-5, high=5, shape=[dim1, dim2])
718 719 720 721 722
            # [[0, -1, -3],  # random
            #  [4, -2,  0]]  # random

            # example 3:
            # attr shape is a Tensor
723
            shape_tensor = paddle.to_tensor(3)
Z
zhupengyang 已提交
724
            out3 = paddle.randint(low=-5, high=5, shape=shape_tensor)
725 726 727 728
            # [-2, 2, 3]  # random

            # example 4:
            # data type is int32
729
            out4 = paddle.randint(low=-5, high=5, shape=[3], dtype='int32')
730 731 732 733 734
            # [-5, 4, -4]  # random

            # example 5:
            # Input only one parameter
            # low=0, high=10, shape=[1], dtype='int64'
735
            out5 = paddle.randint(10)
736
            # [7]  # random
S
silingtong123 已提交
737

738 739
    """
    if high is None:
740 741
        if low <= 0:
            raise ValueError(
742 743 744 745
                "If high is None, low must be greater than 0, but received low = {0}.".format(
                    low
                )
            )
746 747
        high = low
        low = 0
S
silingtong123 已提交
748 749
    if dtype is None:
        dtype = 'int64'
750 751
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
S
silingtong123 已提交
752

F
From00 已提交
753 754 755
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
756
        return _C_ops.randint(low, high, shape, dtype, place)
F
From00 已提交
757
    if _in_legacy_dygraph():
758
        shape = utils.convert_shape_to_list(shape)
759 760 761
        return _legacy_C_ops.randint(
            'shape', shape, 'low', low, 'high', high, 'seed', 0, 'dtype', dtype
        )
S
silingtong123 已提交
762

763
    check_shape(shape, 'randint')
764 765
    check_dtype(dtype, 'dtype', ['int32', 'int64'], 'randint')
    if low >= high:
S
silingtong123 已提交
766 767
        raise ValueError(
            "randint's low must less then high, but received low = {0}, "
768 769
            "high = {1}".format(low, high)
        )
S
silingtong123 已提交
770

771 772
    inputs = dict()
    attrs = {'low': low, 'high': high, 'seed': 0, 'dtype': dtype}
773 774 775
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='randint'
    )
776 777 778

    helper = LayerHelper("randint", **locals())
    out = helper.create_variable_for_type_inference(dtype=dtype)
779 780 781
    helper.append_op(
        type='randint', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
782
    out.stop_gradient = True
S
silingtong123 已提交
783
    return out
C
cc 已提交
784 785


786 787
def randint_like(x, low=0, high=None, dtype=None, name=None):
    """
788
    Returns a Tensor filled with random integers from a discrete uniform
789
    distribution in the range [``low``, ``high``), with the same shape as ``x``.
790
    (use ``dtype`` if ``dtype`` is not None)
791 792 793
    If ``high`` is None (the default), the range is [0, ``low``).

    Args:
794
        x (Tensor): The input tensor which specifies shape. The dtype of ``x``
795 796 797 798 799 800 801 802
            can be bool, int32, int64, float16, float32, float64.
        low (int): The lower bound on the range of random values to generate.
            The ``low`` is included in the range. If ``high`` is None, the
            range is [0, ``low``). Default is 0.
        high (int, optional): The upper bound on the range of random values to
            generate, the ``high`` is excluded in the range. Default is None
            (see above for behavior if high = None). Default is None.
        dtype (str|np.dtype, optional): The data type of the
803
            output tensor. Supported data types: bool, int32, int64, float16,
804 805 806 807 808 809
            float32, float64. If ``dytpe`` is None, the data type is the
            same as x's data type. Default is None.
        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`.

810
    Returns:
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912
        Tensor: A Tensor filled with random integers from a discrete uniform
        distribution in the range [``low``, ``high``), with ``shape`` and ``dtype``.

    Examples:
        .. code-block:: python

            import paddle

            # example 1:
            # dtype is None and the dtype of x is float16
            x = paddle.zeros((1,2)).astype("float16")
            out1 = paddle.randint_like(x, low=-5, high=5)
            print(out1)
            print(out1.dtype)
            # [[0, -3]]  # random
            # paddle.float16

            # example 2:
            # dtype is None and the dtype of x is float32
            x = paddle.zeros((1,2)).astype("float32")
            out2 = paddle.randint_like(x, low=-5, high=5)
            print(out2)
            print(out2.dtype)
            # [[0, -3]]  # random
            # paddle.float32

            # example 3:
            # dtype is None and the dtype of x is float64
            x = paddle.zeros((1,2)).astype("float64")
            out3 = paddle.randint_like(x, low=-5, high=5)
            print(out3)
            print(out3.dtype)
            # [[0, -3]]  # random
            # paddle.float64

            # example 4:
            # dtype is None and the dtype of x is int32
            x = paddle.zeros((1,2)).astype("int32")
            out4 = paddle.randint_like(x, low=-5, high=5)
            print(out4)
            print(out4.dtype)
            # [[0, -3]]  # random
            # paddle.int32

            # example 5:
            # dtype is None and the dtype of x is int64
            x = paddle.zeros((1,2)).astype("int64")
            out5 = paddle.randint_like(x, low=-5, high=5)
            print(out5)
            print(out5.dtype)
            # [[0, -3]]  # random
            # paddle.int64

            # example 6:
            # dtype is float64 and the dtype of x is float32
            x = paddle.zeros((1,2)).astype("float32")
            out6 = paddle.randint_like(x, low=-5, high=5, dtype="float64")
            print(out6)
            print(out6.dtype)
            # [[0, -1]]  # random
            # paddle.float64

            # example 7:
            # dtype is bool and the dtype of x is float32
            x = paddle.zeros((1,2)).astype("float32")
            out7 = paddle.randint_like(x, low=-5, high=5, dtype="bool")
            print(out7)
            print(out7.dtype)
            # [[0, -1]]  # random
            # paddle.bool

            # example 8:
            # dtype is int32 and the dtype of x is float32
            x = paddle.zeros((1,2)).astype("float32")
            out8 = paddle.randint_like(x, low=-5, high=5, dtype="int32")
            print(out8)
            print(out8.dtype)
            # [[0, -1]]  # random
            # paddle.int32

            # example 9:
            # dtype is int64 and the dtype of x is float32
            x = paddle.zeros((1,2)).astype("float32")
            out9 = paddle.randint_like(x, low=-5, high=5, dtype="int64")
            print(out9)
            print(out9.dtype)
            # [[0, -1]]  # random
            # paddle.int64

            # example 10:
            # dtype is int64 and the dtype of x is bool
            x = paddle.zeros((1,2)).astype("bool")
            out10 = paddle.randint_like(x, low=-5, high=5, dtype="int64")
            print(out10)
            print(out10.dtype)
            # [[0, -1]]  # random
            # paddle.int64

    """
    if high is None:
        if low <= 0:
            raise ValueError(
913 914 915 916
                "If high is None, low must be greater than 0, but received low = {0}.".format(
                    low
                )
            )
917 918 919 920 921 922
        high = low
        low = 0
    if dtype is None:
        dtype = x.dtype
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
923
    shape = paddle.shape(x)
924 925 926 927

    if low >= high:
        raise ValueError(
            "randint_like's low must less then high, but received low = {0}, "
928 929
            "high = {1}".format(low, high)
        )
930

Z
zhiboniu 已提交
931
    if paddle.in_dynamic_mode():
932
        shape = utils.convert_shape_to_list(shape)
933 934 935 936 937 938 939 940 941 942 943 944
        out = _legacy_C_ops.randint(
            'shape',
            shape,
            'low',
            low,
            'high',
            high,
            'seed',
            0,
            'dtype',
            core.VarDesc.VarType.INT64,
        )
945 946 947 948
        out = paddle.cast(out, dtype)
        return out

    check_shape(shape, 'randint_like')
949 950 951 952 953 954
    check_dtype(
        dtype,
        'dtype',
        ['bool', 'float16', 'float32', 'float64', 'int32', 'int64'],
        'randint_like',
    )
955

956
    inputs = {"ShapeTensor": shape}
957 958 959 960
    attrs = {
        'low': low,
        'high': high,
        'seed': 0,
961
        'dtype': core.VarDesc.VarType.INT64,
962 963 964 965
    }

    helper = LayerHelper("randint", **locals())
    out = helper.create_variable_for_type_inference(
966 967 968 969 970
        dtype=core.VarDesc.VarType.INT64
    )
    helper.append_op(
        type='randint', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
971 972 973 974 975
    out.stop_gradient = True
    out = paddle.cast(out, dtype)
    return out


976
def randperm(n, dtype="int64", name=None):
C
cc 已提交
977
    """
978
    Returns a 1-D Tensor filled with random permutation values from 0
979
    to n-1, with ``dtype``.
C
cc 已提交
980 981

    Args:
982 983
        n (int): The upper bound (exclusive), and it should be greater than 0.
        dtype (str|np.dtype, optional): The data type of
984 985
            the output Tensor. Supported data types: int32, int64, float32,
            float64. Default is int64.
986
        name (str, optional): The default value is None. Normally there is no
987 988
            need for user to set this property. For more information, please
            refer to :ref:`api_guide_Name`.
C
cc 已提交
989 990

    Returns:
991 992
        Tensor: A 1-D Tensor filled with random permutation values from 0
        to n-1, with ``dtype``.
C
cc 已提交
993 994 995 996

    Examples:
        .. code-block:: python

997
            import paddle
C
cc 已提交
998

999
            out1 = paddle.randperm(5)
1000
            # [4, 1, 2, 3, 0]  # random
C
cc 已提交
1001

1002
            out2 = paddle.randperm(7, 'int32')
1003
            # [1, 6, 2, 0, 4, 3, 5]  # random
1004

C
cc 已提交
1005
    """
1006 1007 1008
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)

Z
zyfncg 已提交
1009
    if in_dygraph_mode():
1010
        return _C_ops.randperm(n, dtype, _current_expected_place())
Z
zyfncg 已提交
1011
    if _in_legacy_dygraph():
1012
        return _legacy_C_ops.randperm('n', n, 'seed', 0, 'dtype', dtype)
C
cc 已提交
1013 1014 1015

    if n < 1:
        raise ValueError("The input n should be greater than 0 in randperm op.")
1016 1017 1018
    check_dtype(
        dtype, 'dtype', ['int64', 'int32', 'float32', 'float64'], 'randperm'
    )
C
cc 已提交
1019 1020

    helper = LayerHelper("randperm", **locals())
1021 1022
    out = helper.create_variable_for_type_inference(dtype)
    attrs = {'n': n, 'dtype': dtype, 'seed': 0}
1023 1024 1025
    helper.append_op(
        type='randperm', inputs={}, outputs={'Out': out}, attrs=attrs
    )
1026
    out.stop_gradient = True
C
cc 已提交
1027
    return out
X
Xing Wu 已提交
1028 1029


1030
def rand(shape, dtype=None, name=None):
X
Xing Wu 已提交
1031
    """
1032
    Returns a Tensor filled with random values sampled from a uniform
1033
    distribution in the range [0, 1), with ``shape`` and ``dtype``.
X
Xing Wu 已提交
1034 1035

    Args:
1036
        shape (list|tuple|Tensor): The shape of the output Tensor. If ``shape``
1037 1038 1039 1040
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64).
1041
        dtype (str|np.dtype, optional): The data type of the output Tensor.
1042 1043 1044
            Supported data types: float32, float64.
            Default is None, use global default dtype (see ``get_default_dtype``
            for details).
1045
        name (str, optional): The default value is None. Normally there is no
1046 1047
            need for user to set this property. For more information, please
            refer to :ref:`api_guide_Name`.
1048

X
Xing Wu 已提交
1049
    Returns:
1050 1051
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [0, 1), with ``shape`` and ``dtype``.
X
Xing Wu 已提交
1052 1053 1054 1055

    Examples:
        .. code-block:: python

1056
            import paddle
1057

1058
            # example 1: attr shape is a list which doesn't contain Tensor.
1059
            out1 = paddle.rand(shape=[2, 3])
1060 1061 1062 1063
            # [[0.451152  , 0.55825245, 0.403311  ],  # random
            #  [0.22550228, 0.22106001, 0.7877319 ]]  # random

            # example 2: attr shape is a list which contains Tensor.
Z
zhupengyang 已提交
1064 1065
            dim1 = paddle.to_tensor([2], 'int64')
            dim2 = paddle.to_tensor([3], 'int32')
1066
            out2 = paddle.rand(shape=[dim1, dim2, 2])
1067 1068 1069 1070 1071 1072 1073 1074
            # [[[0.8879919 , 0.25788337],  # random
            #   [0.28826773, 0.9712097 ],  # random
            #   [0.26438272, 0.01796806]],  # random
            #  [[0.33633623, 0.28654453],  # random
            #   [0.79109055, 0.7305809 ],  # random
            #   [0.870881  , 0.2984597 ]]]  # random

            # example 3: attr shape is a Tensor, the data type must be int64 or int32.
1075
            shape_tensor = paddle.to_tensor([2, 3])
Z
zhupengyang 已提交
1076
            out3 = paddle.rand(shape_tensor)
1077 1078
            # [[0.22920267, 0.841956  , 0.05981819],  # random
            #  [0.4836288 , 0.24573246, 0.7516129 ]]  # random
X
Xing Wu 已提交
1079 1080

    """
1081
    return uniform(shape, dtype, min=0.0, max=1.0, name=name)
1082 1083 1084


def exponential_(x, lam=1.0, name=None):
1085
    r"""
1086 1087
    This inplace OP fill input Tensor ``x`` with random number from a Exponential Distribution.

1088 1089
    ``lam`` is :math:`\lambda` parameter of Exponential Distribution.

1090 1091 1092 1093 1094 1095
    .. math::

        f(x) = \lambda e^{-\lambda x}

    Args:
        x(Tensor):  Input tensor. The data type should be float32, float64.
1096
        lam(float, optional): :math:`\lambda` parameter of Exponential Distribution. Default, 1.0.
1097 1098 1099
        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`.
1100
    Returns:
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
        Tensor: Input Tensor ``x``.

    Examples:
        .. code-block:: python

            import paddle
            paddle.set_device('cpu')
            paddle.seed(100)

            x = paddle.empty([2,3])
            x.exponential_()
            # [[0.80643415, 0.23211166, 0.01169797],
            #  [0.72520673, 0.45208144, 0.30234432]]

    """
1116
    if in_dygraph_mode():
1117
        return _C_ops.exponential_(x, lam)
1118
    elif paddle.in_dynamic_mode():
1119
        return _legacy_C_ops.exponential_(x, "lambda", lam)
1120 1121 1122 1123

    check_variable_and_dtype(x, "x", ["float32", "float64"], "exponential")

    helper = LayerHelper("exponential", **locals())
1124 1125 1126 1127 1128 1129
    helper.append_op(
        type='exponential',
        inputs={"X": x},
        outputs={'Out': x},
        attrs={"lambda": lam},
    )
1130
    return x