o
    ei                     @   s   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 )    N)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de	de	e
B dB de	e
B dB dedB ddf
 fd	d
Zd fdd	Zdd Zede	fddZede	fddZedejfddZe fded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logitsNtemperaturer   r   validate_argsreturnc                    s   || _ |d u |d u krtd|d urt|t}t|\| _n|d u r'tdt|t}t|\| _|d ur9| jn| j| _|rDt	
 }n| j }t j||d d S )Nz;Either `probs` or `logits` must be specified, but not both.zlogits is unexpectedly Noner   )r   
ValueError
isinstancer   r   r   AssertionErrorr   _paramtorchSizesizesuper__init__)selfr   r   r   r   	is_scalarbatch_shape	__class__ o/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/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*   K   s   


zLogitRelaxedBernoulli.expandc                 O   s   | j j|i |S N)r   r.   )r!   argskwargsr&   r&   r'   _newY   s   zLogitRelaxedBernoulli._newc                 C      t | jddS NT)	is_binary)r   r   r!   r&   r&   r'   r   \      zLogitRelaxedBernoulli.logitsc                 C   r3   r4   )r
   r   r6   r&   r&   r'   r   `   r7   zLogitRelaxedBernoulli.probsc                 C   s
   | j  S r/   )r   r   r6   r&   r&   r'   param_shaped   s   
z!LogitRelaxedBernoulli.param_shapesample_shapec                 C   s\   |  |}t| j|}ttj||j|jd}| | 	  |  | 	  | j
 S )N)dtypedevice)_extended_shaper   r   r*   r   randr:   r;   loglog1pr   )r!   r9   shaper   uniformsr&   r&   r'   rsampleh   s   
"zLogitRelaxedBernoulli.rsamplec                 C   sN   | j r| | t| j|\}}||| j }| j | d|    S )N   )	r+   _validate_sampler   r   mulr   r>   expr?   )r!   valuer   diffr&   r&   r'   log_probr   s
   
zLogitRelaxedBernoulli.log_probNNNr/   )__name__
__module____qualname____doc__r   unit_intervalrealarg_constraintssupportr   r   boolr    r*   r2   r	   r   r   propertyr   r   r8   r   rB   rI   __classcell__r&   r&   r$   r'   r      s8    


c                       s   e Zd ZU dZejejdZejZdZ	e
ed< 			ddedeeB dB deeB dB d	edB d
df
 fddZd fdd	Zed
efddZed
efddZed
ef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   r   r   r   r   c                    s$   t |||}t j|t |d d S )Nr   )r   r   r    r   )r!   r   r   r   r   rV   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.expandc                 C      | j jS r/   )rV   r   r6   r&   r&   r'   r         zRelaxedBernoulli.temperaturec                 C   rW   r/   )rV   r   r6   r&   r&   r'   r      rX   zRelaxedBernoulli.logitsc                 C   rW   r/   )rV   r   r6   r&   r&   r'   r      rX   zRelaxedBernoulli.probsrJ   r/   )rK   rL   rM   rN   r   rO   rP   rQ   rR   has_rsampler   __annotations__r   r   rS   r    r*   rT   r   r   r   rU   r&   r&   r$   r'   r   z   s6   
 


)r   r   torch.distributionsr    torch.distributions.distributionr   ,torch.distributions.transformed_distributionr   torch.distributions.transformsr   torch.distributions.utilsr   r   r	   r
   r   torch.typesr   r   r   __all__r   r   r&   r&   r&   r'   <module>   s   d