U
    ©Ê¹j�  ã                   @   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 k|d kkrt dƒ‚|d k	rJ| ¡ dk r4t dƒ‚||jddd� | _n(| ¡ dk r^t dƒ‚||jddd� | _|d k	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	   Z	logsumexpr
   Ú_paramÚsizeÚ_num_eventsZ
ndimensionÚtorchÚSizeÚsuperÚ__init__)Úselfr	   r
   r   Úbatch_shape©Ú	__class__© ú^/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributions/categorical.pyr   3   s     ÿ&ÿzCategorical.__init__c                    s�   |   t|¡}t |¡}|t | jf¡ }d| jkrH| j |¡|_|j|_d| jk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!   H   s    


zCategorical.expandc                 O   s   | j j||ŽS ©N)r   r#   )r   ÚargsÚkwargsr   r   r   Ú_newW   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   ÚsupportZ   s    zCategorical.supportc                 C   s
   t | jƒS r%   )r   r	   r)   r   r   r   r
   ^   s    zCategorical.logitsc                 C   s
   t | jƒS r%   )r   r
   r)   r   r   r   r	   b   s    zCategorical.probsc                 C   s
   | j  ¡ S r%   )r   r   r)   r   r   r   r$   f   s    zCategorical.param_shapec                 C   s   t j|  ¡ t| jj| jjd�S ©N©ÚdtypeÚdevice©r   ÚfullÚ_extended_shaper   r	   r-   r.   r)   r   r   r   Úmeanj   s    üzCategorical.meanc                 C   s   | j jdd�S )Nr   )Zaxis)r	   Zargmaxr)   r   r   r   Úmodes   s    zCategorical.modec                 C   s   t j|  ¡ t| jj| jjd�S r+   r/   r)   r   r   r   Úvariancew   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ÚTr1   )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
   r-   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aranger8   r   r.   Ú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!   r(   Zdependent_propertyr*   r   r
   r	   Úpropertyr$   r2   r3   r4   r   r   r7   r:   r=   rA   Ú__classcell__r   r   r   r   r   
   s0   %






)r   r   Ztorch.distributionsr   Z torch.distributions.distributionr   Ztorch.distributions.utilsr   r   r   Ú__all__r   r   r   r   r   Ú<module>   s   