
    zj,<                    x    d dl mZ d dlmZ d dlmZ d dlZd dlmZ erd dlm	Z	m
Z
  G d dej                  ZdS )	    )annotations)Sequence)TYPE_CHECKINGN)distribution)Tensordtypec                       e Zd ZU dZded<   ded<   ded<   	 dd  fdZd!dZd"dZd"dZd#dZ	d"dZ
ed"d            Zed"d            Zg fd$dZg fd$dZd#dZd#dZd"dZd#dZd#dZd%dZ xZS )&ContinuousBernoullia   The Continuous Bernoulli distribution with parameter: `probs` characterizing the shape of the density function.
    The Continuous Bernoulli distribution is defined on [0, 1], and it can be viewed as a continuous version of the Bernoulli distribution.

    `The continuous Bernoulli: fixing a pervasive error in variational autoencoders. <https://arxiv.org/abs/1907.06845>`_

    Mathematical details

    The probability density function (pdf) is

    .. math::

        p(x;\lambda) = C(\lambda)\lambda^x (1-\lambda)^{1-x}

    In the above equation:

    * :math:`x`: is continuous between 0 and 1
    * :math:`probs = \lambda`: is the probability.
    * :math:`C(\lambda)`: is the normalizing constant factor

    .. math::

        C(\lambda) =
        \left\{
        \begin{aligned}
        &2 & \text{ if $\lambda = \frac{1}{2}$} \\
        &\frac{2\tanh^{-1}(1-2\lambda)}{1 - 2\lambda} & \text{ otherwise}
        \end{aligned}
        \right.

    Args:
        probs(int|float|Tensor): The probability of Continuous Bernoulli distribution between [0, 1],
            which characterize the shape of the pdf. If the input data type is int or float, the data type of
            `probs` will be convert to a 1-D Tensor the paddle global default dtype.
        lims(tuple): Specify the unstable calculation region near 0.5, where the calculation is approximated
            by talyor expansion. The default value is (0.499, 0.501).

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> from paddle.distribution import ContinuousBernoulli
            >>> paddle.set_device("cpu")
            >>> paddle.seed(100)

            >>> rv = ContinuousBernoulli(paddle.to_tensor([0.2, 0.5]))

            >>> print(rv.sample([2]))
            Tensor(shape=[2, 2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[0.38694882, 0.20714243],
             [0.00631948, 0.51577556]])

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

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

            >>> print(rv.entropy())
            Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [-0.07641457,  0.        ])

            >>> print(rv.cdf(paddle.to_tensor(0.1)))
            Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [0.17259926, 0.10000000])

            >>> print(rv.icdf(paddle.to_tensor(0.1)))
            Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [0.05623737, 0.10000000])

            >>> rv1 = ContinuousBernoulli(paddle.to_tensor([0.2, 0.8]))
            >>> rv2 = ContinuousBernoulli(paddle.to_tensor([0.7, 0.5]))
            >>> print(rv1.kl_divergence(rv2))
            Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [0.20103608, 0.07641447])
    r   probslimsr   gV-?gx&1?float | Tensortuple[float]returnNonec                   t          j                    | _        |                     |          | _        t          j        || j                  | _        t          j        | j        j                  j        }t          j	        | j        |d|z
            | _        | j        j
        }t                                          |           d S )Nr      )minmax)paddleget_default_dtyper   
_to_tensorr   	to_tensorr   finfoepsclipshapesuper__init__)selfr   r   eps_probbatch_shape	__class__s        x/lsinfo/ai/hellotax_ai/data_center/backend/venv/lib/python3.11/site-packages/paddle/distribution/continuous_bernoulli.pyr    zContinuousBernoulli.__init__n   s     -//
__U++
$T<<<	 <
 0115[q8|LLL
j&%%%%%    c                    t          |t          t          f          rt          j        |g| j                  }n|j        | _        |S )zoConvert the input parameters into tensors

        Returns:
            Tensor: converted probability.
        r   )
