a
    h                     @   sj   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
mZmZ dgZG dd deZdS )	    )OptionalN)nanTensor)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%e	e
 e	e
 e	e dd fddZd& fdd		Zd
d Zejddddd Zee
dddZee
dddZeejdddZee
dddZee
dddZee
d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-deterministic")
        >>> 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logitsTN)r   r   validate_argsreturnc                    s   |d u |d u krt d|d urJ| dk r4t d||jddd | _n4|d usVJ | dk rjt 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   r   )
ValueErrorr   sumr   Z	logsumexpr   _paramsize_num_eventsZ
ndimensiontorchSizesuper__init__)selfr   r   r   batch_shape	__class__ M/var/www/auris/lib/python3.9/site-packages/torch/distributions/categorical.pyr   8   s"    &zCategorical.__init__c                    s   |  t|}t|}|t| jf }d| jv rH| j||_|j|_d| jv rh| j	||_	|j	|_| j|_t
t|j|dd | j|_|S )Nr   r   Fr   )Z_get_checked_instancer
   r   r   r   __dict__r   expandr   r   r   r   _validate_args)r   r   Z	_instancenewparam_shaper   r!   r"   r$   S   s    


zCategorical.expandc                 O   s   | j j|i |S N)r   r&   )r   argskwargsr!   r!   r"   _newb   s    zCategorical._newr   )Zis_discreteZ	event_dimc                 C   s   t d| jd S )Nr   r   )r   Zinteger_intervalr   r   r!   r!   r"   supporte   s    zCategorical.support)r   c                 C   s
   t | jS r(   )r	   r   r,   r!   r!   r"   r   i   s    zCategorical.logitsc                 C   s
   t | jS r(   )r   r   r,   r!   r!   r"   r   m   s    zCategorical.probsc                 C   s
   | j  S r(   )r   r   r,   r!   r!   r"   r'   q   s    zCategorical.param_shapec                 C   s   t j|  t| jj| jjdS Ndtypedevicer   full_extended_shaper   r   r0   r1   r,   r!   r!   r"   meanu   s    zCategorical.meanc                 C   s   | j jddS )Nr   )r   )r   Zargmaxr,   r!   r!   r"   mode~   s    zCategorical.modec                 C   s   t j|  t| jj| jjdS r.   r2   r,   r!   r!   r"   variance   s    zCategorical.variancec                 C   sJ   t |tjst|}| jd| j}t|| dj}|| 	|S )Nr   T)

isinstancer   r   r   Zreshaper   ZmultinomialZnumelTr4   )r   Zsample_shapeZprobs_2dZ
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%   Z_validate_samplelongZ	unsqueezer   Zbroadcast_tensorsr   ZgatherZsqueeze)r   valueZ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   Zfinfor   r0   r>   clampr   r   )r   Zmin_realr   Zp_log_pr!   r!   r"   entropy   s    
zCategorical.entropyc                 C   sL   | j }tj|tj| jjd}|ddt| j  }|rH|	d| j }|S )Nr/   )r   )r   )
r   r   Zaranger;   r   r1   viewlenZ_batch_shaper$   )r   r$   Z
num_eventsvaluesr!   r!   r"   enumerate_support   s    zCategorical.enumerate_support)NNN)N)T) __name__
__module____qualname____doc__r   ZsimplexZreal_vectorZarg_constraintsZhas_enumerate_supportr   r   boolr   r$   r+   Zdependent_propertyr-   r   r   r   propertyr   r   r'   r5   r6   r7   r:   r=   r@   rD   __classcell__r!   r!   r   r"   r
      s@   &   
)typingr   r   r   r   Ztorch.distributionsr   Z torch.distributions.distributionr   Ztorch.distributions.utilsr   r   r	   __all__r
   r!   r!   r!   r"   <module>   s   