
    zjn?                    4   d dl mZ d dlmZ d dlZd dlZd dlmZm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZmZmZ erd d	lmZ d d
lmZ d dlmZ  ej        ej                  j         ej        ej                  j        dZd Z G d dej                  Z dS )    )annotations)TYPE_CHECKINGN)
check_typeconvert_dtype)Variable)exponential_family)in_dynamic_mode) binary_cross_entropy_with_logitssigmoidsoftplus)Sequence)Tensor)_DTypeLiteral)float32float64c                    t                               |          }t          j        | |d|z
                                |          S )zClip probs from [0, 1] to (0, 1) with ``eps``.

    Args:
        probs (Tensor): probs of Bernoulli.
        dtype (str): data type.

    Returns:
        Tensor: Clipped probs.
       )minmax)EPSgetpaddleclipastype)probsdtypeepss      m/lsinfo/ai/hellotax_ai/data_center/backend/venv/lib/python3.11/site-packages/paddle/distribution/bernoulli.py_clip_probsr   ,   s<     ''%..C;u#1s7333::5AAA    c                       e Zd ZU dZded<   ded<   ded<   ded<   dd  fdZed!d            Zed!d            Zg fd"dZ	g dfd#dZ
d$dZd$dZd$dZd!dZd%dZ xZS )&	Bernoullia  Bernoulli distribution parameterized by ``probs``, which is the probability of value 1.

    In probability theory and statistics, the Bernoulli distribution, named after Swiss
    mathematician Jacob Bernoulli, is the discrete probability distribution of a random
    variable which takes the value 1 with probability ``p`` and the value 0 with
    probability ``q=1-p``.

    The probability mass function of this distribution, over possible outcomes ``k``, is

    .. math::

        {\begin{cases}
        q=1-p & \text{if }value=0 \\
        p & \text{if }value=1
        \end{cases}}

    Args:
        probs (float|Tensor): The ``probs`` input of Bernoulli distribution. The data type is float32 or float64. The range must be in [0, 1].
        name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.

    Examples:

        .. code-block:: python

            >>> import paddle
            >>> from paddle.distribution import Bernoulli

            >>> # init `probs` with a float
            >>> rv = Bernoulli(probs=0.3)

            >>> print(rv.mean)
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            0.30000001)

            >>> print(rv.variance)
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            0.21000001)

            >>> print(rv.entropy())
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            0.61086434)
    strnamer   r   logitsr   r   Nfloat | Tensor
str | NonereturnNonec                J   |pd| _         t                      s3t          |dt          t          t
          j        j        f| j                    |                     |          r!|| _	        t          |j                  | _        n4|                     |          \  | _	        t          j                    | _        t          | j	        | j                  | _	        |                     | j	        d          | _        t#                                          | j	        j        d           d S )Nr"   r   T)	is_binary )batch_shapeevent_shape)r$   r	   r   floatr   r   pirValue_validate_argsr   r   r   
_to_tensorget_default_dtyper   _probs_to_logitsr%   super__init__shape)selfr   r$   	__class__s      r   r7   zBernoulli.__init__k   s    'K	   	&*"23		   u%% 	4DJ&u{33DJJ??511LTZ133DJ !TZ88
++DJ$+GGTZ%52FFFFFr    c                    | j         S )zjMean of Bernoulli distribution.

        Returns:
            Tensor: Mean value of distribution.
        )r   r9   s    r   meanzBernoulli.mean   s     zr    c                F    t          j        | j        d| j        z
            S )zrVariance of Bernoulli distribution.

        Returns:
            Tensor: Variance value of distribution.
        r   )r   multiplyr   r<   s    r   variancezBernoulli.variance   s     tzA
N<<<r    r8   Sequence[int]c           	        | j         dz   }t                      s?t          |dt          j        t
          t          t          t          j	        j
        f|           t          |t                    r|nt          |          }|                     |          }t          j                    5  t          j        | j                            |          |          cddd           S # 1 swxY w Y   dS )a  Sample from Bernoulli distribution.

        Args:
            shape (Sequence[int], optional): Sample shape.

        Returns:
            Tensor: Sampled data with shape `sample_shape` + `batch_shape` + `event_shape`.

        Examples:

            .. code-block:: pycon

                >>> import paddle
                >>> from paddle.distribution import Bernoulli

                >>> rv = Bernoulli(paddle.full([1], 0.3))
                >>> print(rv.sample([100]).shape)
                paddle.Size([100, 1])

                >>> rv = Bernoulli(paddle.to_tensor(0.3))
                >>> print(rv.sample([100]).shape)
                paddle.Size([100])

                >>> rv = Bernoulli(paddle.to_tensor([0.3, 0.5]))
                >>> print(rv.sample([100]).shape)
                paddle.Size([100, 2])

                >>> rv = Bernoulli(paddle.to_tensor([0.3, 0.5]))
                >>> print(rv.sample([100, 2]).shape)
                paddle.Size([100, 2, 2])
        _sampler8   r$   N)r$   r	   r   npndarrayr   listtupler   r0   r1   