isinstancefloatintr   r   r   )r!   r   s     r%   r   zContinuousBernoulli._to_tensor|   sC     eeS\** 	%$eWDJ???EEDJr&   c                    t          j        t          j        | j        | j        d                   t          j        | j        | j        d                             S )zGenerate stable support region indicator (prob < self.lims[0] && prob >= self.lims[1] )

        Returns:
            Tensor: the element of the returned indicator tensor corresponding to stable region is True, and False otherwise
        r   r   )r   
logical_or
less_equalr   r   greater_thanr!   s    r%   _cut_support_regionz'ContinuousBernoulli._cut_support_region   sI      dj$)A,77
DIaL99
 
 	
r&   c                    t          j        |                                 | j        | j        d         t          j        | j                  z            S )zCut the probability parameter with stable support region

        Returns:
            Tensor: the element of the returned probability tensor corresponding to unstable region is set to be self.lims[0], and unchanged otherwise
        r   )r   wherer0   r   r   	ones_liker/   s    r%   
_cut_probszContinuousBernoulli._cut_probs   sG     |$$&&JIaL6+DJ777
 
 	
r&   valuec                \    dt          j        |          t          j        |           z
  z  S )zCalculate the tanh inverse of value

        Args:
            value (Tensor)

        Returns:
            Tensor: tanh inverse of value
              ?)r   log1pr!   r5   s     r%   _tanh_inversez!ContinuousBernoulli._tanh_inverse   s*     fl5))FL%,@,@@AAr&   c           
     x   |                                  }t          j        d| j                  }t          j        t          j        ||          |t          j        |                    }t          j        t          j        ||          |t          j        |                    }t          j	        dt          j
        |                     dd|z  z
                      z            t          j        t          j        ||          t          j        d|z            t          j	        d|z  dz
                      z
  }t          j        | j        dz
            }t          j	        t          j        d| j                            dd|z  z   |z  z   }t          j        |                                 ||          S )zCalculate the logarithm of the constant factor :math:`C(lambda)` in the pdf of the Continuous Bernoulli distribution

        Returns:
            Tensor: logarithm of the constant factor
        r7   r          @      ?g       gUUUUUU?g'}'}@)r4   r   r   r   r2   r-   
zeros_likegreater_equalr3   logabsr:   r8   squarer   r0   )r!   	cut_probshalfcut_probs_below_halfcut_probs_above_halflog_constant_proposextaylor_expansions           r%   _log_constantz!ContinuousBernoulli._log_constant   s    OO%%	4:666%|i..i(( 
  

  &| D11Y'' 
  

  &z&*T//cIo0EFFGGG 
  
Li..L 4455Js11C788
 
 
 M$*s*++Jv'4:>>>??<!++q01 	 |$$&&(<>N
 
 	
r&   c           
        |                                  }t          j        |d|z  dz
            }|t          j        t          j        d| j                  d|                     dd|z  z
            z            z   }| j        dz
  }dddt          j        |          z  z   |z  z   }t          j        | 	                                ||          S )zeMean of Continuous Bernoulli distribution.

        Returns:
            Tensor: mean value.
        r<   r=   r   r7   gUUUUUU?gll?)
r4   r   divider   r   r:   r   rB   r2   r0   r!   rC   tmpproposerH   rI   s         r%   meanzContinuousBernoulli.mean   s     OO%%	mIsY'<==S
333$$$S3?%:;;;
 
 
 J9{V]1-=-===BB 	 |$$&&1A
 
 	
r&   c           
     
   |                                  }t          j        ||dz
  z  t          j        dd|z  z
                      }|t          j        t          j        d| j                  t          j        t          j        |           t          j        |          z
                      z   }t          j        | j        dz
            }ddd|z  z
  |z  z
  }t          j	        | 
                                ||          S )zmVariance of Continuous Bernoulli distribution.

        Returns:
            Tensor: variance value.
        r=   r<   r   r7   gUUUUUU?g?ggjV?)r4   r   rL   rB   r   r   r8   r@   r   r2   r0   rM   s         r%   variancezContinuousBernoulli.variance   s     OO%%	mS)M#i/00
 
 S
