o
    "j-                     @   sz   d dl Z d dlm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 d dlmZ d dlmZ G dd	 d	ejZdS )
    N)Iterable)
check_typeconvert_dtype)Variable)distribution)in_dynamic_mode)randomc                       sn   e Zd ZdZd f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  ZS )Normala
  The Normal distribution with location `loc` and `scale` parameters.

    Mathematical details

    The probability density function (pdf) is

    .. math::

        pdf(x; \mu, \sigma) = \frac{1}{Z}e^{\frac {-0.5 (x - \mu)^2}  {\sigma^2} }

    .. math::

        Z = (2 \pi \sigma^2)^{0.5}

    In the above equation:

    * :math:`loc = \mu`: is the mean.
    * :math:`scale = \sigma`: is the std.
    * :math:`Z`: is the normalization constant.

    Args:
        loc(int|float|list|tuple|numpy.ndarray|Tensor): The mean of normal distribution.The data type is float32 and float64.
        scale(int|float|list|tuple|numpy.ndarray|Tensor): The std of normal distribution.The data type is float32 and float64.
        name(str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> from paddle.distribution import Normal

            >>> # Define a single scalar Normal distribution.
            >>> dist = Normal(loc=0., scale=3.)
            >>> # Define a batch of two scalar valued Normals.
            >>> # The first has mean 1 and standard deviation 11, the second 2 and 22.
            >>> dist = Normal(loc=[1., 2.], scale=[11., 22.])
            >>> # Get 3 samples, returning a 3 x 2 tensor.
            >>> dist.sample([3])

            >>> # Define a batch of two scalar valued Normals.
            >>> # Both have mean 1, but different standard deviations.
            >>> dist = Normal(loc=1., scale=[11., 22.])

            >>> # Complete example
            >>> value_tensor = paddle.to_tensor([0.8], dtype="float32")

            >>> normal_a = Normal([0.], [1.])
            >>> normal_b = Normal([0.5], [2.])
            >>> sample = normal_a.sample([2])
            >>> # a random tensor created by normal distribution with shape: [2, 1]
            >>> entropy = normal_a.entropy()
            >>> print(entropy)
            Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                [1.41893852])
            >>> lp = normal_a.log_prob(value_tensor)
            >>> print(lp)
            Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                [-1.23893857])
            >>> p = normal_a.probs(value_tensor)
            >>> print(p)
            Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.28969154])
            >>> kl = normal_a.kl_divergence(normal_b)
            >>> print(kl)
            Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.34939718])
    Nc              	      sh  t  st|dtttjtttfd t|dtttjtttfd d| _	|d ur(|nd| _
d| _t|tr7t|}t|tr@t|}| ||rS|| _|| _t|j| _nWt|tr`t|tr`d| _	t|tjrrt|jdv rr|j| _nt|tjrt|jdv r|j| _| ||\| _| _| jt| jjkrtj| j| jd| _tj| j| jd| _t | jj d S )	Nlocr	   scaleFfloat32T)r   Zfloat64dtype)r   r   intfloatnpZndarrayr   listtupleall_arg_is_floatnamer   
isinstanceZ_validate_argsr
   r   r   strZ
_to_tensorpaddlecastsuper__init__shape)selfr
   r   r   	__class__ [/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/distribution/normal.pyr   a   sF   


zNormal.__init__c                 C   s   | j S )z[Mean of multinomial distribuion.

        Returns:
            Tensor: mean value.
        )r
   r   r    r    r!   mean   s   zNormal.meanc                 C   s   | j dS )zbVariance of lognormal distribution.

        Returns:
            Tensor: variance value.
           )r   powr"   r    r    r!   variance   s   zNormal.variancer    r   c                 C   sD  t |ts	tdt st|dtd t|}t| j| j j	}| j
d }d|v rr|| }t|| }t	| j| j d  |d< t|d| j}t||}t	|}	tj|	dd|| jd	}
|
|| j  }tj|| j|d
}|S || }tj|dd|| jd	tj|| jd| j  }tj|| j|d
}| jrtj|||d
S |S )a&  Generate samples of the specified shape.

        Args:
            shape (Sequence[int], optional): Shape of the generated samples.
            seed (int): Python integer number.

        Returns:
            Tensor, A tensor with prepended dimensions shape.The data type is float32.

        %sample shape must be Iterable object.seedsample_sampler                 ?)r#   Zstdr(   r   r   r   )r   r   	TypeErrorr   r   r   r   r
   r   r   r   r   itemfullr   Zreshaper   ZgaussianaddZzerosr   )r   r   r(   batch_shaper   Zoutput_shape
fill_shapezero_tmpZzero_tmp_reshapeZzero_tmp_shapeZnormal_random_tmpoutputr    r    r!   r)      s<   