isinstance_extend_shapeno_grad	bernoullir   expand)r9   r8   r$   s      r   samplezBernoulli.sample   s+   @ y9$   	XtUFJ4DE	   $E511CuU||""5))^ 	I 	I#DJ$5$5e$<$<4HHH	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	Is   &.C!!C%(C%g      ?temperaturer/   c           
     (   | j         dz   }t                      sWt          |dt          j        t
          t          j        j        t          t          f|           t          |dt          f|           t          |t                    r|nt          |          }|                     |          }t          j        d|| j                  }| j                            |          }t          j        || j                  }t          j        t          j        t          j        |                                |                                           t          j        |                                |                                                     |          S )a  Sample from Bernoulli distribution (reparameterized).

        The `rsample` is a continuously approximate of Bernoulli distribution reparameterized sample method.
        [1] Chris J. Maddison, Andriy Mnih, and Yee Whye Teh. The Concrete Distribution: A Continuous Relaxation of Discrete Random Variables. 2016.
        [2] Eric Jang, Shixiang Gu, and Ben Poole. Categorical Reparameterization with Gumbel-Softmax. 2016.

        Note:
            `rsample` need to be followed by a `sigmoid`, which converts samples' value to unit interval (0, 1).

        Args:
            shape (Sequence[int], optional): Sample shape.
            temperature (float): temperature for rsample, must be positive.

        Returns:
            Tensor: Sampled data with shape `sample_shape` + `batch_shape` + `event_shape`.

        Examples:

            .. code-block:: pycon

                >>> import paddle
                >>> paddle.seed(1)
                >>> from paddle.distribution import Bernoulli

                >>> rv = Bernoulli(paddle.full([1], 0.3))
                >>> print(rv.sample([100]).shape)
                paddle.Size([100, 1])

                >>> rv = Bernoulli(0.3)
                >>> print(rv.rsample([100]).shape)
                paddle.Size([100])

                >>> rv = Bernoulli(paddle.to_tensor([0.3, 0.5]))
                >>> print(rv.rsample([100]).shape)
                paddle.Size([100, 2])

                >>> rv = Bernoulli(paddle.to_tensor([0.3, 0.5]))
                >>> print(rv.rsample([100, 2]).shape)
                paddle.Size([100, 2, 2])

                >>> # `rsample` has to be followed by a `sigmoid`
                >>> rv = Bernoulli(0.3)
                >>> rsample = rv.rsample([3])
                >>> rsample_sigmoid = paddle.nn.functional.sigmoid(rsample)
                >>> print(rsample)
                Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
                [-1.46112013, -0.01239836, -1.32765460])
                >>> print(rsample_sigmoid)
                Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.18829606, 0.49690047, 0.20954758])

                >>> # The smaller the `temperature`, the distribution of `rsample` closer to `sample`, with `probs` of 0.3.
                >>> print(
                ...     paddle.nn.functional.sigmoid(
                ...         rv.rsample(
                ...             [1000],
                ...             temperature=1.0,
                ...         )
                ...     ).sum()
                ... )
                >>> # doctest: +SKIP('output will be different')
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                365.63122559)
                >>> # doctest: -SKIP

                >>> print(
                ...     paddle.nn.functional.sigmoid(
                ...         rv.rsample(
                ...             [1000],
                ...             temperature=0.1,
                ...         )
                ...     ).sum()
                ... )
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                320.15057373)
        _rsampler8   rO   r,   )r8   
fill_valuer   )r   )r$   r	   r   rE   rF   r   r   r0   r1   rG   rH   r/   rI   rJ   fullr   r   rM   randdivideaddsubtractloglog1p)r9   r8   rO   r$   r   uniformss         r   rsamplezBernoulli.rsample   s`   ^ y:%   	Xvz'7uE	   	   $E511CuU||""5))kDJ
 
 
 
!!%((;uDJ777}J(0A0A0C0CDD		uf^^-=-=>>  
 
 	
r    valuec                   | j         dz   }t                      s(t          |dt          t          j        j        f|           |                     | j        |          }t	          j	        | j        |g          \  }}t	          j
        |          }t	          j        |          }t	          j        |dk     |t	          j        |dk     t	          j        ||          |          |          S )a
  Cumulative distribution function(CDF) evaluated at value.

        .. math::

            { \begin{cases}
            0 & \text{if } value \lt  0 \\
            1 - p & \text{if } 0 \leq value \lt  1 \\
            1 & \text{if } value \geq 1
            \end{cases}
            }

        Args:
            value (Tensor): Value to be evaluated.

        Returns:
            Tensor: CDF evaluated at value.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Bernoulli

                >>> rv = Bernoulli(0.3)
                >>> print(rv.cdf(paddle.to_tensor([1.0])))
                Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                [1.])
        _cdfr\   r   r   rD   )r$   r	   r   r   r   r0   r1   _check_values_dtype_in_probsr   broadcast_tensors
zeros_like	ones_likewhererW   )r9   r\   r$   r   zerosoness         r   cdfzBernoulli.cdf3  s    < y6!   	Kug&*2B'CTJJJ11$*eDD/U0CDDu!%((&&|AILFOD%$@$@$GG	
 
 
 	
r    c                   | j         dz   }t                      s(t          |dt          t          j        j        f|           |                     | j        |          }t	          j	        | j
        |g          \  }}t          ||d|           S )a;  Log of probability density function.

        Args:
            value (Tensor): Value to be evaluated.

        Returns:
            Tensor: Log of probability density evaluated at value.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Bernoulli

                >>> rv = Bernoulli(0.3)
                >>> print(rv.log_prob(paddle.to_tensor([1.0])))
                Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                [-1.20397282])
        	_log_probr\   none	reductionr$   )r$   r	   r   r   r   r0   r1   r_   r   r`   r%   r
   )r9   r\   r$   r%   s       r   log_probzBernoulli.log_probb  s    * y;&   	Kug&*2B'CTJJJ11$*eDD0$+u1EFF0EV$
 
 
 
 	
