U
    yhc                     @   sX   d dl 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)constraints)Categorical)Distribution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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 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__ Y/var/www/html/venv/lib/python3.8/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   1   s    

  zOneHotCategorical.expandc                 O   s   | j j||S N)r   _new)r   argskwargsr   r   r   r   ;   s    zOneHotCategorical._newc                 C   s   | j jS r   )r   _paramr   r   r   r   r    >   s    zOneHotCategorical._paramc                 C   s   | j jS r   r   r   r!   r   r   r   r   B   s    zOneHotCategorical.probsc                 C   s   | j jS r   )r   r   r!   r   r   r   r   F   s    zOneHotCategorical.logitsc                 C   s   | j jS r   r"   r!   r   r   r   meanJ   s    zOneHotCategorical.meanc                 C   s2   | j j}|jdd}tjjj||jd d|S )Nr	   )Zaxis)Znum_classes)	r   r   Zargmaxr   nn
functionalone_hotshapeto)r   r   moder   r   r   r)   N   s    zOneHotCategorical.modec                 C   s   | j jd| j j  S )N   r"   r!   r   r   r   varianceT   s    zOneHotCategorical.variancec                 C   s   | j jS r   )r   r   r!   r   r   r   r   X   s    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   r,   \   s
    
zOneHotCategorical.samplec                 C   s*   | j r| | |dd }| j|S )Nr	   r*   )r   Z_validate_samplemaxr   log_prob)r   valuer.   r   r   r   r0   c   s    
zOneHotCategorical.log_probc                 C   s
   | j  S r   )r   entropyr!   r   r   r   r2   i   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)r*   )
r   r   eyer    r3   r4   viewlenr   r   )r   r   nvaluesr   r   r   enumerate_supportl   s    
 z#OneHotCategorical.enumerate_support)NNN)N)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+   r   r   r   r,   r0   r2   r:   __classcell__r   r   r   r   r   
   s2   







c                   @   s$   e Zd ZdZdZ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)
    Tc                 C   s"   |  |}| jj}|||   S r   )r,   r   r   detach)r   r-   Zsamplesr   r   r   r   rsample   s    
z(OneHotCategoricalStraightThrough.rsampleN)r;   r<   r=   r>   Zhas_rsampler   r   rB   r   r   r   r   r   u   s   )
r   Ztorch.distributionsr   Ztorch.distributions.categoricalr   Z torch.distributions.distributionr   __all__r   r   r   r   r   r   <module>   s   k