Ë
    ˆ\;j%/  ã                   ó’   — 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	ej"                  «      Zy)
é    N)ÚIterable)Ú
check_typeÚconvert_dtype)ÚVariable)Údistribution)Úin_dynamic_mode)Úrandomc                   ól   ‡ — e Zd ZdZdˆ fd„	Zed„ «       Zed„ «       Zdd„Zdd„Z	d„ Z
d„ Zd	„ Zd
„ Zˆ x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])
    c           
      óü  •— t        «       slt        |dt        t        t        j
                  t        t        t        fd«       t        |dt        t        t        j
                  t        t        t        fd«       d| _	        |�|nd| _
        d| _        t        |t        «      rt        |«      }t        |t        «      rt        |«      }| j                  ||«      r*|| _        || _        t!        |j                  «      | _        �nWt        |t        «      rt        |t        «      rd| _	        t        |t        j
                  «      r)t#        |j                  «      dv r|j                  | _        nBt        |t        j
                  «      r(t#        |j                  «      dv r|j                  | _        | j%                  ||«      \  | _        | _        | j                  t!        | j                  j                  «      k7  r`t'        j(                  | j                  | j                  ¬«      | _        t'        j(                  | j                  | j                  ¬«      | _        t*        ‰| �Y  | j                  j.                  «       y )	NÚlocr   ÚscaleFÚfloat32T)r   Úfloat64©Údtype)r   r   ÚintÚfloatÚnpÚndarrayr   ÚlistÚtupleÚall_arg_is_floatÚnamer   Ú
isinstanceÚ_validate_argsr   r   r   ÚstrÚ
_to_tensorÚpaddleÚcastÚsuperÚ__init__Úshape)Úselfr   r   r   Ú	__class__s       €úcG:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\paddle/distribution/normal.pyr"   zNormal.__init__a   s¿  ø€ ÜÔ ÜØØÜ”eœRŸZ™Z¬´4¼Ð?Øô	ô ØØÜ”eœRŸZ™Z¬´4¼Ð?Øô	ð !&ˆÔØ Ð,‘D°(ˆŒ	ØˆŒ
ä�cœ3ÔÜ˜“*ˆCÜ�eœSÔ!Ü˜%“LˆEà×Ñ˜s EÔ*ØˆDŒHØˆDŒJÜ& s§y¡yÓ1ˆDŽJä˜#œuÔ%¬*°U¼EÔ*BØ(,�Ô%Ü˜#œrŸz™zÔ*¬s°3·9±9«~ð Bñ 0ð !ŸY™Y�•
Ü˜E¤2§:¡:Ô.´3°u·{±{Ó3Cð Hñ 4ð #Ÿ[™[�”
Ø#'§?¡?°3¸Ó#>Ñ ˆDŒH�d”jØ�z‰zœ]¨4¯8©8¯>©>Ó:Ò:Ü!Ÿ;™; t§x¡x°t·z±zÔB�”Ü#Ÿ[™[¨¯©¸4¿:¹:ÔF�”
Ü‰Ñ˜Ÿ™Ÿ™Õ(ó    c                 ó   — | j                   S )z[Mean of multinomial distribuion.

        Returns:
            Tensor: mean value.
        )r   ©r$   s    r&   ÚmeanzNormal.mean�   s   € ð �x‰xˆr'   c                 ó8   — | j                   j                  d«      S )zbVariance of lognormal distribution.

        Returns:
            Tensor: variance value.
        é   )r   Úpowr)   s    r&   ÚvariancezNormal.variance™   s   € ð �z‰z�~‰~˜aÓ Ð r'   c                 ó6  — t        |t        «      st        d«      ‚t        «       st	        |dt
        d«       t        |«      }t        | j                  | j                  z   j                  «      }| j                  dz   }d|v rù||z   }t        ||z   «      }t        j                  | j                  | j                  z   «      d   j                  «       |d<   t        j                  |d| j                  «      }t        j                  ||«      }t        j                  |«      }	t!        j"                  |	dd|| j                  ¬	«      }
