
    zj3                        d dl mZ d dlZd dlmZ d dlZd dlZd dlm	Z	 d dl
mZ erd dlmZ d dlmZ  G d d	ej                  ZdS )
    )annotationsN)TYPE_CHECKING)	framework)distribution)Sequence)Tensorc                       e Zd ZU dZded<   ded<   d fdZedd	            Zedd
            Zedd            Z	ddZ
ddZddZddZddZg fddZg fddZd dZd!dZ xZS )"Laplacea  
    Creates a Laplace distribution parameterized by :attr:`loc` and :attr:`scale`.

    Mathematical details

    The probability density function (pdf) is

    .. math::
        pdf(x; \mu, \sigma) = \frac{1}{2 * \sigma} * e^{\frac{-|x - \mu|}{\sigma}}

    In the above equation:

    * :math:`loc = \mu`: is the location parameter.
    * :math:`scale = \sigma`: is the scale parameter.

    Args:
        loc (scalar|Tensor): The mean of the distribution.
        scale (scalar|Tensor): The scale of the distribution.

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> paddle.seed(2023)
            >>> m = paddle.distribution.Laplace(paddle.to_tensor(0.0), paddle.to_tensor(1.0))
            >>> m.sample()  # Laplace distributed with loc=0, scale=1
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                1.31554604)

    r   locscalefloat | TensorreturnNonec                X   t          |t          j        t          j        t
          j        j        f          st          dt          |                     t          |t          j        t          j        t
          j        j        f          st          dt          |                     t          |t          j                  rt          j
        d|          }t          |t          j                  rt          j
        d|          }t          |j                  dk    st          |j                  dk    r4|j        |j        k    r$t          j        ||g          \  | _        | _        n||c| _        | _        t#                                          | j        j                   d S )Nz/Expected type of loc is Real|Variable, but got z1Expected type of scale is Real|Variable, but got  shape
