U
    ©Ê¹j÷  ã                   @   sŒ   d dl mZ 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mZmZmZmZ dd	gZG d
d„ deƒZG dd	„ d	eƒZdS )é    )ÚNumberN)Úconstraints)ÚDistribution)ÚTransformedDistribution)ÚSigmoidTransform)Úbroadcast_allÚclamp_probsÚlazy_propertyÚlogits_to_probsÚprobs_to_logitsÚLogitRelaxedBernoulliÚRelaxedBernoullic                       sˆ   e Zd ZdZejejdœZej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 ¡ fdd„Zdd„ Z‡  ZS )r   a�  
    Creates a LogitRelaxedBernoulli distribution parameterized by :attr:`probs`
    or :attr:`logits` (but not both), which is the logit of a RelaxedBernoulli
    distribution.

    Samples are logits of values in (0, 1). See [1] for more details.

    Args:
        temperature (Tensor): relaxation temperature
        probs (Number, Tensor): the probability of sampling `1`
        logits (Number, Tensor): the log-odds of sampling `1`

    [1] The Concrete Distribution: A Continuous Relaxation of Discrete Random
    Variables (Maddison et al, 2017)

    [2] Categorical Reparametrization with Gumbel-Softmax
    (Jang et al, 2017)
    ©ÚprobsÚlogitsNc                    s–   || _ |d k|d kkrtdƒ‚|d k	r>t|tƒ}t|ƒ\| _nt|tƒ}t|ƒ\| _|d k	rb| jn| j| _|rxt 	¡ }n
| j 
¡ }tƒ j||d� d S )Nz;Either `probs` or `logits` must be specified, but not both.©Úvalidate_args)ÚtemperatureÚ
ValueErrorÚ
isinstancer   r   r   r   Ú_paramÚtorchÚSizeÚsizeÚsuperÚ__init__)Úselfr   r   r   r   Z	is_scalarÚbatch_shape©Ú	__class__© úd/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributions/relaxed_bernoulli.pyr   )   s    ÿ



zLogitRelaxedBernoulli.__init__c                    s~   |   t|¡}t |¡}| j|_d| jkr>| j |¡|_|j|_d| jkr^| j	 |¡|_	|j	|_t
t|ƒj|dd� | j|_|S )Nr   r   Fr   )Ú_get_checked_instancer   r   r   r   Ú__dict__r   Úexpandr   r   r   r   Ú_validate_args©r   r   Ú	_instanceÚnewr   r    r!   r$   <   s    


zLogitRelaxedBernoulli.expandc                 O   s   | j j||ŽS ©N)r   r(   )r   ÚargsÚkwargsr    r    r!   Ú_newJ   s    zLogitRelaxedBernoulli._newc                 C   s   t | jdd�S ©NT)Z	is_binary)r   r   ©r   r    r    r!   r   M   s    zLogitRelaxedBernoulli.logitsc                 C   s   t | jdd�S r-   )r
   r   r.   r    r    r!   r   Q   s    zLogitRelaxedBernoulli.probsc                 C   s
   | j  ¡ S r)   )r   r   r.   r    r    r!   Úparam_shapeU   s    z!LogitRelaxedBernoulli.param_shapec                 C   s\   |   |¡}t| j |¡ƒ}ttj||j|jd�ƒ}| ¡ |  	¡  | ¡  |  	¡  | j
 S )N)ÚdtypeÚdevice)Z_extended_shaper   r   r$   r   Zrandr0   r1   ÚlogÚlog1pr   )r   Zsample_shapeÚshaper   Zuniformsr    r    r!   ÚrsampleY   s    
ÿ"þzLogitRelaxedBernoulli.rsamplec                 C   sN   | j r|  |¡ t| j|ƒ\}}|| | j¡ }| j ¡ | d| ¡  ¡   S )Né   )	r%   Z_validate_sampler   r   Úmulr   r2   Úexpr3   )r   Úvaluer   Údiffr    r    r!   Úlog_probc   s
    
zLogitRelaxedBernoulli.log_prob)NNN)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úunit_intervalÚrealÚarg_constraintsÚsupportr   r$   r,   r	   r   r   Úpropertyr/   r   r   r5   r;   Ú__classcell__r    r    r   r!   r      s   



c                       sl   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ed	d
„ ƒZedd„ ƒZedd„ ƒZ‡  ZS )r   aç  
    Creates a RelaxedBernoulli distribution, parametrized by
    :attr:`temperature`, and either :attr:`probs` or :attr:`logits`
    (but not both). This is a relaxed version of the `Bernoulli` distribution,
    so the values are in (0, 1), and has reparametrizable samples.

    Example::

        >>> # xdoctest: +IGNORE_WANT("non-deterinistic")
        >>> m = RelaxedBernoulli(torch.tensor([2.2]),
        ...                      torch.tensor([0.1, 0.2, 0.3, 0.99]))
        >>> m.sample()
        tensor([ 0.2951,  0.3442,  0.8918,  0.9021])

    Args:
        temperature (Tensor): relaxation temperature
        probs (Number, Tensor): the probability of sampling `1`
        logits (Number, Tensor): the log-odds of sampling `1`
    r   TNc                    s$   t |||ƒ}tƒ j|tƒ |d� d S )Nr   )r   r   r   r   )r   r   r   r   r   Ú	base_distr   r    r!   r   ƒ   s    zRelaxedBernoulli.__init__c                    s   |   t|¡}tƒ j||d�S )N)r'   )r"   r   r   r$   r&   r   r    r!   r$   ‡   s    zRelaxedBernoulli.expandc                 C   s   | j jS r)   )rF   r   r.   r    r    r!   r   ‹   s    zRelaxedBernoulli.temperaturec                 C   s   | j jS r)   )rF   r   r.   r    r    r!   r   �   s    zRelaxedBernoulli.logitsc                 C   s   | j jS r)   )rF   r   r.   r    r    r!   r   “   s    zRelaxedBernoulli.probs)NNN)N)r<   r=   r>   r?   r   r@   rA   rB   rC   Zhas_rsampler   r$   rD   r   r   r   rE   r    r    r   r!   r   k   s   

)Únumbersr   r   Ztorch.distributionsr   Z torch.distributions.distributionr   Z,torch.distributions.transformed_distributionr   Ztorch.distributions.transformsr   Ztorch.distributions.utilsr   r   r	   r
   r   Ú__all__r   r   r    r    r    r!   Ú<module>   s   X