333M&,	z22VZ	5J5JJKK
 
 
 M$*s*++%ma6G)G1(LL|$$&&1A
 
 	
r&   r   Sequence[int]c                    t          j                    5  |                     |          cddd           S # 1 swxY w Y   dS )C  Generate Continuous Bernoulli samples of the specified shape. The final shape would be ``sample_shape + batch_shape``.

        Args:
            shape (Sequence[int], optional): Prepended shape of the generated samples.

        Returns:
            Tensor, Sampled data with shape `sample_shape` + `batch_shape`.
        N)r   no_gradrsample)r!   r   s     r%   samplezContinuousBernoulli.sample   s     ^ 	' 	'<<&&	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	's   6::c                   t          |t                    st          d          t          |          }t          | j                  }t          ||z             }t          j        || j        dd          }|                     |          S )rU   z%sample shape must be Sequence object.r   r   )r   r   r   r   )	r(   r   	TypeErrortupler#   r   uniformr   icdf)r!   r   r#   output_shapeus        r%   rW   zContinuousBernoulli.rsample  s}     %** 	ECDDDeD,--U[011NTZQANNNyy||r&   c                T   t          j        || j                  }t          j        | j        j                  j        }t          j        |t          j        | j                  z  d|z
  t          j        d| j        z
            z  z   |           }|                                 |z   S )zLog probability density function.

        Args:
          value (Tensor): The input tensor.

        Returns:
          Tensor: log probability. The data type is the same as `self.probs`.
        r   r=   r   )neginf)	r   castr   r   r   r   
nan_to_numr@   rJ   )r!   r5   r   cross_entropys       r%   log_probzContinuousBernoulli.log_prob  s     E444l4:+,,0)FJtz***U{fjTZ88894
 
 

 !!##m33r&   c                P    t          j        |                     |                    S )zProbability density function.

        Args:
            value (Tensor): The input tensor.

        Returns:
            Tensor: probability. The data type is the same as `self.probs`.
        )r   expre   r9   s     r%   probzContinuousBernoulli.prob'  s      z$--..///r&   c           	     n   t          j        | j                  }t          j        | j                   }t          j        t          j        | j        t          j        d| j                            t          j        | j        d          | 	                                 | j
        ||z
  z  z   |z
            S )a  Shannon entropy in nats.

        The entropy is

        .. math::

            \mathcal{H}(X) = -\log C + \left[ \log (1 - \lambda) -\log \lambda \right] \mathbb{E}(X)  - \log(1 - \lambda)

        In the above equation:

        * :math:`\Omega`: is the support of the distribution.

        Returns:
            Tensor, Shannon entropy of Continuous Bernoulli distribution.
        r7   r           )r   r@   r   r8   r2   equalr   r   	full_likerJ   rP   )r!   log_plog_1_minus_ps      r%   entropyzContinuousBernoulli.entropy2  s      
