Ë
    ˆ\;js5  ã                   ó~   — 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)Ú
check_typeÚconvert_dtype)ÚVariable)Údistribution)Úin_dynamic_mode)Úmultinomialc                   ó6   — e Zd ZdZd	d„Zd„ Zd„ Zd„ Zd„ Zd„ Z	y)
ÚCategoricala‘	  
    Categorical distribution is a discrete probability distribution that
    describes the possible results of a random variable that can take on
    one of K possible categories, with the probability of each category
    separately specified.

    The probability mass function (pmf) is:

    .. math::

        pmf(k; p_i) = \prod_{i=1}^{k} p_i^{[x=i]}

    In the above equation:

    * :math:`[x=i]` : it evaluates to 1 if :math:`x==i` , 0 otherwise.

    Args:
        logits(list|tuple|numpy.ndarray|Tensor): The logits input of categorical distribution. The data type is float32 or 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 Categorical

            >>> paddle.seed(100) # on CPU device
            >>> x = paddle.rand([6])
            >>> print(x)
            Tensor(shape=[6], dtype=float32, place=Place(cpu), stop_gradient=True,
            [0.55355281, 0.20714243, 0.01162981, 0.51577556, 0.36369765, 0.26091650])

            >>> paddle.seed(200) # on CPU device
            >>> y = paddle.rand([6])
            >>> print(y)
            Tensor(shape=[6], dtype=float32, place=Place(cpu), stop_gradient=True,
            [0.77663314, 0.90824795, 0.15685187, 0.04279523, 0.34468332, 0.79557180])

            >>> cat = Categorical(x)
            >>> cat2 = Categorical(y)

            >>> paddle.seed(1000) # on CPU device
            >>> print(cat.sample([2,3]))
            Tensor(shape=[2, 3], dtype=int64, place=Place(cpu), stop_gradient=True,
            [[0, 1, 5],
            [3, 4, 5]])

            >>> print(cat.entropy())
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            1.77528250)

            >>> print(cat.kl_divergence(cat2))
            Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
            [0.07195196])

            >>> value = paddle.to_tensor([2,1,3])
            >>> print(cat.probs(value))
            Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [0.00608027, 0.10829761, 0.26965630])

            >>> print(cat.log_prob(value))
            Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [-5.10270691, -2.22287226, -1.31060708])
    Nc                 óÔ  — t        «       s,t        |dt        j                  t        t
        t        fd«       |�|nd| _        d| _        | j                  |«      r"|| _
        t        |j                  «      | _        n·t        |t        j                  «      r(t        |j                  «      dv r|j                  | _        | j                  |«      d   | _
        | j                  t        | j                  j                  «      k7  r0t        j                   | j                  | j                  ¬«      | _
        t        j"                  | j                  dd	¬
«      }| j                  |z  | _        y)a1  
        Args:
            logits(list|tuple|numpy.ndarray|Tensor): The logits input of categorical distribution. The data type is float32 or float64.
            name(str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.
        Úlogitsr
   NÚfloat32)r   Úfloat64r   )ÚdtypeéÿÿÿÿT©ÚaxisÚkeepdim)r   r   ÚnpÚndarrayr   ÚlistÚtupleÚnamer   Ú_validate_argsr   r   Ú
isinstanceÚstrÚ
_to_tensorÚpaddleÚcastÚsumÚ_prob)Úselfr   r   Údist_sums       úhG:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\paddle/distribution/categorical.pyÚ__init__zCategorical.__init__[   s  € ô Ô ÜØØÜ—‘œX¤t¬UÐ3Øô	ð !Ð,‘D°-ˆŒ	ØˆŒ
à×Ñ˜vÔ&Ø ˆDŒKÜ& v§|¡|Ó4ˆD�Jä˜&¤"§*¡*Ô-´#°f·l±lÓ2Cð Hñ 3ð $Ÿ\™\�”
ØŸ/™/¨&Ó1°!Ñ4ˆDŒKØ�z‰zœ]¨4¯;©;×+<Ñ+<Ó=Ò=Ü$Ÿk™k¨$¯+©+¸T¿Z¹ZÔH�”Ü—:‘:˜dŸk™k°¸DÔAˆØ—[‘[ 8Ñ+ˆ�
ó    c                 ó¶  — | j                   dz   }t        «       st        |dt        d«       t	        j
                  t	        j                  |«      «      }t        | j                  j                  «      }t        |«      dkD  rD||dd z   }t        j                  | j                  t	        j
                  |dd «      |d   g«      }n|}| j                  }t        | j                  |«      |d«      }t        t        |j                  «       «      «      }|j!                  d|j#                  d«      «       |j%                  |«      }t        j                  |||¬	«      S )
