o
    pi{E                     @  sl  U d dl mZ d dlZd dlmZmZ d dlmZ d dlZ	d dl
m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 erd d
lmZ d dlmZ d dlmZmZ d dlmZ eee f Z!de"d< ee	j#e	j$e	j%e	j&f Z'de"d< ee!ee! ee! ej(e' ef Z)de"d< eeee ee ej(ee	j#e	j$f  ef Z*de"d< G dd dej+Z,dS )    )annotationsN)IterableSequence)TYPE_CHECKING)
check_typeconvert_dtype)Variable)distribution)in_dynamic_mode)random)Union)	TypeAlias)Tensordtype)NestedSequencer   _NormalLocBase_NormalLocNDArray
_NormalLoc_NormalScalec                      s   e Zd ZU dZded< ded< ded< ded< 	d'd( fddZed)ddZed)ddZg dfd*ddZ	g fd+ddZ
d)ddZd,d d!Zd,d"d#Zd-d%d&Z  ZS ).Normala  The Normal distribution with location `loc` and `scale` parameters.

    Mathematical details

    If 'loc' is real number, 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}

    If 'loc' is complex number, the probability density function (pdf) is

    .. math::

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

    .. math::

        Z = \pi \sigma^2

    In the above equations:

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

    Args:
        loc(int|float|complex|list|tuple|numpy.ndarray|Tensor): The mean of normal distribution.The data type is float32, float64, complex64 and complex128.
        scale(int|float|list|tuple|numpy.ndarray|Tensor): The std of normal distribution.The data type is float32 and float64.
        name(str|None, 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])
    r   locscalestrnamer   Nr   r   
str | NonereturnNonec                   sB  t  s&t|dttttjttj	j
ttfd t|dtttjttj	j
ttfd d| _|d ur/|nd| _d| _d| _t|trAt|}t|trJt|}t|ttfrlt|}|jtjkra|d}|jtjkrl|d}t|ttfr{tj|tjd}t|tst|tjr|jtjtjfv s| |r%| r%d| _t|trt|trd| _t|tjr|jtjkrdnd	}|jtjkrdnd	}t|j|}t|j|}t||| _n t|trtj|jdd}tj|jdd}t||| _n|| _t|tjrtj||jd| _nt|trtj|dd| _n|| _t| jj| _nr| ||r9|| _|| _t|j| _n^t|trHt|trHd| _t|tjr\t |jd
v r\|j| _nt|tjrot |jd
v ro|j| _| !||\| _| _| jt| jjkrtj"| j| jd| _tj"| j| jd| _t# $| jj% d S )Nr   r   r   Ffloat32	complex64r   Tfloat64)r   r    )&r
   r   intfloatcomplexnpZndarrayr   paddleZpirValuelisttupleall_arg_is_floatr   r   _complex_gaussian
isinstancearrayr    Zastype
complex128r   r   Z_validate_argsZ
is_complexZ	to_tensorrealimagr   r   r   r   Z
_to_tensorcastsuper__init__shape)selfr   r   r   Z
real_dtypeZ
imag_dtyper.   r/   	__class__ a/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/paddle/distribution/normal.pyr2      s   
	







zNormal.__init__c                 C  s   | j S )zWMean of normal distribution.

        Returns:
            Tensor: mean value.
        )r   r4   r7   r7   r8   mean  s   zNormal.meanc                 C  s   | j dS )z_Variance of normal distribution.

        Returns:
            Tensor: variance value.
           )r   powr9   r7   r7   r8   variance
  s   zNormal.variancer   r3   Sequence[int]seedr!   c                 C  sX  t |ts	tdt st|dtd t|}t| j| j j	}| j
