
    zj,#                        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	 d dl
mZ  G d d	ej                  ZdS )
    )annotations)Sequence)TYPE_CHECKINGN)distribution)Tensor)_DTypeLiteralc                       e Zd ZU dZded<   ded<   ded<   d fdZddZedd            Zedd            Z	g fddZ
ddZddZddZddZddZ xZS ) Binomiala  
    The Binomial distribution with size `total_count` and `probs` parameters.

    In probability theory and statistics, the binomial distribution is the most basic discrete probability distribution defined on :math:`[0, n] \cap \mathbb{N}`,
    which can be viewed as the number of times a potentially unfair coin is tossed to get heads, and the result
    of its random variable can be viewed as the sum of a series of independent Bernoulli experiments.

    The probability mass function (pmf) is

    .. math::

        pmf(x; n, p) = \frac{n!}{x!(n-x)!}p^{x}(1-p)^{n-x}

    In the above equation:

    * :math:`total\_count = n`: is the size, meaning the total number of Bernoulli experiments.
    * :math:`probs = p`: is the probability of the event happening in one Bernoulli experiments.

    Args:
        total_count(int|Tensor): The size of Binomial distribution which should be greater than 0, meaning the number of independent bernoulli
            trials with probability parameter :math:`p`. The data type will be converted to 1-D Tensor with paddle global default dtype if the input
            :attr:`probs` is not Tensor, otherwise will be converted to the same as :attr:`probs`.
        probs(float|Tensor): The probability of Binomial distribution which should reside in [0, 1], meaning the probability of success
            for each individual bernoulli trial. If the input data type is float, it will be converted to a 1-D Tensor with paddle global default dtype.

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> from paddle.distribution import Binomial
            >>> paddle.set_device('cpu')
            >>> paddle.seed(100)
            >>> rv = Binomial(100, paddle.to_tensor([0.3, 0.6, 0.9]))

            >>> print(rv.sample([2]))
            Tensor(shape=[2, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[31., 62., 93.],
             [29., 54., 91.]])

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

            >>> print(rv.entropy())
            Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [2.94053698, 3.00781751, 2.51124287])
    r   dtyper   total_countprobsint | Tensorfloat | TensorreturnNonec                    t          j                    | _        |                     ||          \  | _        | _        | j        j        }t                                          |           d S )N)	paddleget_default_dtyper   
_to_tensorr   r   shapesuper__init__)selfr   r   batch_shape	__class__s       l/lsinfo/ai/hellotax_ai/data_center/backend/venv/lib/python3.11/site-packages/paddle/distribution/binomial.pyr   zBinomial.__init__Q   s[     -//
'+{E'J'J$$*&,%%%%%    list[Tensor]c                @   t          |t                    rt          j        || j                  }n|j        | _        t          |t
                    rt          j        || j                  }nt          j        || j                  }t          j        ||g          S )zConvert the input parameters into Tensors if they were not and broadcast them

        Returns:
            list[Tensor]: converted total_count and probs.
        r   )