aÒ  Generate samples of the specified shape.

        Args:
            shape (list): Shape of the generated samples.

        Returns:
            Tensor: A tensor with prepended dimensions shape.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Categorical

                >>> paddle.seed(100) # on CPU device
                >>> x = paddle.rand([6])
                >>> print(x)
                Tensor(shape=[6], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.55355281, 0.20714243, 0.01162981, 0.51577556, 0.36369765, 0.26091650])

                >>> # doctest: +SKIP
                >>> cat = Categorical(x)
                >>> paddle.seed(1000) # on CPU device
                >>> print(cat.sample([2,3]))
                Tensor(shape=[2, 3], dtype=int64, place=Place(cpu), stop_gradient=True,
                [[0, 1, 5],
                [3, 4, 5]])
        Ú_sampleÚshapeÚsampleé   Nr   Tr   ©r   )r   r   r   r   r   ÚprodÚarrayr   r(   Úlenr   Úreshaper   Ú_logits_to_probsÚrangeÚdimÚinsertÚpopÚ	transpose)	r!   r(   r   Únum_samplesÚlogits_shapeÚsample_shaper   Úsample_indexÚpermutes	            r#   r)   zCategorical.sample{   s  € ð: �y‰y˜9Ñ$ˆÜÔ Ü�u˜g¬¨xÔ8ä—g‘gœbŸh™h u›oÓ.ˆä˜DŸK™K×-Ñ-Ó.ˆÜˆ|Ó˜qÒ Ø  <°°Ð#4Ñ4ˆLÜ—^‘^Ø—‘œbŸg™g l°3°BÐ&7Ó8¸,ÀrÑ:JÐKó‰Fð !ˆLØ—[‘[ˆFä"Ø×!Ñ! &Ó)¨;¸ó
ˆô ”u˜\×-Ñ-Ó/Ó0Ó1ˆØ�‰�q˜'Ÿ+™+ b›/Ô*Ø#×-Ñ-¨gÓ6ˆä�~‰~˜l¨L¸tÔDÐDr%   c                 ól  — | j                   dz   }t        «       st        |dt        d«       | j                  t        j                  | j                  dd¬«      z
  }|j                  t        j                  |j                  dd¬«      z
  }t        j                  |«      }t        j                  |«      }t        j                  |dd¬«      }t        j                  |dd¬«      }||z  }	t        j                  |	|t        j                  |«      z
  |z
  t        j                  |«      z   z  dd|¬«      }
|
S )aï  The KL-divergence between two Categorical distributions.

        Args:
            other (Categorical): instance of Categorical. The data type is float32.

        Returns:
            Tensor: kl-divergence between two Categorical distributions.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Categorical

                >>> paddle.seed(100) # on CPU device
                >>> x = paddle.rand([6])
                >>> print(x)
                Tensor(shape=[6], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.55355281, 0.20714243, 0.01162981, 0.51577556, 0.36369765, 0.26091650])

                >>> paddle.seed(200) # on CPU device
                >>> y = paddle.rand([6])
                >>> print(y)
                Tensor(shape=[6], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.77663314, 0.90824795, 0.15685187, 0.04279523, 0.34468332, 0.79557180])

                >>> cat = Categorical(x)
                >>> cat2 = Categorical(y)

                >>> print(cat.kl_divergence(cat2))
                Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.07195196])
        Ú_kl_divergenceÚotherÚkl_divergencer   Tr   )r   r   r   )
r   r   r   r
   r   r   ÚmaxÚexpr   Úlog)r!   r=   r   r   Úother_logitsÚe_logitsÚother_e_logitsÚzÚother_zÚprobÚkls              r#   r>   zCategorical.kl_divergence´   s   € ðD �y‰yÐ+Ñ+ˆÜÔ Ü�u˜g¤{°OÔDà—‘œvŸz™z¨$¯+©+¸BÈÔMÑMˆØ—|‘|¤f§j¡jØ�L‰L˜r¨4ô'
ñ 
ˆô —:‘:˜fÓ%ˆÜŸ™ LÓ1ˆÜ�J‰J�x b°$Ô7ˆÜ—*‘*˜^°"¸dÔCˆØ˜!‰|ˆÜ�Z‰ZØØœŸ
™
 1›Ñ%¨Ñ4´v·z±zÀ'Ó7JÑJñLàØØô
