o
    Me%                     @   s   d dl mZ d dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
 d dlmZmZmZmZ d dlmZmZmZ d dlmZmZmZmZmZmZmZmZ d dlmZmZm Z m!Z! G d	d
 d
e"Z#dS )    )print_functionN)_C_ops_legacy_C_ops)core)check_dtype
check_typecheck_variable_and_dtypeconvert_dtype)_non_static_modein_dygraph_mode_in_legacy_dygraph)control_flowelementwise_addelementwise_divelementwise_mulelementwise_subnnopstensor)arangeconcat	gather_ndmultinomialc                       s   e Zd ZdZd( fdd	Zedd Zedd Zed	d
 Zedd Z	d)ddZ
d)ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd*d$d%Zd*d&d'Z  ZS )+Distributiona>  
    The abstract base class for probability distributions. Functions are
    implemented in specific distributions.

    Args:
        batch_shape(Sequence[int], optional):  independent, not identically
            distributed draws, aka a "collection" or "bunch" of distributions.
        event_shape(Sequence[int], optional): the shape of a single
            draw from the distribution; it may be dependent across dimensions.
            For scalar distributions, the event shape is []. For n-dimension
            multivariate distribution, the event shape is [n].
     c                    sB   t |tr|nt|| _t |tr|nt|| _tt|   d S )N)
isinstancetuple_batch_shape_event_shapesuperr   __init__)selfbatch_shapeevent_shape	__class__r   PD:\Projects\ConvertPro\env\Lib\site-packages\paddle/distribution/distribution.pyr    E   s   zDistribution.__init__c                 C      | j S )zeReturns batch shape of distribution

        Returns:
            Sequence[int]: batch shape
        )r   r!   r   r   r&   r"   T      zDistribution.batch_shapec                 C   r'   )zeReturns event shape of distribution

        Returns:
            Sequence[int]: event shape
        )r   r(   r   r   r&   r#   ]   r)   zDistribution.event_shapec                 C      t )zMean of distributionNotImplementedErrorr(   r   r   r&   meanf      zDistribution.meanc                 C   r*   )zVariance of distributionr+   r(   r   r   r&   variancek   r.   zDistribution.variancec                 C   r*   )zSampling from the distribution.r+   r!   shaper   r   r&   samplep      zDistribution.samplec                 C   r*   )zreparameterized sampler+   r0   r   r   r&   rsamplet   r3   zDistribution.rsamplec                 C   r*   )z The entropy of the distribution.r+   r(   r   r   r&   entropyx   r3   zDistribution.entropyc                 C   r*   )z7The KL-divergence between self distributions and other.r+   )r!   otherr   r   r&   kl_divergence|   r3   zDistribution.kl_divergencec                 C   s   |  | S )zProbability density/mass function evaluated at value.

        Args:
            value (Tensor): value which will be evaluated
        )log_probexpr!   valuer   r   r&   prob   s   zDistribution.probc                 C   r*   )z&Log probability density/mass function.r+   r:   r   r   r&   r8      r3   zDistribution.log_probc                 C   r*   )zProbability density/mass function.

        Note:

            This method will be deprecated in the future, please use `prob`
            instead.
        r+   r:   r   r   r&   probs   s   zDistribution.probsc                 C   s   || j  | j S )zcompute shape of the sample

        Args:
            sample_shape (Tensor): sample shape

        Returns:
            Tensor: generated sample data shape
        )r   r   )r!   Zsample_shaper   r   r&   _extend_shape   s   	zDistribution._extend_shapec                 G   s<   d}d}|D ]}t |tjrd}qd}q|r|rtd|S )z
        Argument validation for distribution args
        Args:
            value (float, list, numpy.ndarray, Tensor)
        Raises
            ValueError: if one argument is Tensor, all arguments should be Tensor
        FTz9if one argument is Tensor, all arguments should be Tensor)r   r   Variable
ValueError)r!   argsZis_variableZ	is_numberargr   r   r&   _validate_args   s   zDistribution._validate_argsc                 G   s   g }g }d}|D ]E}t |tr|g}t |tttjtjfs&td	t
|t|}|j}t|dkrDt|dkr?td |d}|| }|| q|j}|D ]}t||\}	}
tj|d}t|	| || qSt|S )z
        Argument convert args to Tensor

        Args:
            value (float, list, numpy.ndarray, Tensor)
        Returns:
            Tensor of args.
        g        zUType of input args must be float, list, numpy.ndarray or Tensor, but received type {}float32float64zadata type of argument only support float32 and float64, your argument will be convert to float32.dtype)r   floatlistr   npZndarrayr   r?   	TypeErrorformattypearrayrG   strwarningswarnZastypeappendZbroadcast_arraysZcreate_tensorZassign)r!   rA   Z
numpy_argsZvariable_argstmprB   Zarg_npZ	arg_dtyperG   Zarg_broadcasted_Zarg_variabler   r   r&   
_to_tensor   s:   	


zDistribution._to_tensorc                 C   s   t  r/|j|jkr-t|jdv r-td t rt||jS t r-t	|d|jd|jS |S t
|dddgd |j|jkrKtd tj||jd	S |S )
a  
        Log_prob and probs methods have input ``value``, if value's dtype is different from param,
        convert value's dtype to be consistent with param's dtype.

        Args:
            param (Tensor): low and high in Uniform class, loc and scale in Normal class.
            value (Tensor): The input tensor.

        Returns:
            value (Tensor): Change value's dtype if value's dtype is different from param.
        )rD   rE   ztdtype of input 'value' needs to be the same as parameters of distribution class. dtype of 'value' will be converted.Zin_dtypeZ	out_dtyper;   rD   rE   r8   rF   )r
   rG   r	   rP   rQ   r   r   castr   r   r   r   )r!   paramr;   r   r   r&   _check_values_dtype_in_probs   s*   z)Distribution._check_values_dtype_in_probsFc                 C   s$   |rt |t |  S t |S )a  
        Converts probabilities into logits. For the binary, probs denotes the
        probability of occurrence of the event indexed by `1`. For the
        multi-dimensional, values of last axis denote the probabilities of
        occurrence of each of the events.
        )paddleloglog1p)r!   r=   	is_binaryr   r   r&   _probs_to_logits  s
   	zDistribution._probs_to_logitsc                 C   s$   |r	t jj|S t jjj|ddS )z
        Converts logits into probabilities. For the binary, each value denotes
        log odds, whereas for the multi-dimensional case, the values along the
        last dimension denote the log probabilities of the events.
        )Zaxis)rY   r   Z
functionalZsigmoidZsoftmax)r!   Zlogitsr\   r   r   r&   _logits_to_probs  s
   zDistribution._logits_to_probs)r   r   )r   )F)__name__
__module____qualname____doc__r    propertyr"   r#   r-   r/   r2   r4   r5   r7   r<   r8   r=   r>   rC   rU   rX   r]   r_   __classcell__r   r   r$   r&   r   7   s0    






.
&r   )$
__future__r   mathrP   numpyrJ   rY   r   r   Zpaddle.fluidr   Zpaddle.fluid.data_feederr   r   r   r	   Zpaddle.fluid.frameworkr
   r   r   Zpaddle.fluid.layersr   r   r   r   r   r   r   r   Zpaddle.tensorr   r   r   r   objectr   r   r   r   r&   <module>   s   (