isinstancefloatr   	to_tensorr   intcastbroadcast_tensors)r   r   r   s      r   r   zBinomial._to_tensorZ   s     eU## 	%$U$*===EEDJk3'' 	E *;djIIIKK +kDDDK 'e(<===r   c                     | j         | j        z  S )zYMean of binomial distribution.

        Returns:
            Tensor: mean value.
        r   r   r   s    r   meanzBinomial.meano   s     $*,,r   c                6    | j         | j        z  d| j        z
  z  S )zaVariance of binomial distribution.

        Returns:
            Tensor: variance value.
           r(   r)   s    r   variancezBinomial.variancex   s     $*,DJ??r   r   Sequence[int]c                   t          |t                    st          d          t          j        d          5  t          |          }t          | j                  }t          ||z             }t          j        | j        |          }t          j        | j	        |          }t          j
        t          j        |d          |          }t          j        || j                  cddd           S # 1 swxY w Y   dS )a^  Generate binomial samples of the specified shape. The final shape would be ``shape+batch_shape`` .

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

        Returns:
            Tensor: Sampled data with shape `sample_shape` + `batch_shape`. The returned data type is the same as `probs`.
        z%sample shape must be Sequence object.F)r   int32r    N)r!   r   	TypeErrorr   set_grad_enabledtupler   broadcast_tor   r   binomialr%   r   )r   r   r   output_shapeoutput_sizeoutput_probsamples          r   r9   zBinomial.sample   s8    %** 	ECDDD$U++ 	3 	3%LLE 011K !455L -   K !-djMMMK_Kw777 F ;vtz22	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3s   B.C44C8;C8c                    |                                  }|                     |          }t          j        |          |z                      d           S )ae  Shannon entropy in nats.

        The entropy is

        .. math::

            \mathcal{H}(X) = - \sum_{x \in \Omega} p(x) \log{p(x)}

        In the above equation:

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

        Returns:
            Tensor: Shannon entropy of binomial distribution. The data type is the same as `probs`.
        r   )_enumerate_supportlog_probr   expsum)r   valuesr<   s      r   entropyzBinomial.entropy   sL      ((**==((H%%055a8888r   c                    t          j        dt          j        | j                  z   | j                  }|                    ddt          | j                  z  z             }|S )zReturn the support of binomial distribution [0, 1, ... ,n]

        Returns:
            Tensor: the support of binomial distribution
        r,   r    ))r,   )r   arangemaxr   r   reshapelenr   )r   r?   s     r   r;   zBinomial._enumerate_support   s`     
4+,,,DJ
 
 
 s43C/D/D(D DEEr   valuec                   t          j        || j                  }t          j        | j        dz             t          j        | j        |z
  dz             z
  t          j        |dz             z
  }t          j        | j        j                  j        }t          j        | j        |d|z
            }t          j	        ||t          j
        |          z  z   | j        |z
  t          j
        d|z
            z  z   |           S )zLog probability density/mass function.

        Args:
            value (Tensor): The input tensor.

        Returns:
            Tensor: log probability. The data type is the same as `probs`.
        r    g      ?r,   )minrD   )neginf)r   r%   r   lgammar   finfor   epsclip
nan_to_numlog)r   rG   log_combrM   r   s        r   r<   zBinomial.log_prob   s     E444 M$*S011mD,u4s:;;<mECK(() 	
 l4:+,,0DJCQW=== &*U+++,#e+vz!e)/D/DDE 4
 
 
 	
r   c                P    t          j        |                     |                    S )zProbability density/mass function.

        Args:
            value (Tensor): The input tensor.

        Returns:
            Tensor: probability. The data type is the same as `probs`.
        )r   r=   r<   )r   rG   s     r   probzBinomial.prob   s      z$--..///r   otherc                   |                                  }|                     |          }|                    |          }t          j        t          j        |          t          j        ||                                        d          S )av  The KL-divergence between two binomial distributions with the same :attr:`total_count`.

        The probability density function (pdf) is

        .. math::

            KL\_divergence(n_1, p_1, n_2, p_2) = \sum_x p_1(x) \log{\frac{p_1(x)}{p_2(x)}}

        .. math::

            p_1(x) = \frac{n_1!}{x!(n_1-x)!}p_1^{x}(1-p_1)^{n_1-x}

        .. math::

            p_2(x) = \frac{n_2!}{x!(n_2-x)!}p_2^{x}(1-p_2)^{n_2-x}

        Args:
            other (Binomial): instance of ``Binomial``.

        Returns:
            Tensor: kl-divergence between two binomial distributions. The data type is the same as `probs`.

        r   )r;   r<   r   multiplyr=   subtractr>   )r   rT   support
log_prob_1
log_prob_2s        r   kl_divergencezBinomial.kl_divergence   st    0 ))++]]7++
^^G,,
O
:&&Z88  #a&&	r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   )r   r.   r   r   )rG   r   r   r   )rT   r
   r   r   )__name__
__module____qualname____doc____annotations__r   r   propertyr*   r-   r9   r@   r;   r<   rS   r[   __classcell__)r   s   @r   r
   r
      sG        . .` MMM& & & & & &> > > >* - - - X- @ @ @ X@ -/ 3 3 3 3 329 9 9 9(
 
 
 

 
 
 
:	0 	0 	0 	0               r   r
   )
__future__r   collections.abcr   typingr   r   paddle.distributionr   r   paddle._typing.dtype_liker   Distributionr
    r   r   <module>rj      s    # " " " " " $ $ $ $ $ $              , , , , , , 8777777f f f f f|( f f f f fr   