|
|| j                  z   z  }t        j$                  || j                  |¬
«      }|S ||z   }t!        j"                  |dd|| j                  ¬	«      t        j&                  || j                  ¬«      | j                  z   z  }t        j$                  || j                  |¬
«      }| j(                  rt        j                  |||¬
«      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Ú_sampleéÿÿÿÿr   ç        ç      ð?)r*   Ústdr1   r   ©r   r   )r   r   Ú	TypeErrorr   r   r   r   r   r   r#   r   r   ÚitemÚfullr   Úreshaper	   ÚgaussianÚaddÚzerosr   )r$   r#   r1   Úbatch_shaper   Úoutput_shapeÚ
fill_shapeÚzero_tmpÚzero_tmp_reshapeÚzero_tmp_shapeÚnormal_random_tmpÚoutputs               r&   r2   zNormal.sample¢   s¶  € ô ˜%¤Ô*ÜÐCÓDÐDäÔ Ü�t˜V¤c¨HÔ5ä�U“ˆÜ˜DŸH™H t§z¡zÑ1×8Ñ8Ó9ˆØ�y‰y˜9Ñ$ˆØ�ÑØ  ;Ñ.ˆLÜ˜k¨EÑ1Ó2ˆJÜ"ŸL™L¨¯©°D·J±JÑ)>Ó?ÀÑB×GÑGÓIˆJ�q‰MÜ—{‘{ :¨s°D·J±JÓ?ˆHÜ%Ÿ~™~¨h¸ÓEÐä#Ÿ\™\Ð*:Ó;ˆNÜ &§¡Ø S¨c¸ÀDÇJÁJô!Ðð 'Ð*:¸T¿Z¹ZÑ*GÑHˆFÜ—Z‘Z ¨¯©°tÔ<ˆFØˆMà  ;Ñ.ˆLÜ—_‘_Ø 3¨C°dÀ$Ç*Á*ôä—‘˜l°$·*±*Ô=ÀÇ
Á
ÑJñLˆFô —Z‘Z ¨¯©°tÔ<ˆFØ×$Ò$Ü—~‘~ f¨e¸$Ô?Ð?à�r'   c                 óÐ   — t        |t        «      st        d«      ‚| j                  t	        |«      «      }t        j                  |¬«      }| j                  || j                  z  z   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.

        r0   )r#   )	r   r   r9   Ú_extend_shaper   r   Únormalr   r   )r$   r#   Úepss      r&   ÚrsamplezNormal.rsampleÏ   sT   € ô ˜%¤Ô*ÜÐCÓDÐDà×"Ñ"¤5¨£<Ó0ˆÜ�m‰m %Ô(ˆØ�x‰x˜# §
¡
Ñ*Ñ*Ð*r'   c                 ó˜  — | j                   dz   }t        | j                  | j                  z   j                  «      }d|v r†t        |«      }t        j                  | j                  | j                  z   «      d   j                  «       |d<   | j                  | j                  z   j                  }t        j                  |d|«      }n!t        j                  |d| j                  «      }t        j                  d|z   dt        j                  dt        j                  z  «      z  t        j                  | j                  |z   «      z   |¬«      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.

        Ú_entropyr4   r   r5   ç      à?r,   r8   )r   r   r   r   r#   r   r:   r   r;   r>   ÚmathÚlogÚpi)r$   r   r@   rB   Ú