4:&&dj[11|LV%5c%L%L%LMMTZ--##%%%)}u456 	
 
 	
r&   c                |   t          j        || j                  }|                                 }t          j        ||          t          j        d|z
  d|z
            z  |z   dz
  d|z  dz
  z  }t          j        |                                 ||          }t          j        t          j        |t          j        d| j                            t          j	        |          t          j        t          j
        |t          j        d| j                            t          j        |          |                    S )a>  Cumulative distribution function

        .. math::

            {   P(X \le t; \lambda) =
                F(t;\lambda) =
                \left\{
                \begin{aligned}
                &t & \text{ if $\lambda = \frac{1}{2}$} \\
                &\frac{\lambda^t (1 - \lambda)^{1 - t} + \lambda - 1}{2\lambda - 1} & \text{ otherwise}
                \end{aligned}
                \right. }

        Args:
            value (Tensor): The input tensor.

        Returns:
            Tensor: quantile of :attr:`value`. The data type is the same as `self.probs`.
        r   r=   r<   rj   )r   rb   r   r4   powr2   r0   r-   r   r>   r?   r3   )r!   r5   rC   cdfsunbounded_cdfss        r%   cdfzContinuousBernoulli.cdfO  s)   ( E444OO%%	Jy%((jy#+667  9_s"$  d&>&>&@&@$NN|eV%5c%L%L%LMMe$$L$6+CtzBBB   '' 

 

 
	
r&   c           	     p   t          j        || j                  }|                                 }t          j        |                                 t          j        | |d|z  dz
  z  z             t          j        |           z
  t          j        |          t          j        |           z
  z  |          S )af  Inverse cumulative distribution function

        .. math::

            {   F^{-1}(x;\lambda) =
                \left\{
                \begin{aligned}
                &x & \text{ if $\lambda = \frac{1}{2}$} \\
                &\frac{\log(1+(\frac{2\lambda - 1}{1 - \lambda})x)}{\log(\frac{\lambda}{1-\lambda})} & \text{ otherwise}
                \end{aligned}
                \right. }

        Args:
            value (Tensor): The input tensor, meaning the quantile.

        Returns:
            Tensor: the value of the r.v. corresponding to the quantile. The data type is the same as `self.probs`.
        r   r<   r=   )r   rb   r   r4   r2   r0   r8   r@   )r!   r5   rC   s      r%   r]   zContinuousBernoulli.icdfx  s    & E444OO%%	|$$&&iZ%3?S3H*IIJJ,	z**+ z)$$v|YJ'?'??	A
 
 
 	
r&   otherc                &   | j         |j         k    rt          d          |                                  }t          j        |j                  }t          j        |j                   }|                                | j        ||z
  z  z   |z    }||z   S )a  The KL-divergence between two Continuous Bernoulli distributions with the same `batch_shape`.

        The probability density function (pdf) is

        .. math::

            KL\_divergence(\lambda_1, \lambda_2) = - H - \{\log C_2 + [\log \lambda_2 -  \log (1-\lambda_2)]  \mathbb{E}_1(X) +  \log (1-\lambda_2)  \}

        Args:
            other (ContinuousBernoulli): instance of Continuous Bernoulli.

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

        z\KL divergence of two Continuous Bernoulli distributions should share the same `batch_shape`.)	r#   
ValueErrorro   r   r@   r   r8   rJ   rP   )r!   rv   part1log_qlog_1_minus_qpart2s         r%   kl_divergencez!ContinuousBernoulli.kl_divergence  s    " u000n   
5;''ek\22!!i5=012

 u}r&   )r   )r   r   r   r   r   r   )r   r   r   r   )r   r   )r5   r   r   r   )r   rS   r   r   )rv   r
   r   r   )__name__
__module____qualname____doc____annotations__r    r   r0   r4   r:   rJ   propertyrP   rR   rX   rW   re   rh   ro   rt   r]   r}   __classcell__)r$   s   @r%   r
   r
      s        L L\ MMMLLLLLL ;I& & & & & & &   	
 	
 	
 	


 

 

 

	B 	B 	B 	B 
  
  
  
D 
 
 
 X
( 
 
 
 X
* -/ 
' 
' 
' 
' 
' .0     "4 4 4 4$	0 	0 	0 	0
 
 
 
:'
 '
 '
 '
R
 
 
 
>       r&   r
   )
__future__r   collections.abcr   typingr   r   paddle.distributionr   r   r   Distributionr
    r&   r%   <module>r      s    # " " " " " $ $ $ $ $ $              , , , , , , %$$$$$$$$Y Y Y Y Y,3 Y Y Y Y Yr&   