o
    "j                     @   sJ   d dl mZ d dlZd dlmZmZ G dd dejZdd Zdd	 Z	dS )
    )IterableN)categoricaldistributionc                       sb   e Zd ZdZ fddZedd Zedd Zdd	 Zd
d Z	dddZ
dd Z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.]]])
    c                    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 shoule not be none and over one dimensionT)Zkeepdim)logits)
isinstanceint
ValueErrordimsumprobstotal_countr   ZCategorical_probs_to_logits_categoricalsuper__init__shape)selfr   r   	__class__ `/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/distribution/multinomial.pyr   E   s   &zMultinomial.__init__c                 C   s   | j | j S )z[mean of multinomial distribuion.

        Returns:
            Tensor: mean value.
        )r   r   r   r   r   r   meanX   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   variancea   s   zMultinomial.variancec                 C   s   t | |S )zprobability mass function evaluated at value.

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

        Returns:
            Tensor: probability of value.
        )paddleexplog_prob)r   valuer   r   r   probj   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 )zprobability mass function evaluated at value

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

        Returns:
            Tensor: probability of value.
        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   u   s    
	zMultinomial.log_probr   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 (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   r*      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   r2      s   zMultinomial.entropyc              	   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   countr    r   Zfactor_nZfactor_kZ
factor_nmkZnormr   r   r   r1      s   
zMultinomial._binomial_logpmf)r   )__name__
__module____qualname____doc__r   propertyr   r   r!   r   r*   r2   r1   __classcell__r   r   r   r   r      s    /


r   c                 C   s   t j| d |dS )Nr   r-   )r   r/   )r7   r$   r   r   r   _binomial_support   s   r>   c                 C   s    | j dd|  | j dd d S )Nr   )min)max   )Zclip)xr   r   r   r4      s    r4   )
collections.abcr   r   Zpaddle.distributionr   r   Distributionr   r>   r4   r   r   r   r   <module>   s    5