zNormal.samplec                 C   s<   t |ts	td| t|}tj|d}| j|| j  S )a  Generate reparameterized samples of the specified shape.

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

        Returns:
          Tensor: A tensor with prepended dimensions shape.The data type is float32.

        r'   )r   )	r   r   r/   Z_extend_shaper   r   normalr
   r   )r   r   epsr    r    r!   rsample   s
   

zNormal.rsamplec                 C   s   | j d }t| j| j j}d|v r4t|}t| j| j d  |d< | j| j j}t|d|}nt|d| j}tj	d| dt
dt
j  t| j|  |dS )a>  Shannon entropy in nats.

        The entropy is

        .. math::

            entropy(\sigma) = 0.5 \log (2 \pi e \sigma^2)

        In the above equation:

        * :math:`scale = \sigma`: is the std.

        Returns:
            Tensor, Shannon entropy of normal distribution.The data type is float32.

        Z_entropyr+   r   r,         ?r$   r.   )r   r   r
   r   r   r   r0   r   r1   r2   mathlogpi)r   r   r3   r4   Z
fill_dtyper5   r    r    r!   entropy   s   
"zNormal.entropyc              	   C   sr   | j d }| | j|}| j| j }t| j}tjd|| j || j   d|  |ttdtj	  |dS )zLog probability density/mass function.

        Args:
          value (Tensor): The input tensor.

        Returns:
          Tensor: log probability.The data type is same with :attr:`value` .

        Z	_log_prob             @r.   )
r   _check_values_dtype_in_probsr
   r   r   r<   subtractr;   sqrtr=   )r   valuer   varZ	log_scaler    r    r!   log_prob   s   

zNormal.log_probc                 C   sh   | j d }| | j|}| j| j }tjtd|| j || j   d|  tdtj	 | j |dS )zProbability density/mass function.

        Args:
            value (Tensor): The input tensor.

        Returns:
            Tensor, probability. The data type is same with :attr:`value` .

        Z_probsr?   r@   r$   r.   )
r   rA   r
   r   r   divideexpr;   rC   r=   )r   rD   r   rE   r    r    r!   probs  s   

zNormal.probsc                 C   sr   t  s
t|dtd | jd }| j|j }|| }| j|j |j }|| }tjd| d|d t|  |dS )a  The KL-divergence between two normal distributions.

        The probability density function (pdf) is

        .. math::

            KL\_divergence(\mu_0, \sigma_0; \mu_1, \sigma_1) = 0.5 (ratio^2 + (\frac{diff}{\sigma_1})^2 - 1 - 2 \ln {ratio})

        .. math::

            ratio = \frac{\sigma_0}{\sigma_1}

        .. math::

            diff = \mu_1 - \mu_0

        In the above equation:

        * :math:`loc = \mu_0`: is the mean of current Normal distribution.
        * :math:`scale = \sigma_0`: is the std of current Normal distribution.
        * :math:`loc = \mu_1`: is the mean of other Normal distribution.
        * :math:`scale = \sigma_1`: is the std of other Normal distribution.
        * :math:`ratio`: is the ratio of scales.
        * :math:`diff`: is the difference between means.

        Args:
            other (Normal): instance of Normal.

        Returns:
            Tensor, kl-divergence between two normal distributions.The data type is float32.

        otherkl_divergenceZ_kl_divergencer:   r-   r.   )	r   r   r	   r   r   r
   r   r2   r<   )r   rJ   r   Z	var_ratiot1r    r    r!   rK   +  s   !
zNormal.kl_divergence)N)r    r   )r    )__name__
__module____qualname____doc__r   propertyr#   r&   r)   r9   r>   rF   rI   rK   __classcell__r    r    r   r!   r	      s    D/



- r	   )r;   collections.abcr   numpyr   r   Zpaddle.base.data_feederr   r   Zpaddle.base.frameworkr   Zpaddle.distributionr   Zpaddle.frameworkr   Zpaddle.tensorr   Distributionr	   r    r    r    r!   <module>   s   