Ë
    ˆ\;jÍ2  ã                   ó^   — d dl Z d dlZd dlZd dlmZ d dlmZ  G d„ dej                  «      Z	y)é    N)Ú	framework)Údistributionc                   óŠ   ‡ — e Zd ZdZˆ fd„Zed„ «       Zed„ «       Zed„ «       Zd„ Z	d„ Z
d„ Zd	„ Zd
„ Zdd„Zd„ Zd„ Z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)

    c                 ó  •— t        |t        j                  t        j                  f«      st        dt        |«      › �«      ‚t        |t        j                  t        j                  f«      st        dt        |«      › �«      ‚t        |t        j                  «      rt        j                  d|¬«      }t        |t        j                  «      rt        j                  d|¬«      }t        |j                  «      dkD  st        |j                  «      dkD  r>|j                  |j                  k(  r%t        j                  ||g«      \  | _        | _        n||c| _        | _        t        ‰| �A  | j                  j                  «       y )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Ú	TypeErrorÚtypeÚpaddleÚfullÚlenr
   ÚdtypeÚbroadcast_tensorsÚlocÚscaleÚsuperÚ__init__)Úselfr   r   Ú	__class__s      €údG:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\paddle/distribution/laplace.pyr   zLaplace.__init__8   s  ø€ Ü˜#¤§¡¬i×.@Ñ.@ÐAÔBÜØAÄ$ÀsÃ)ÀÐMóð ô ˜%¤'§,¡,´	×0BÑ0BÐ!CÔDÜØCÄDÈÃKÀ=ÐQóð ô �cœ7Ÿ<™<Ô(Ü—+‘+ B°3Ô7ˆCä�eœWŸ\™\Ô*Ü—K‘K b°UÔ;ˆEä�—‘Ó˜qÒ ¤C¨¯	©	£N°QÒ$6Ø�I‰I˜Ÿ™Ò$ä#)×#;Ñ#;¸SÀ%¸LÓ#IÑ ˆDŒH�d•jà#&¨Ð ˆDŒH�d”jä‰Ñ˜Ÿ™Ÿ™Õ(ó    c                 ó   — | j                   S )zTMean of distribution.

        Returns:
            Tensor: The mean value.
        )r   ©r   s    r   ÚmeanzLaplace.meanR   s   € ð �x‰xˆr   c                 ó    — d| j                   z  S )zýStandard 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.stddev[   s   € ð  ˜$Ÿ*™*Ñ$Ð$r   c                 ó8   — | j                   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.variancem   s   € ð  �{‰{�‰˜qÓ!Ð!r   c                 óR  — t        |t        j                  «      rt        j                  d|¬«      }|j
                  | j                  j
                  k7  r*t        j                  || j                  j
                  «      }t        | j                  j                  «      dkD  s:t        | j                  j                  «      dkD  st        |j                  «      dkD  r1t        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   Úvaluer   r   s       r   Ú_validate_valuezLaplace._validate_value   sØ   € ô �eœWŸ\™\Ô*Ü—K‘K b°UÔ;ˆEØ�;‰;˜$Ÿ*™*×*Ñ*Ò*Ü—K‘K  t§z¡z×'7Ñ'7Ó8ˆEä�—
‘
× Ñ Ó! AÒ%Ü�4—8‘8—>‘>Ó" QÒ&Ü�5—;‘;Ó !Ò#ä &× 8Ñ 8Ø—‘˜4Ÿ:™: uÐ-ó!ÑˆC�™ð Ÿ™ 4§:¡:�ˆCà�E˜5Ð Ð r   c                 óš   — | j                  |«      \  }}}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%   )r+   r   ÚlogÚabs)r   r*   r   r   Ú	log_scales        r   Úlog_probzLaplace.log_probš   sM   € ð> !×0Ñ0°Ó7ÑˆˆU�EÜ—Z‘Z  E¡	Ó*Ð*ˆ	àœ6Ÿ:™: e¨c¡kÓ2°UÑ:Ñ:Ð:r   c                 óL   — 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   r-   r   r    s    r   ÚentropyzLaplace.entropy¾   s    € ð2 ”6—:‘:˜a $§*¡*™nÓ-Ñ-Ð-r   c                 ó¸   — | j                  |«      \  }}}d||z
  j                  «       z  t        j                  ||z
  j	                  «        |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)
        ç      à?)r+   Úsignr   Úexpm1r.   )r   r*   r   r   Úiterms        r   ÚcdfzLaplace.cdfÙ   sj   € ð< !×0Ñ0°Ó7ÑˆˆU�EàØ�s‰{× Ñ Ó"ñ#ä�l‰l˜U S™[×-Ñ-Ó/Ð/°%Ñ7Ó8ñ9ð 	ð �U‰{Ðr   c                 ó°   — | j                  |«      \  }}}|dz
  }|||j                  «       z  t        j                  d|j	                  «       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)
        r5   éþÿÿÿ)r+   r6   r   Úlog1pr.   )r   r*   r   r   Úterms        r   ÚicdfzLaplace.icdf   sR   € ð: !×0Ñ0°Ó7ÑˆˆU�EØ�s‰{ˆà�U˜dŸ[™[›]Ñ*¬V¯\©\¸"¸t¿x¹x»z¹/Ó-JÑJÑJÐJr   c                 ó²   — t        |t        «      r|n
t        |«      }t        j                  «       5  | j	                  |«      cddd«       S # 1 sw Y   yxY w)az  Generate samples of the specified shape.

        Args:
            shape(tuple[int]): The shape of generated samples.

        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.sample"  s:   € ô& $ E¬5Ô1‘´u¸U³|ˆÜ�^‰^ÕØ—<‘< Ó&÷ ×Òús   ²AÁAc           	      óŽ  — | j                  «       }| j                  |«      }t        j                  |t	        t        j                  dd«      «      |dz  z   d|dz  z
  | j                  j                  ¬«      }| j                  | j                  |j                  «       z  t        j                  |j                  «        «      z  z
  S )az  Reparameterized sample.

        Args:
            shape(tuple[int]): The shape of generated samples.

        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]])
        éÿÿÿÿr2   r%   g      ð?)r
   ÚminÚmaxr   )Ú_get_epsÚ_extend_shaper   ÚuniformÚfloatÚnpÚ	nextafterr   r   r   r6   r<   r.   )r   r
   ÚepsrJ   s       r   rB   zLaplace.rsample9  s¡   € ð( �m‰m‹oˆØ×"Ñ" 5Ó)ˆÜ—.‘.ØÜ”b—l‘l 2 qÓ)Ó*¨S°1©WÑ4Ø�c˜A‘g‘Ø—(‘(—.‘.ô	
ˆð �x‰x˜$Ÿ*™* w§|¡|£~Ñ5¼¿¹Ø�[‰[‹]ˆNó9
ñ 
ñ 
ð 	
r   c                 óª   — 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   rN   s     r   rH   zLaplace._get_epsY  s=   € ð ˆà�H‰H�N‰NœfŸn™nÒ,Ø�x‰x�~‰~¤×!2Ñ!2Ò2àˆCàˆ
r   c                 óF  — |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])
        r2   )r   r   r.   r   Úexpr-   )r   ÚotherÚ	var_ratioÚtÚterm1Úterm2s         r   Úkl_divergencezLaplace.kl_divergencem  s~   € ðR —K‘K $§*¡*Ñ,ˆ	Ü�J‰J�t—x‘x %§)¡)Ñ+Ó,ˆØ—‘œfŸj™j¨!¨¨d¯j©j©Ó9Ñ9¸AÑ=ÀÇÁÑLˆÜ—
‘
˜9Ó%ˆà�u‰}˜qÑ Ð r   )r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úpropertyr!   r#   r'   r+   r0   r3   r9   r>   rC   rB   rH   rY   Ú__classcell__)r   s   @r   r   r      s{   ø„ ñô>)ð4 ñó ðð ñ%ó ð%ð" ñ"ó ð"ò"!ò6";òH.ò6%òN KóD'ò.
ò@ö(.!r   r   )
r   ÚnumpyrL   r   Úpaddle.baser   Úpaddle.distributionr   ÚDistributionr   r   r   r   Ú<module>rd      s*   ðó ã ã Ý !Ý ,ôC!ˆl×'Ñ'õ C!r   