
    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l
mZmZmZmZmZ d dlmZmZ d	d
gZ G d d	e      Z G d d
e      Zy)    N)Tensor)constraints)Distribution)TransformedDistribution)SigmoidTransform)broadcast_allclamp_probslazy_propertylogits_to_probsprobs_to_logits)_Number_sizeLogitRelaxedBernoulliRelaxedBernoullic                       e Zd ZdZej
                  ej                  dZej                  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j$                  fd	       Z ej$                         fd
edefdZd Z x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logitsc                    || _         |d u |d u k(  rt        d      |#t        |t              }t	        |      \  | _        n"t        |t              }t	        |      \  | _        || j
                  n| j                  | _        |rt        j                         }n| j                  j                         }t        | 1  ||       y )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   	is_scalarbatch_shape	__class__s          U/home/dcms/DCMS/lib/python3.12/site-packages/torch/distributions/relaxed_bernoulli.pyr    zLogitRelaxedBernoulli.__init__,   s    &TMv~.M  "5'2I)%0MTZ"673I*62NT[$)$5djj4;;**,K++**,KMB    c                    | j                  t        |      }t        j                  |      }| j                  |_        d| j
                  v r1| j                  j                  |      |_        |j                  |_        d| j
                  v r1| j                  j                  |      |_	        |j                  |_        t        t        |/  |d       | j                  |_        |S )Nr   r   Fr   )_get_checked_instancer   r   r   r   __dict__r   expandr   r   r   r    _validate_argsr!   r#   	_instancenewr$   s       r%   r*   zLogitRelaxedBernoulli.expand?   s    (()>	Jjj-**dmm#

))+6CICJt}}$++K8CJCJ#S2;e2T!00
r&   c                 :     | j                   j                  |i |S N)r   r.   )r!   argskwargss      r%   _newzLogitRelaxedBernoulli._newM   s    t{{///r&   returnc                 0    t        | j                  d      S NT)	is_binary)r   r   r!   s    r%   r   zLogitRelaxedBernoulli.logitsP   s    tzzT::r&   c                 0    t        | j                  d      S r6   )r   r   r8   s    r%   r   zLogitRelaxedBernoulli.probsT   s    t{{d;;r&   c                 6    | j                   j                         S r0   )r   r   r8   s    r%   param_shapez!LogitRelaxedBernoulli.param_shapeX   s    {{!!r&   sample_shapec                 z   | j                  |      }t        | j                  j                  |            }t        t	        j
                  ||j                  |j                              }|j                         | j                         z
  |j                         z   | j                         z
  | j                  z  S )N)dtypedevice)_extended_shaper	   r   r*   r   randr>   r?   loglog1pr   )r!   r<   shaper   uniformss        r%   rsamplezLogitRelaxedBernoulli.rsample\   s    $$\2DJJ--e45JJuEKKE
 LLNxi..00599;>5&AQQ 	r&   c                 (   | j                   r| j                  |       t        | j                  |      \  }}||j	                  | j
                        z
  }| j
                  j                         |z   d|j                         j                         z  z
  S )N   )	r+   _validate_sampler   r   mulr   rB   exprC   )r!   valuer   diffs       r%   log_probzLogitRelaxedBernoulli.log_probf   sy    !!%(%dkk59		$"2"233##%,q488:3C3C3E/EEEr&   NNNr0   )__name__
__module____qualname____doc__r   unit_intervalrealarg_constraintssupportr    r*   r3   r
   r   r   r   propertyr   r   r;   r   rF   rN   __classcell__r$   s   @r%   r   r      s    & !, 9 9[EUEUVOGC&0 ; ; ; <v < < "UZZ " " -7EJJL E V Fr&   c                        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edefd       Zedefd       Zedefd	       Z x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   Tc                 T    t        |||      }t        | 	  |t               |       y )Nr   )r   r   r    r   )r!   r   r   r   r   	base_distr$   s         r%   r    zRelaxedBernoulli.__init__   s)    )+ufE	$4$6mTr&   c                 R    | j                  t        |      }t        |   ||      S )N)r-   )r(   r   r   r*   r,   s       r%   r*   zRelaxedBernoulli.expand   s)    (()99Ew~kS~99r&   r4   c                 .    | j                   j                  S r0   )r]   r   r8   s    r%   r   zRelaxedBernoulli.temperature   s    ~~)))r&   c                 .    | j                   j                  S r0   )r]   r   r8   s    r%   r   zRelaxedBernoulli.logits   s    ~~$$$r&   c                 .    | j                   j                  S r0   )r]   r   r8   s    r%   r   zRelaxedBernoulli.probs   s    ~~###r&   rO   r0   )rP   rQ   rR   rS   r   rT   rU   rV   rW   has_rsampler    r*   rX   r   r   r   r   rY   rZ   s   @r%   r   r   n   s    ( !, 9 9[EUEUVO''GKU: *V * * % % % $v $ $r&   )r   r   torch.distributionsr    torch.distributions.distributionr   ,torch.distributions.transformed_distributionr   torch.distributions.transformsr   torch.distributions.utilsr   r	   r
   r   r   torch.typesr   r   __all__r   r    r&   r%   <module>rk      sQ      + 9 P ;  ' #$6
7VFL VFr+$. +$r&   