o
    h                     @   sZ   d dl Z d dl mZ d dlmZ d dlmZ d dlmZmZm	Z	 dgZ
G dd deZdS )    N)nan)constraints)Distribution)lazy_propertylogits_to_probsprobs_to_logitsCategoricalc                       s   e Zd ZdZejejdZdZd# fdd	Z	d$ fdd	Z
d	d
 Zejddddd Zedd Zedd Zedd Zedd Zedd Zedd Ze fddZdd Zdd  Zd%d!d"Z  ZS )&r   a  
    Creates a categorical distribution parameterized by either :attr:`probs` or
    :attr:`logits` (but not both).

    .. note::
        It is equivalent to the distribution that :func:`torch.multinomial`
        samples from.

    Samples are integers from :math:`\{0, \ldots, K-1\}` where `K` is ``probs.size(-1)``.

    If `probs` is 1-dimensional with length-`K`, each element is the relative probability
    of sampling the class at that index.

    If `probs` is N-dimensional, the first N-1 dimensions are treated as a batch of
    relative probability vectors.

    .. note:: The `probs` argument must be non-negative, finite and have a non-zero sum,
              and it will be normalized to sum to 1 along the last dimension. :attr:`probs`
              will return this normalized value.
              The `logits` argument will be interpreted as unnormalized log probabilities
              and can therefore be any real number. It will likewise be normalized so that
              the resulting probabilities sum to 1 along the last dimension. :attr:`logits`
              will return this normalized value.

    See also: :func:`torch.multinomial`

    Example::

        >>> # xdoctest: +IGNORE_WANT("non-deterinistic")
        >>> m = Categorical(torch.tensor([ 0.25, 0.25, 0.25, 0.25 ]))
        >>> m.sample()  # equal probability of 0, 1, 2, 3
        tensor(3)

    Args:
        probs (Tensor): event probabilities
        logits (Tensor): event log probabilities (unnormalized)
    )probslogitsTNc                    s   |d u |d u krt d|d ur%| dk rt d||jddd | _n| dk r/t d||jddd | _|d ur@| jn| j| _| j d | _| j	 dkr\| j d d nt
 }t j||d	 d S )
Nz;Either `probs` or `logits` must be specified, but not both.   z3`probs` parameter must be at least one-dimensional.T)keepdimz4`logits` parameter must be at least one-dimensional.)dimr   validate_args)
ValueErrorr   sumr	   	logsumexpr
   _paramsize_num_events
ndimensiontorchSizesuper__init__)selfr	   r
   r   batch_shape	__class__ U/var/www/html/ai/venv/lib/python3.10/site-packages/torch/distributions/categorical.pyr   3   s    &zCategorical.__init__c                    s   |  t|}t|}|t| jf }d| jv r$| j||_|j|_d| jv r4| j	||_	|j	|_| j|_t
t|j|dd | j|_|S )Nr	   r
   Fr   )_get_checked_instancer   r   r   r   __dict__r	   expandr   r
   r   r   _validate_args)r   r   	_instancenewparam_shaper   r    r!   r$   H   s   


zCategorical.expandc                 O   s   | j j|i |S N)r   r'   )r   argskwargsr    r    r!   _newW   s   zCategorical._newr   )is_discrete	event_dimc                 C   s   t d| jd S )Nr   r   )r   integer_intervalr   r   r    r    r!   supportZ   s   zCategorical.supportc                 C   
   t | jS r)   )r   r	   r0   r    r    r!   r
   ^      
zCategorical.logitsc                 C   r2   r)   )r   r
   r0   r    r    r!   r	   b   r3   zCategorical.probsc                 C   s
   | j  S r)   )r   r   r0   r    r    r!   r(   f   r3   zCategorical.param_shapec                 C      t j|  t| jj| jjdS Ndtypedevicer   full_extended_shaper   r	   r7   r8   r0   r    r    r!   meanj      zCategorical.meanc                 C   s   | j jddS )Nr   )axis)r	   argmaxr0   r    r    r!   modes   s   zCategorical.modec                 C   r4   r5   r9   r0   r    r    r!   variancew   r=   zCategorical.variancec                 C   sJ   t |tjst|}| jd| j}t|| dj}|| 	|S )Nr   T)

isinstancer   r   r	   reshaper   multinomialnumelTr;   )r   sample_shapeprobs_2d
samples_2dr    r    r!   sample   s
   
zCategorical.samplec                 C   sR   | j r| | | d}t|| j\}}|dd df }|d|dS )Nr   .r   )	r%   _validate_samplelong	unsqueezer   broadcast_tensorsr
   gathersqueeze)r   valuelog_pmfr    r    r!   log_prob   s   
zCategorical.log_probc                 C   s6   t | jjj}t j| j|d}|| j }|d S )N)minr   )r   finfor
   r7   rT   clampr	   r   )r   min_realr
   p_log_pr    r    r!   entropy   s   
zCategorical.entropyc                 C   sL   | j }tj|tj| jjd}|ddt| j  }|r$|	d| j }|S )Nr6   )r   )r   )
r   r   arangerL   r   r8   viewlen_batch_shaper$   )r   r$   
num_eventsvaluesr    r    r!   enumerate_support   s   zCategorical.enumerate_support)NNNr)   )T)__name__
__module____qualname____doc__r   simplexreal_vectorarg_constraintshas_enumerate_supportr   r$   r,   dependent_propertyr1   r   r
   r	   propertyr(   r<   r@   rA   r   r   rJ   rS   rY   r`   __classcell__r    r    r   r!   r   
   s2    %






)r   r   torch.distributionsr    torch.distributions.distributionr   torch.distributions.utilsr   r   r   __all__r   r    r    r    r!   <module>   s    