ˆð ˆ	r%   c                 óv  — | j                   dz   }| j                  t        j                  | j                  dd¬«      z
  }t        j                  |«      }t        j
                  |dd¬«      }||z  }t        j
                  ||t        j                  |«      z
  z  d¬«      }t        j                  |d|¬«      }|S )a  Shannon entropy in nats.

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

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Categorical

                >>> paddle.seed(100) # on CPU device
                >>> x = paddle.rand([6])
                >>> print(x)
                Tensor(shape=[6], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.55355281, 0.20714243, 0.01162981, 0.51577556, 0.36369765, 0.26091650])

                >>> cat = Categorical(x)

                >>> print(cat.entropy())
                Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
                1.77528250)
        Ú_entropyr   Tr   ©r   g      ð¿)Úscaler   )r   r   r   r?   r@   r   rA   rL   )r!   r   r   rC   rE   rG   Úneg_entropyÚentropys           r#   rN   zCategorical.entropyí   s“   € ð0 �y‰y˜:Ñ%ˆØ—‘œvŸz™z¨$¯+©+¸BÈÔMÑMˆÜ—:‘:˜fÓ%ˆÜ�J‰J�x b°$Ô7ˆØ˜!‰|ˆä—j‘j ¨´&·*±*¸Q³-Ñ)?Ñ!@ÀrÔJˆÜ—,‘,˜{°$¸TÔBˆØˆr%   c           	      ó6  — | j                   dz   }t        | j                  j                  «      dk(  rOt	        j
                  | j                  |j                  dg|¬«      |¬«      j                  |j                  |¬«      S t        |j                  «      dk(  r`t	        j                  | j                  t	        j                  |t        | j                  j                  «      dz
  dgz  dgz   |¬«      d¬«      S t	        j                  | j                  |d¬«      S )aš  Probabilities of the given category (``value``).

        If ``logits`` is 2-D or higher dimension, the last dimension will be regarded as
        category, and the others represents the different distributions.
        At the same time, if ``vlaue`` is 1-D Tensor, ``value`` will be broadcast to the
        same number of distributions as ``logits``.
        If ``value`` is not 1-D Tensor, ``value`` should have the same number distributions
        with ``logits. That is, ``value[:-1] = logits[:-1]``.

        Args:
            value (Tensor): The input tensor represents the selected category index.

        Returns:
            Tensor: probability according to the category index.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Categorical

                >>> paddle.seed(100) # on CPU device
                >>> x = paddle.rand([6])
                >>> print(x)
                Tensor(shape=[6], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.55355281, 0.20714243, 0.01162981, 0.51577556, 0.36369765, 0.26091650])

                >>> cat = Categorical(x)

                >>> value = paddle.to_tensor([2,1,3])
                >>> print(cat.probs(value))
                Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.00608027, 0.10829761, 0.26965630])
        Ú_probsr*   r   r+   rK   )r   r.   r    r(   r   Úgatherr/   Útake_along_axis©r!   Úvaluer   s      r#   ÚprobszCategorical.probs  së   € ðF �y‰y˜8Ñ#ˆÜˆt�z‰z×ÑÓ  AÒ%Ü—=‘=Ø—
‘
˜EŸM™M¨2¨$°T˜MÓ:Àôç‰g�e—k‘k¨ˆgÓ-ð.ô �5—;‘;Ó 1Ò$Ü×-Ñ-Ø—J‘JÜ—N‘NØÜ˜TŸZ™Z×-Ñ-Ó.°Ñ2°q°cÑ9¸R¸DÑ@Ø!ôð
 ôð ô ×-Ñ-¨d¯j©j¸%ÀbÔIÐIr%   c                 ól   — | j                   dz   }t        j                  | j                  |«      |¬«      S )aÍ  Log probabilities of the given category. Refer to ``probs`` method.

        Args:
            value (Tensor): The input tensor represents the selected category index.

        Returns:
            Tensor: Log probability.

        Examples:
            .. code-block:: python

                >>> import paddle
                >>> from paddle.distribution import Categorical

                >>> paddle.seed(100) # on CPU device
                >>> x = paddle.rand([6])
                >>> print(x)
                Tensor(shape=[6], dtype=float32, place=Place(cpu), stop_gradient=True,
                [0.55355281, 0.20714243, 0.01162981, 0.51577556, 0.36369765, 0.26091650])

                >>> cat = Categorical(x)

                >>> value = paddle.to_tensor([2,1,3])
                >>> print(cat.log_prob(value))
                Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
                [-5.10270691, -2.22287226, -1.31060708])
        Ú	_log_probr+   )r   r   rA   rU   rS   s      r#   Úlog_probzCategorical.log_probE  s,   € ð8 �y‰y˜;Ñ&ˆä�z‰z˜$Ÿ*™* UÓ+°$Ô7Ð7r%   )N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r$   r)   r>   rN   rU   rX   © r%   r#   r
   r
      s-   „ ñ?óB,ò@7Eòr7òr òD4Jól8r%   r
   )Únumpyr   r   Úpaddle.base.data_feederr   r   Úpaddle.base.frameworkr   Úpaddle.distributionr   Úpaddle.frameworkr   Úpaddle.tensorr   ÚDistributionr
   r]   r%   r#   Ú<module>re      s0   ðó ã ß =Ý *Ý ,Ý ,Ý %ôJ8�,×+Ñ+õ J8r%   