fill_dtyperC   s         r&   ÚentropyzNormal.entropyà   sù   € ð" �y‰y˜:Ñ%ˆÜ˜DŸH™H t§z¡zÑ1×8Ñ8Ó9ˆØ�ÑÜ˜kÓ*ˆJÜ"ŸL™L¨¯©°D·J±JÑ)>Ó?ÀÑB×GÑGÓIˆJ�q‰MØŸ(™( T§Z¡ZÑ/×6Ñ6ˆJÜ—{‘{ :¨s°JÓ?‰Hä—{‘{ ;°°T·Z±ZÓ@ˆHÜ�z‰zØ�(‰NØ”$—(‘(˜1œtŸw™w™;Ó'Ñ'¬&¯*©*°T·Z±ZÀ(Ñ5JÓ*KÑKØô
ð 	
r'   c           
      ó¸  — | j                   dz   }| j                  | j                  |«      }| j                  | j                  z  }t	        j
                  | j                  «      }t	        j                  d|| j                  z
  || j                  z
  z  z  d|z  z  |t        j
                  t        j                  dt        j                  z  «      «      z   |¬«      S )zÊLog probability density/mass function.

        Args:
          value (Tensor): The input tensor.

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

        Ú	_log_probç      ð¿ç       @r8   )
r   Ú_check_values_dtype_in_probsr   r   r   rQ   ÚsubtractrP   ÚsqrtrR   )r$   Úvaluer   ÚvarÚ	log_scales        r&   Úlog_probzNormal.log_prob   sª   € ð �y‰y˜;Ñ&ˆØ×1Ñ1°$·(±(¸EÓBˆà�j‰j˜4Ÿ:™:Ñ%ˆÜ—J‘J˜tŸz™zÓ*ˆ	Ü�‰Ø�U˜TŸX™XÑ%¨%°$·(±(Ñ*:Ñ;Ñ<ÀÀcÁ	ÑJØœŸ™¤§¡¨3´·±©=Ó!9Ó:Ñ:Øô
ð 	
r'   c                 óŽ  — | j                   dz   }| j                  | j                  |«      }| j                  | j                  z  }t	        j
                  t	        j                  d|| j                  z
  || j                  z
  z  z  d|z  z  «      t        j                  dt        j                  z  «      | j                  z  |¬«      S )zÇProbability density/mass function.

        Args:
            value (Tensor): The input tensor.

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

        Ú_probsrW   rX   r,   r8   )
r   rY   r   r   r   ÚdivideÚexprP   r[   rR   )r$   r\   r   r]   s       r&   ÚprobszNormal.probs  s¡   € ð �y‰y˜8Ñ#ˆØ×1Ñ1°$·(±(¸EÓBˆà�j‰j˜4Ÿ:™:Ñ%ˆÜ�}‰}Ü�J‰JØ˜ §¡Ñ)¨e°d·h±hÑ.>Ñ?Ñ@ÀCÈ#ÁIÑNóô �Y‰Y�qœ4Ÿ7™7‘{Ó# d§j¡jÑ0Øô
ð 	
r'   c                 óX  — t        «       st        |dt        d«       | j                  dz   }| j                  |j                  z  }||z  }| j
                  |j
                  z
  |j                  z  }||z  }t        j                  d|z  d|dz
  t        j                  |«      z
  z  |¬«      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_divergenceÚ_kl_divergencerO   r6   r8   )	r   r   r   r   r   r   r   r>   rQ   )r$   rf   r   Ú	var_ratioÚt1s        r&   rg   zNormal.kl_divergence+  s›   € ôB Ô Ü�u˜g¤v¨Ô?à�y‰yÐ+Ñ+ˆØ—J‘J §¡Ñ,ˆ	Ø 	Ñ)ˆ	Ø�h‰h˜Ÿ™Ñ" e§k¡kÑ1ˆØ�"‰WˆÜ�z‰zØ�)‰O˜S B¨¡H¬v¯z©z¸)Ó/DÑ$DÑEÈDô
ð 	
r'   )N)© r   )rk   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r"   Úpropertyr*   r.   r2   rL   rT   r_   rd   rg   Ú__classcell__)r%   s   @r&   r   r      sX   ø„ ñBõH-)ð^ ñó ðð ñ!ó ð!ó+óZ+ò"
ò@
ò*
ö,+
r'   r   )rP   Úcollections.abcr   Únumpyr   r   Úpaddle.base.data_feederr   r   Úpaddle.base.frameworkr   Úpaddle.distributionr   Úpaddle.frameworkr   Úpaddle.tensorr	   ÚDistributionr   rk   r'   r&   Ú<module>rz      s6   ðó Ý $ã ã ß =Ý *Ý ,Ý ,Ý  ôz
ˆ\×&Ñ&õ z
r'   