a
    hD                     @   s   d dl mZ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 d dlmZmZmZmZmZ d d	lmZmZmZ d
dgZG dd
 d
eZG dd de
ZdS )    )OptionalUnionN)Tensor)constraints)Distribution)TransformedDistribution)SigmoidTransform)broadcast_allclamp_probslazy_propertylogits_to_probsprobs_to_logits)_Number_sizeNumberLogitRelaxedBernoulliRelaxedBernoullic                       s   e Zd ZdZejejdZejZde	e
ee	ef  e
ee	ef  e
e dd fddZd fdd	Zd	d
 Zee	dddZee	dddZeejdddZe fee	d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logitsNtemperaturer   r   validate_argsreturnc                    s   || _ |d u |d u krtd|d ur>t|t}t|\| _n"|d usJJ t|t}t|\| _|d urn| jn| j| _|rt	 }n
| j
 }t j||d d S )Nz;Either `probs` or `logits` must be specified, but not both.r   )r   
ValueError
isinstancer   r	   r   r   _paramtorchSizesizesuper__init__)selfr   r   r   r   Z	is_scalarbatch_shape	__class__ S/var/www/auris/lib/python3.9/site-packages/torch/distributions/relaxed_bernoulli.pyr"   .   s     



zLogitRelaxedBernoulli.__init__c                    s~   |  t|}t|}| j|_d| jv r>| j||_|j|_d| jv 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+   H   s    


zLogitRelaxedBernoulli.expandc                 O   s   | j j|i |S N)r   r/   )r#   argskwargsr'   r'   r(   _newV   s    zLogitRelaxedBernoulli._newr   c                 C   s   t | jddS NT)Z	is_binary)r   r   r#   r'   r'   r(   r   Y   s    zLogitRelaxedBernoulli.logitsc                 C   s   t | jddS r5   )r   r   r6   r'   r'   r(   r   ]   s    zLogitRelaxedBernoulli.probsc                 C   s
   | j  S r0   )r   r    r6   r'   r'   r(   param_shapea   s    z!LogitRelaxedBernoulli.param_shape)sample_shaper   c                 C   s\   |  |}t| j|}ttj||j|jd}| | 	  |  | 	  | j
 S )N)dtypedevice)Z_extended_shaper
   r   r+   r   Zrandr9   r:   loglog1pr   )r#   r8   shaper   Zuniformsr'   r'   r(   rsamplee   s    
"zLogitRelaxedBernoulli.rsamplec                 C   sN   | j r| | t| j|\}}||| j }| j | d|    S )N   )	r,   Z_validate_sampler	   r   mulr   r;   expr<   )r#   valuer   diffr'   r'   r(   log_probo   s
    
zLogitRelaxedBernoulli.log_prob)NNN)N)__name__
__module____qualname____doc__r   unit_intervalrealarg_constraintssupportr   r   r   r   boolr"   r+   r3   r   r   r   propertyr   r   r7   r   r>   rD   __classcell__r'   r'   r%   r(   r      s.      
c                       s   e Zd ZU dZejejdZejZdZ	e
ed< deeeeef  eeeef  ee dd fddZd fd	d
	ZeedddZeedddZeed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-deterministic")
        >>> 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   T	base_distNr   c                    s$   t |||}t j|t |d d S )Nr   )r   r!   r"   r   )r#   r   r   r   r   rP   r%   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.expandr4   c                 C   s   | j jS r0   )rP   r   r6   r'   r'   r(   r      s    zRelaxedBernoulli.temperaturec                 C   s   | j jS r0   )rP   r   r6   r'   r'   r(   r      s    zRelaxedBernoulli.logitsc                 C   s   | j jS r0   )rP   r   r6   r'   r'   r(   r      s    zRelaxedBernoulli.probs)NNN)N)rE   rF   rG   rH   r   rI   rJ   rK   rL   Zhas_rsampler   __annotations__r   r   r   r   rM   r"   r+   rN   r   r   r   rO   r'   r'   r%   r(   r   w   s,   
   
)typingr   r   r   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   Ztorch.typesr   r   r   __all__r   r   r'   r'   r'   r(   <module>   s   `