
    Vh                     |    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e      Z G d
 de      Zy)    N)Tensor)constraints)Categorical)Distribution)_sizeOneHotCategorical OneHotCategoricalStraightThroughc                   n    e Zd ZdZej
                  ej                  dZej                  Z	dZ
d fd	Zd fd	Zd Zedefd       Zedefd	       Zedefd
       Zedefd       Zedefd       Zedefd       Zedej.                  fd       Z ej.                         fdZd Zd ZddZ x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logitsTc                     t        ||      | _        | j                  j                  }| j                  j                  dd  }t        |   |||       y )Nvalidate_args)r   _categoricalbatch_shapeparam_shapesuper__init__)selfr   r   r   r   event_shape	__class__s         W/home/dcms/DCMS/lib/python3.12/site-packages/torch/distributions/one_hot_categorical.pyr   zOneHotCategorical.__init__/   sO    'v6''33''33BC8kO    c                     | j                  t        |      }t        j                  |      }| j                  j                  |      |_        t        t        |  || j                  d       | j                  |_	        |S )NFr   )
_get_checked_instancer   torchSizer   expandr   r   r   _validate_args)r   r   	_instancenewr   s       r   r   zOneHotCategorical.expand5   st    (():IFjj-,,33K@.)) 	/ 	
 "00
r   c                 :     | j                   j                  |i |S N)r   _new)r   argskwargss      r   r%   zOneHotCategorical._new?   s     %t  %%t6v66r   returnc                 .    | j                   j                  S r$   )r   _paramr   s    r   r*   zOneHotCategorical._paramB         '''r   c                 .    | j                   j                  S r$   r   r   r+   s    r   r   zOneHotCategorical.probsF         &&&r   c                 .    | j                   j                  S r$   )r   r   r+   s    r   r   zOneHotCategorical.logitsJ   r,   r   c                 .    | j                   j                  S r$   r.   r+   s    r   meanzOneHotCategorical.meanN   r/   r   c                     | j                   j                  }|j                  d      }t        j                  j
                  j                  ||j                  d         j                  |      S )Nr   )dim)num_classes)	r   r   argmaxr   nn
functionalone_hotshapeto)r   r   modes      r   r<   zOneHotCategorical.modeR   sW    !!''|||#xx""**4U[[_*MPPQVWWr   c                 b    | j                   j                  d| j                   j                  z
  z  S )N   r.   r+   s    r   variancezOneHotCategorical.varianceX   s*      &&!d.?.?.E.E*EFFr   c                 .    | j                   j                  S r$   )r   r   r+   s    r   r   zOneHotCategorical.param_shape\   s      ,,,r   c                 ,   t        j                  |      }| j                  j                  }| j                  j                  }| j                  j                  |      }t         j                  j                  j                  ||      j                  |      S r$   )
r   r   r   r   _num_eventssampler7   r8   r9   r;   )r   sample_shaper   
num_eventsindicess        r   rC   zOneHotCategorical.sample`   sp    zz,/!!''&&22
##**<8xx""**7J?BB5IIr   c                     | j                   r| j                  |       |j                  d      d   }| j                  j	                  |      S )Nr   r>   )r    _validate_samplemaxr   log_prob)r   valuerF   s      r   rJ   zOneHotCategorical.log_probg   sB    !!%())B-"  ))'22r   c                 6    | j                   j                         S r$   )r   entropyr+   s    r   rM   zOneHotCategorical.entropym   s      ((**r   c                 L   | j                   d   }t        j                  || j                  j                  | j                  j
                        }|j                  |fdt        | j                        z  z   |fz         }|r#|j                  |f| j                  z   |fz         }|S )Nr   )dtypedevice)r>   )
r   r   eyer*   rO   rP   viewlenr   r   )r   r   nvaluess       r   enumerate_supportz#OneHotCategorical.enumerate_supportp   s    Q1DKK$5$5dkk>P>PQaTD3t/?/?+@$@@A4GH]]A4$*:*:#:aT#ABFr   )NNNr$   )T)__name__
__module____qualname____doc__r   simplexreal_vectorarg_constraintsr9   supporthas_enumerate_supportr   r   r%   propertyr   r*   r   r   r2   r<   r?   r   r   r   rC   rJ   rM   rV   __classcell__)r   s   @r   r   r      s*   : !, 3 3{?V?VWO!!G P7 ( ( ( 'v ' ' ( ( ( 'f ' ' Xf X X
 G& G G -UZZ - - #-%**, J3+r   c                   F    e Zd ZdZdZ ej                         fdedefdZ	y)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)
    TrD   r(   c                 |    | j                  |      }| j                  j                  }|||j                         z
  z   S r$   )rC   r   r   detach)r   rD   samplesr   s       r   rsamplez(OneHotCategoricalStraightThrough.rsample   s7    ++l+!!''%%,,.011r   N)
rW   rX   rY   rZ   has_rsampler   r   r   r   rf    r   r   r	   r	   y   s,     K,6EJJL 2E 2V 2r   )r   r   torch.distributionsr   torch.distributions.categoricalr    torch.distributions.distributionr   torch.typesr   __all__r   r	   rh   r   r   <module>rn      s@      + 7 9   B
Ci iX2'8 2r   