fill_valuer   )
isinstancenumbersRealr   VariablepaddlepirValue	TypeErrortypefulllenr   dtypebroadcast_tensorsr   r   super__init__)selfr   r   	__class__s      k/lsinfo/ai/hellotax_ai/data_center/backend/venv/lib/python3.11/site-packages/paddle/distribution/laplace.pyr#   zLaplace.__init__B   sx   ',	 2FJ4DE
 
 	 M$s))MM   GL)"4fj6FG
 
 	 QDKKQQ   c7<(( 	8+B3777CeW\** 	<KbU;;;Eq  C	NNQ$6$6I$$#)#;S%L#I#I DHdjj#& DHdj(((((    c                    | j         S )zTMean of distribution.

        Returns:
            Tensor: The mean value.
        )r   r$   s    r&   meanzLaplace.mean`   s     xr'   c                    d| j         z  S )zStandard deviation.

        The stddev is

        .. math::
            stddev = \sqrt{2} * \sigma

        In the above equation:

        * :math:`scale = \sigma`: is the scale parameter.

        Returns:
            Tensor: The std value.
        g;f?)r   r)   s    r&   stddevzLaplace.stddevi   s      $*$$r'   c                6    | j                             d          S )a  Variance of distribution.

        The variance is

        .. math::
            variance = 2 * \sigma^2

        In the above equation:

        * :math:`scale = \sigma`: is the scale parameter.

        Returns:
            Tensor: The variance value.
           )r,   powr)   s    r&   variancezLaplace.variance{   s      {q!!!r'   valuetuple[Tensor, Tensor, Tensor]c                   t          |t          j                  rt          j        d|          }|j        | j        j        k    rt          j        || j        j                  }t          | j        j	                  dk    s5t          | j
        j	                  dk    st          |j	                  dk    r&t          j        | j
        | j        |g          \  }}}n| j
        | j        }}|||fS )aH  Argument dimension check for distribution methods such as `log_prob`,
        `cdf` and `icdf`.

        Args:
          value (Tensor|Scalar): The input value, which can be a scalar or a tensor.

        Returns:
          loc, scale, value: The broadcasted loc, scale and value, with the same dimension and data type.
        r   r   r   )r   r   r   r   r   r    r   castr   r   r   r!   )r$   r1   r   r   s       r&   _validate_valuezLaplace._validate_value   s     eW\** 	<KbU;;;E;$****Ktz'788E
 !!A%%48>""Q&&5;!## & 84:u-! !C 4:CE5  r'   c                    |                      |          \  }}}t          j        d|z             }|t          j        ||z
            |z  z
  S )a  Log probability density/mass function.

        The log_prob is

        .. math::
            log\_prob(value) = \frac{-log(2 * \sigma) - |value - \mu|}{\sigma}

        In the above equation:

        * :math:`loc = \mu`: is the location parameter.
        * :math:`scale = \sigma`: is the scale parameter.

        Args:
          value (Tensor|Scalar): The input value, can be a scalar or a tensor.

        Returns:
          Tensor: The log probability, whose data type is same with value.

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> m = paddle.distribution.Laplace(paddle.to_tensor(0.0), paddle.to_tensor(1.0))
                >>> value = paddle.to_tensor(0.1)
                >>> m.log_prob(value)
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                        -0.79314721)

        r.   )r5   r   logabs)r$   r1   r   r   	log_scales        r&   log_probzLaplace.log_prob   sR    > !0077UEZE	***	6:eck22U:::r'   c                @    dt          j        d| j        z            z   S )am  Entropy of Laplace distribution.

        The entropy is:

        .. math::
            entropy() = 1 + log(2 * \sigma)

        In the above equation:

        * :math:`scale = \sigma`: is the scale parameter.

        Returns:
            The entropy of distribution.

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> m = paddle.distribution.Laplace(paddle.to_tensor(0.0), paddle.to_tensor(1.0))
                >>> m.entropy()
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                        1.69314718)
           r.   )r   r7   r   r)   s    r&   entropyzLaplace.entropy   s    2 6:a$*n----r'   c                    |                      |          \  }}}d||z
                                  z  t          j        ||z
                                   |z            z  }d|z
  S )aZ  Cumulative distribution function.

        The cdf is

        .. math::
            cdf(value) = 0.5 - 0.5 * sign(value - \mu) * e^\frac{-|(\mu - \sigma)|}{\sigma}

        In the above equation:

        * :math:`loc = \mu`: is the location parameter.
        * :math:`scale = \sigma`: is the scale parameter.

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

        Returns:
            Tensor: The cumulative probability of value.

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> m = paddle.distribution.Laplace(paddle.to_tensor(0.0), paddle.to_tensor(1.0))
                >>> value = paddle.to_tensor(0.1)
                >>> m.cdf(value)
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                        0.54758132)
              ?)r5   signr   expm1r8   )r$   r1   r   r   items        r&   cdfzLaplace.cdf   st    < !0077UEs{  ""#lUS[--///%7889 	 Tzr'   c                    |                      |          \  }}}|dz
  }|||                                z  t          j        d|                                z            z  z
  S )a`  Inverse Cumulative distribution function.

        The icdf is

        .. math::
            cdf^{-1}(value)= \mu - \sigma * sign(value - 0.5) * ln(1 - 2 * |value-0.5|)

        In the above equation:

        * :math:`loc = \mu`: is the location parameter.
        * :math:`scale = \sigma`: is the scale parameter.

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

        Returns:
            Tensor: The cumulative probability of value.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> m = paddle.distribution.Laplace(paddle.to_tensor(0.0), paddle.to_tensor(1.0))
                >>> value = paddle.to_tensor(0.1)
                >>> m.icdf(value)
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                        -1.60943794)
        r?   )r5   r@   r   log1pr8   )r$   r1   r   r   terms        r&   icdfzLaplace.icdf  sZ    : !0077UEs{Ud[[]]*V\"txxzz/-J-JJJJr'   r   Sequence[int]c                    t          |t                    r|nt          |          }t          j                    5  |                     |          cddd           S # 1 swxY w Y   dS )a  Generate samples of the specified shape.

        Args:
            shape(Sequence[int], optional): The shape of generated samples.
                Defaults to [].

        Returns:
            Tensor: A sample tensor that fits the Laplace distribution.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> paddle.seed(2023)
                >>> m = paddle.distribution.Laplace(paddle.to_tensor(0.0), paddle.to_tensor(1.0))
                >>> m.sample()  # Laplace distributed with loc=0, scale=1
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                    1.31554604)
        N)r   tupler   no_gradrsample)r$   r   s     r&   samplezLaplace.sample2  s    ( $E511CuU||^ 	' 	'<<&&	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	's   AA #A c           	        |                                  }|                     |          }t          j        |t	          t          j        dd                    |dz  z   d|dz  z
  | j        j                  }| j        | j	        |
                                z  t          j        |                                           z  z
  S )a  Reparameterized sample.

        Args:
            shape(Sequence[int], optional): The shape of generated samples.
                Defaults to [].

        Returns:
            Tensor: A sample tensor that fits the Laplace distribution.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> paddle.seed(2023)
                >>> m = paddle.distribution.Laplace(paddle.to_tensor([0.0]), paddle.to_tensor([1.0]))
                >>> m.rsample((1,))  # Laplace distributed with loc=0, scale=1
                Tensor(shape=[1, 1], dtype=float32, place=Place(cpu), stop_gradient=True,
                    [[1.31554604]])
        r<   r.   g      ?)r   minmaxr    )_get_eps_extend_shaper   uniformfloatnp	nextafterr   r    r   r@   rF   r8   )r$   r   epsrU   s       r&   rM   zLaplace.rsampleJ  s    * mmoo""5)).bl2q))**S1W4cAg(.	
 
 
 x$*w||~~5[[]]N9
 9
 
 
 	
r'   rV   c                v    d}| j         j        t          j        k    s| j         j        t          j        k    rd}|S )z
        Get the eps of certain data type.

        Note:
            Since paddle.finfo is temporarily unavailable, we
            use hard-coding style to get eps value.

        Returns:
            Float: An eps value by different data types.
        gy>gǝ <)r   r    r   float64