d }d|v rw|| }t|| }t	| j| j d  |d< t|d| j}t||}t	|}	tj|	| jr]dndd	|| jd
}
|
|| j  }tj|| j|d}|S || }tj|| jrdn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.r?   sampleZ_sampler                                 ?)r:   Zstdr?   r   r   r   )r+   r   	TypeErrorr
   r   r!   r'   r   r   r3   r   r%   itemfullr   Zreshaper   Zgaussianr*   addZzerosr)   )r4   r3   r?   batch_shaper   Zoutput_shape
fill_shapezero_tmpZzero_tmp_reshapeZzero_tmp_shapeZnormal_random_tmpoutputr7   r7   r8   rA     sL   


zNormal.samplec                 C  sH   t |ts	td| t|}tj| jrdnd|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@   rD   rC   )r:   r3   )
r+   r   rG   Z_extend_shaper(   r%   normalr*   r   r   )r4   r3   Zepsr7   r7   r8   rsampleH  s   

zNormal.rsamplec                 C  s:  | j d }t| j| j j}| jrUd|v r4t|}t| j| j d  |d< | jj}t	|d|}n	t	|d| jj}tj
d| ttjdt| j|   |dS d|v r{t|}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.

        If non-complex, the entropy is

        .. math::

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

        If complex gaussian, the entropy is

        .. math::

            entropy(\sigma) = \log (\pi e \sigma^2) + 1

        In the above equation:

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

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

        Z_entropyrB   r   rC   rE          @rF         ?r;   )r   r'   r   r   r3   r*   r%   rH   r   rI   rJ   mathlogpi)r4   r   rK   rL   Z
fill_dtyperM   r7   r7   r8   entropy[  s2   
"zNormal.entropyvaluec              	   C  s   | j d }| | j|}| j| j }t| j}| jr9tjd|| j  || j   | d| t	t	j
 |dS 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      rQ   rF   )r   _check_values_dtype_in_probsr   r   r%   rT   r*   subtractconjrS   rU   sqrt)r4   rW   r   varZ	log_scaler7   r7   r8   log_prob  s   

zNormal.log_probc                 C  s   | j d }| | j|}| j| j }| jr1tjtd|| j  || j   | t	j
| |dS 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_probsrX   rF   rQ   r;   )r   rY   r   r   r*   r%   divideexpr[   rS   rU   r\   )r4   rW   r   r]   r7   r7   r8   probs  s4   


zNormal.probsotherc                 C  s   t  s
t|dtd | j|jkrtd| jd }| j|j }|| }| j|j |j }| jr@| | }|| d t	
| S || }t	jd| d|d t	
|  |dS )a  The KL-divergence between two normal distributions.

        If non-complex, the KL-divergence 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})

        If complex gaussian:

        .. math::

            KL\_divergence(\mu_0, \sigma_0; \mu_1, \sigma_1) = 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.

        rb   kl_divergencezVThe kl divergence must be computed between two distributions in the same number field.Z_kl_divergencerE   rR   rF   )r
   r   r   r*   
ValueErrorr   r   r   r[   r%   rT   rJ   )r4   rb   r   Z	var_ratiot1r7   r7   r8   rc     s&   '
zNormal.kl_divergence)N)r   r   r   r   r   r   r   r   )r   r   )r3   r>   r?   r!   r   r   )r3   r>   r   r   )rW   r   r   r   )rb   r   r   r   )__name__
__module____qualname____doc____annotations__r2   propertyr:   r=   rA   rP   rV   r^   ra   rc   __classcell__r7   r7   r5   r8   r   :   s$   
 Ns5

5
#r   )-
__future__r   rS   collections.abcr   r   typingr   numpyr$   Znumpy.typingZnptr%   Zpaddle.base.data_feederr   r   Zpaddle.base.frameworkr   Zpaddle.distributionr	   Zpaddle.frameworkr
   Zpaddle.tensorr   r   Ztyping_extensionsr   r   r   Zpaddle._typingr   r"   r#   r   rj   r   r    r   r-   r   ZNDArrayr   r   Distributionr   r7   r7   r7   r8   <module>   sL   	