o
    Zh                     @   sp   d dl Z d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 ddgZ
G d	d deZG d
d deZdS )    N)Tensor)constraints)Categorical)Distribution)_sizeOneHotCategorical OneHotCategoricalStraightThroughc                       s   e Zd ZdZejejdZejZ	dZ
d" fdd	Zd# fdd	Zd	d
 ZedefddZedefddZedefddZedefddZedefddZedefddZedejfddZe fddZdd Zdd Zd$d d!Z  ZS )%r   a  
    Creates a one-hot categorical distribution parameterized by :attr:`probs` or
    :attr:`logits`.

    Samples are one-hot coded vectors of size ``probs.size(-1)``.

    .. 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.distributions.Categorical` for specifications of
    :attr:`probs` and :attr:`logits`.

    Example::

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

    Args:
        probs (Tensor): event probabilities
        logits (Tensor): event log probabilities (unnormalized)
    )probslogitsTNc                    s:   t ||| _| jj}| jjdd  }t j|||d d S )Nvalidate_args)r   _categoricalbatch_shapeparam_shapesuper__init__)selfr	   r
   r   r   event_shape	__class__ V/var/www/auris/lib/python3.10/site-packages/torch/distributions/one_hot_categorical.pyr   /   s   zOneHotCategorical.__init__c                    sH   |  t|}t|}| j||_tt|j|| jdd | j	|_	|S )NFr   )
Z_get_checked_instancer   torchSizer   expandr   r   r   _validate_args)r   r   Z	_instancenewr   r   r   r   5   s   

zOneHotCategorical.expandc                 O   s   | j j|i |S N)r   _new)r   argskwargsr   r   r   r   ?   s   zOneHotCategorical._newreturnc                 C      | j jS r   )r   _paramr   r   r   r   r$   B      zOneHotCategorical._paramc                 C   r#   r   r   r	   r%   r   r   r   r	   F   r&   zOneHotCategorical.probsc                 C   r#   r   )r   r
   r%   r   r   r   r
   J   r&   zOneHotCategorical.logitsc                 C   r#   r   r'   r%   r   r   r   meanN   r&   zOneHotCategorical.meanc                 C   s2   | j j}|jdd}tjjj||jd d|S )Nr   )dim)Znum_classes)	r   r	   Zargmaxr   nn
functionalone_hotshapeto)r   r	   moder   r   r   r/   R   s   zOneHotCategorical.modec                 C   s   | j jd| j j  S )N   r'   r%   r   r   r   varianceX   s   zOneHotCategorical.variancec                 C   r#   r   )r   r   r%   r   r   r   r   \   r&   zOneHotCategorical.param_shapec                 C   s<   t |}| jj}| jj}| j|}t jj||	|S r   )
r   r   r   r	   Z_num_eventssampler*   r+   r,   r.   )r   sample_shaper	   Z
num_eventsindicesr   r   r   r2   `   s
   
zOneHotCategorical.samplec                 C   s*   | j r| | |dd }| j|S )Nr   r0   )r   Z_validate_samplemaxr   log_prob)r   valuer4   r   r   r   r6   g   s   
zOneHotCategorical.log_probc                 C   s
   | j  S r   )r   entropyr%   r   r   r   r8   m   s   
zOneHotCategorical.entropyc                 C   sb   | j d }tj|| jj| jjd}||fdt| j  |f }|r/|	|f| j |f }|S )Nr   )dtypedevice)r0   )
r   r   eyer$   r9   r:   viewlenr   r   )r   r   nvaluesr   r   r   enumerate_supportp   s   
 z#OneHotCategorical.enumerate_support)NNNr   )T)__name__
__module____qualname____doc__r   ZsimplexZreal_vectorZarg_constraintsr,   ZsupportZhas_enumerate_supportr   r   r   propertyr   r$   r	   r
   r(   r/   r1   r   r   r   r2   r6   r8   r@   __classcell__r   r   r   r   r      s4    
c                   @   s.   e Zd ZdZdZe fdedefddZ	dS )r   a  
    Creates a reparameterizable :class:`OneHotCategorical` distribution based on the straight-
    through gradient estimator from [1].

    [1] Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation
    (Bengio et al., 2013)
    Tr3   r"   c                 C   s"   |  |}| jj}|||   S r   )r2   r   r	   detach)r   r3   Zsamplesr	   r   r   r   rsample   s   
z(OneHotCategoricalStraightThrough.rsampleN)
rA   rB   rC   rD   Zhas_rsampler   r   r   r   rH   r   r   r   r   r   y   s    )r   r   Ztorch.distributionsr   Ztorch.distributions.categoricalr   Z torch.distributions.distributionr   Ztorch.typesr   __all__r   r   r   r   r   r   <module>   s   l