o
    pi                     @  sr   d dl mZ d dlmZ d dlmZ d dlZd dlmZm	Z	 er&d dlm
Z
 G dd de	jZd	d
 Zdd ZdS )    )annotations)Iterable)TYPE_CHECKINGN)categoricaldistribution)Tensorc                      s   e Zd ZU dZded< ded< d fdd	Zedd
dZedddZdddZ	dddZ
g fdddZdddZd ddZ  ZS )!Multinomiala$  
    Multinomial distribution parameterized by :attr:`total_count` and
    :attr:`probs`.

    In probability theory, the multinomial distribution is a generalization of
    the binomial distribution, it models the probability of counts for each side
    of a k-sided die rolled n times. When k is 2 and n is 1, the multinomial is
    the bernoulli distribution, when k is 2 and n is grater than 1, it is the
    binomial distribution, when k is grater than 2 and n is 1, it is the
    categorical distribution.

    The probability mass function (PMF) for multinomial is

    .. math::

        f(x_1, ..., x_k; n, p_1,...,p_k) = \frac{n!}{x_1!...x_k!}p_1^{x_1}...p_k^{x_k}

    where, :math:`n` is number of trials, k is the number of categories,
    :math:`p_i` denote probability of a trial falling into each category,
    :math:`{\textstyle \sum_{i=1}^{k}p_i=1}, p_i \ge 0`, and :math:`x_i` denote
    count of each category.

    Args:
        total_count (int): Number of trials.
        probs (Tensor): Probability of a trial falling into each category. Last
            axis of probs indexes over categories, other axes index over batches.
            Probs value should between [0, 1], and sum to 1 along last axis. If
            the value over 1, it will be normalized to sum to 1 along the last
            axis.

    Examples:

    .. code-block:: python

        >>> import paddle
        >>> paddle.seed(2023)
        >>> multinomial = paddle.distribution.Multinomial(10, paddle.to_tensor([0.2, 0.3, 0.5]))
        >>> print(multinomial.sample((2, 3)))
        Tensor(shape=[2, 3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[[1., 5., 4.],
              [0., 4., 6.],
              [1., 3., 6.]],
            [[2., 2., 6.],
              [0., 6., 4.],
              [3., 3., 4.]]])
    inttotal_countr   probsreturnNonec                   s   t |tr	|dk rtd| dk rtd||jddd | _|| _tj| 	|d| _
t |jd d |jdd   d S )N   zBinput parameter total_count must be int type and grater than zero.z9probs parameter should not be none and over one dimensionT)Zkeepdim)logits)
isinstancer	   
ValueErrordimsumr   r
   r   ZCategorical_probs_to_logits_categoricalsuper__init__shape)selfr
   r   	__class__ f/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/paddle/distribution/multinomial.pyr   M   s   &zMultinomial.__init__c                 C  s   | j | j S )z\mean of multinomial distribution.

        Returns:
            Tensor: mean value.
        )r   r
   r   r   r   r   mean`   s   zMultinomial.meanc                 C  s   | j | j d| j  S )zdvariance of multinomial distribution.

        Returns:
            Tensor: variance value.
        r   )r
   r   r   r   r   r   variancei   s   zMultinomial.variancevaluec                 C  s   t | |S )probability mass function evaluated at value.

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

        Returns:
            Tensor: probability of value.
        )paddleexplog_prob)r   r"   r   r   r   probr   s   	zMultinomial.probc                 C  s   t |rt || jj}t t | j|g\}}t  r*d||dkt |@ < nt j	
||dkt |@ d}t |dd t |d d || d S )r#   r   r   r   )r$   
is_integercastr   dtypeZbroadcast_tensorslogZin_dynamic_modeisinfZstaticsetitemlgammar   )r   r"   r   r   r   r   r&   }   s    
	zMultinomial.log_probr   Iterable[int]c                 C  sR   t |ts	td| j| jgt|}tjj	
|| jjd | jjdS )zdraw sample data from multinomial distribution

        Args:
            sample_shape (list|tuple, optional): [description]. Defaults to [].
        z%sample shape must be Iterable object.r   r   )r   r   	TypeErrorr   sampler
   listr$   nnZ
functionalZone_hotr   r   r)   r*   r   )r   r   Zsamplesr   r   r   r1      s   

zMultinomial.samplec                 C  s   t jg | j| jjd}t j| jd | jjdddt| jj  dd }t 	| 
||}|| j  t |d  |t |d  ddg S )	z`entropy of multinomial distribution

        Returns:
            Tensor: entropy value
        )r   Z
fill_valuer*   r   r*   )r   )r   Nr   r   )r$   fullr
   r   r*   arangeZreshapelenr   r%   _binomial_logpmfr   entropyr.   r   )r   nZsupportZbinomial_pmfr   r   r   r9      s   zMultinomial.entropycountc              	   C  s~   | j | jdd}t|d }t|d }t|| d }|t| |ttt|   | }|| | | | S )NT)Z	is_binaryr   )r   r   r$   r.   _clip_by_zerolog1pr%   abs)r   r;   r"   r   Zfactor_nZfactor_kZ
factor_nmkZnormr   r   r   r8      s   
zMultinomial._binomial_logpmf)r
   r	   r   r   r   r   )r   r   )r"   r   r   r   )r   r/   r   r   )r;   r   r"   r   r   r   )__name__
__module____qualname____doc____annotations__r   propertyr    r!   r'   r&   r1   r9   r8   __classcell__r   r   r   r   r      s   
 /


r   c                 C  s   t j| d |dS )Nr   r4   )r$   r6   )r;   r*   r   r   r   _binomial_support   s   rF   c                 C  s    | j dd|  | j dd d S )Nr   )min)max   )Zclip)xr   r   r   r<      s    r<   )
__future__r   collections.abcr   typingr   r$   Zpaddle.distributionr   r   r   Distributionr   rF   r<   r   r   r   r   <module>   s    3