complex128)r$   rY   s     r&   rS   zLaplace._get_epsk  s6     HNfn,,x~!222C
r'   otherc                    |j         | j         z  }t          j        | j        |j        z
            }| j         t          j        | | j         z            z  |z   |j         z  }t          j        |          }||z   dz
  S )a  Calculate the KL divergence KL(self || other) with two Laplace instances.

        The kl_divergence between two Laplace distribution is

        .. math::
            KL\_divergence(\mu_0, \sigma_0; \mu_1, \sigma_1) = 0.5 (ratio^2 + (\frac{diff}{\sigma_1})^2 - 1 - 2 \ln {ratio})

        .. math::
            ratio = \frac{\sigma_0}{\sigma_1}

        .. math::
            diff = \mu_1 - \mu_0

        In the above equation:

        * :math:`loc = \mu`: is the location parameter of self.
        * :math:`scale = \sigma`: is the scale parameter of self.
        * :math:`loc = \mu_1`: is the location parameter of the reference Laplace distribution.
        * :math:`scale = \sigma_1`: is the scale parameter of the reference Laplace distribution.
        * :math:`ratio`: is the ratio between the two distribution.
        * :math:`diff`: is the difference between the two distribution.

        Args:
            other (Laplace): An instance of Laplace.

        Returns:
            Tensor: The kl-divergence between two laplace distributions.

        Examples:
            .. code-block:: python

                >>> import paddle

                >>> m1 = paddle.distribution.Laplace(paddle.to_tensor([0.0]), paddle.to_tensor([1.0]))
                >>> m2 = paddle.distribution.Laplace(paddle.to_tensor([1.0]), paddle.to_tensor([0.5]))
                >>> m1.kl_divergence(m2)
                Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                        [1.04261160])
        r<   )r   r   r8   r   expr7   )r$   r]   	var_ratiotterm1term2s         r&   kl_divergencezLaplace.kl_divergence  ss    R K$*,	Jtx%)+,,fj!dj999A=L
9%%u}q  r'   )r   r   r   r   r   r   )r   r   )r1   r   r   r2   )r1   r   r   r   )r   rI   r   r   )r   rV   )r]   r
   r   r   )__name__
__module____qualname____doc____annotations__r#   propertyr*   r,   r0   r5   r:   r=   rC   rH   rN   rM   rS   rd   __classcell__)r%   s   @r&   r
   r
      s         > KKKMMM) ) ) ) ) )<    X % % % X%" " " " X""! ! ! !:"; "; "; ";H. . . .6% % % %N K  K  K  KD -/ ' ' ' ' '0 .0 
 
 
 
 
B   (.! .! .! .! .! .! .! .!r'   r
   )
__future__r   r   typingr   numpyrW   r   paddle.baser   paddle.distributionr   collections.abcr   r   Distributionr
   r   r'   r&   <module>rs      s    # " " " " "                   ! ! ! ! ! ! , , , , , , ((((((N! N! N! N! N!l' N! N! N! N! N!r'   