r    c                    | j         dz   }t                      s(t          |dt          t          j        j        f|           |                     |                              |          S )a  Probability density function(PDF) evaluated at value.

        .. math::

            { \begin{cases}
                q=1-p & \text{if }value=0 \\
                p & \text{if }value=1
                \end{cases}
            }

        Args:
            value (Tensor): Value to be evaluated.

        Returns:
            Tensor: PDF evaluated at value.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Bernoulli

                >>> rv = Bernoulli(0.3)
                >>> print(rv.prob(paddle.to_tensor([1.0])))
                Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.29999998])
        _probr\   rD   )	r$   r	   r   r   r   r0   r1   rl   exp)r9   r\   r$   s      r   probzBernoulli.prob  s`    : y7"   	Kug&*2B'CTJJJ}}U##''T'222r    c                P    | j         dz   }t          | j        | j        d|          S )a&  Entropy of Bernoulli distribution.

        .. math::

            {
                entropy = -(q \log q + p \log p)
            }

        Returns:
            Tensor: Entropy of distribution.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Bernoulli

                >>> rv = Bernoulli(0.3)
                >>> print(rv.entropy())
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                0.61086434)
        _entropyri   rj   )r$   r
   r%   r   )r9   r$   s     r   entropyzBernoulli.entropy  s4    0 y:%/KvD
 
 
 	
r    otherc           
     L   | j         dz   }t                      st          |dt          |           | j        }|j        }t          |            }t          |            }t          |          }t          |           }t          |           }	t          |           }
t          j        t          j	        t          j
        ||          t          j
        ||                    t          j	        t          j
        |	|          t          j
        |
|                              S )a  The KL-divergence between two Bernoulli distributions.

        .. math::

            {
                KL(a || b) = p_a \log(p_a / p_b) + (1 - p_a) \log((1 - p_a) / (1 - p_b))
            }

        Args:
            other (Bernoulli): instance of Bernoulli.

        Returns:
            Tensor: kl-divergence between two Bernoulli distributions.

        Examples:

            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Bernoulli

                >>> rv = Bernoulli(0.3)
                >>> rv_other = Bernoulli(0.7)

                >>> print(rv.kl_divergence(rv_other))
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                0.33891910)
        _kl_divergencert   )r$   r	   r   r"   r%   r   r   r   rV   rW   r?   )r9   rt   r$   a_logitsb_logitslog_palog_pbpaone_minus_palog_one_minus_palog_one_minus_pbs              r   kl_divergencezBernoulli.kl_divergence  s   : y++   	8ugy$777;<H9%%%H9%%%Xy))$X...$X...zO++V_VR-H-H  O 0,?? 0,?? 	
 
 	
r    )N)r   r&   r$   r'   r(   r)   )r(   r   )r8   rA   r(   r   )r8   rA   rO   r/   r(   r   )r\   r   r(   r   )rt   r"   r(   r   )__name__
__module____qualname____doc____annotations__r7   propertyr=   r@   rN   r[   rf   rl   rp   rs   r   __classcell__)r:   s   @r   r"   r"   :   so        ) )V IIIMMMNNNG G G G G G G0    X = = = X= -/ -I -I -I -I -I` &(cm
 m
 m
 m
 m
^-
 -
 -
 -
^
 
 
 
>!3 !3 !3 !3F
 
 
 
<5
 5
 5
 5
 5
 5
 5
 5
r    r"   )!
__future__r   typingr   numpyrE   r   paddle.base.data_feederr   r   paddle.base.frameworkr   paddle.distributionr   paddle.frameworkr	   paddle.nn.functionalr
   r   r   collections.abcr   r   paddle._typing.dtype_liker   finfor   r   r   r   r   ExponentialFamilyr"   r,   r    r   <module>r      s   # " " " " "                  = = = = = = = = * * * * * * 2 2 2 2 2 2 , , , , , ,           8((((((777777 v|FN++/v|FN++/ B B B}
 }
 }
 }
 }
"4 }
 }
 }
 }
 }
r    