o
    Me                     @   s\   d dl Z d dlmZ d dlmZ d dlmZmZ d dlm	Z	 G dd dej
Zd
dd	ZdS )    N)exponential_family)check_variable_and_dtype)in_dygraph_mode_in_legacy_dygraph)LayerHelperc                       sn   e Zd ZdZ fddZedd Zedd Zdd	d
Zdd Z	dd Z
dd Zedd Zdd Z  ZS )	Dirichleta  
    Dirichlet distribution with parameter "concentration".

    The Dirichlet distribution is defined over the `(k-1)-simplex` using a 
    positive, lenght-k vector concentration(`k > 1`).
    The Dirichlet is identically the Beta distribution when `k = 2`.

    For independent and identically distributed continuous random variable 
    :math:`\boldsymbol X \in R_k` , and support 
    :math:`\boldsymbol X \in (0,1), ||\boldsymbol X|| = 1` , 
    The probability density function (pdf) is

    .. math::
    
        f(\boldsymbol X; \boldsymbol \alpha) = \frac{1}{B(\boldsymbol \alpha)} \prod_{i=1}^{k}x_i^{\alpha_i-1} 

    where :math:`\boldsymbol \alpha = {\alpha_1,...,\alpha_k}, k \ge 2` is 
    parameter, the normalizing constant is the multivariate beta function.

    .. math::

        B(\boldsymbol \alpha) = \frac{\prod_{i=1}^{k} \Gamma(\alpha_i)}{\Gamma(\alpha_0)}

    :math:`\alpha_0=\sum_{i=1}^{k} \alpha_i` is the sum of parameters, 
    :math:`\Gamma(\alpha)` is gamma function.

    Args:
        concentration (Tensor): "Concentration" parameter of dirichlet 
            distribution, also called :math:`\alpha`. When it's over one 
            dimension, the last axis denotes the parameter of distribution,
            ``event_shape=concentration.shape[-1:]`` , axes other than last are
            condsider batch dimensions with ``batch_shape=concentration.shape[:-1]`` .

    Examples:

        .. code-block:: python

            import paddle

            dirichlet = paddle.distribution.Dirichlet(paddle.to_tensor([1., 2., 3.]))

            print(dirichlet.entropy())
            # Tensor(shape=[1], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
            #        [-1.24434423])
            print(dirichlet.prob(paddle.to_tensor([.3, .5, .6])))
            # Tensor(shape=[1], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
            #        [10.80000114])

    c                    sD   |  dk r
td|| _tt| |jd d |jdd   d S )N   z:`concentration` parameter must be at least one dimensional)dim
ValueErrorconcentrationsuperr   __init__shape)selfr   	__class__ MD:\Projects\ConvertPro\env\Lib\site-packages\paddle/distribution/dirichlet.pyr   I   s   zDirichlet.__init__c                 C   s   | j | j jddd S )zbMean of Dirichelt distribution.

        Returns:
            Mean value of distribution.
        r	   TZkeepdim)r   sumr   r   r   r   meanR   s   zDirichlet.meanc                 C   s2   | j jddd}| j || j   |d|d   S )zjVariance of Dirichlet distribution.

        Returns:
            Variance value of distribution.
        r	   Tr      r   )r   r   pow)r   concentration0r   r   r   variance[   s   zDirichlet.variancer   c                 C   s,   t |tr|nt|}t| j| |S )zSample from dirichlet distribution.

        Args:
            shape (Sequence[int], optional): Sample shape. Defaults to empty tuple.
        )
isinstancetuple
_dirichletr   expandZ_extend_shape)r   r   r   r   r   samplef   s   zDirichlet.samplec                 C   s   t | |S )zProbability density function(PDF) evaluated at value.

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

        Returns:
            PDF evaluated at value.
        )paddleexplog_probr   valuer   r   r   probo   s   	zDirichlet.probc                 C   s>   t || jd  dt | jd t | jd S )zpLog of probability densitiy function.

        Args:
            value (Tensor): Value to be evaluated.
              ?r	   )r"   logr   r   lgammar%   r   r   r   r$   z   s
   zDirichlet.log_probc                 C   sb   | j d}| j jd }t| j dt| || t|  | j d t| j  d S )zbEntropy of Dirichlet distribution.

        Returns:
            Entropy of distribution.
        r	   r(   )r   r   r   r"   r*   Zdigamma)r   r   kr   r   r   entropy   s   
zDirichlet.entropyc                 C   s   | j fS N)r   r   r   r   r   _natural_parameters   s   zDirichlet._natural_parametersc                 C   s   |  dt |d S )Nr	   )r*   r   r"   )r   xr   r   r   _log_normalizer   s   zDirichlet._log_normalizer)r   )__name__
__module____qualname____doc__r   propertyr   r   r!   r'   r$   r,   r.   r0   __classcell__r   r   r   r   r      s    2	



	

r   c                 C   sx   d}t | dddg| t rtj| S t rtj| S t|fi t }|j	| j
d}|j|d| id|ii d |S )	N	dirichletr   Zfloat32Zfloat64)dtypeAlphaZOut)typeZinputsZoutputsattrs)r   r   r"   Z_C_opsr7   r   Z_legacy_C_opsr   localsZ"create_variable_for_type_inferencer8   Z	append_op)r   nameZop_typehelperoutr   r   r   r      s$   r   r-   )r"   Zpaddle.distributionr   Zpaddle.fluid.data_feederr   Zpaddle.fluid.frameworkr   r   Zpaddle.fluid.layer_helperr   ZExponentialFamilyr   r   r   r   r   r   <module>   s    