U
    d                     @   sp   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
mZmZmZ d dlmZ G dd	 d	eZdS )
    )NumberN)nan)constraints)ExponentialFamily)broadcast_allprobs_to_logitslogits_to_probslazy_property) binary_cross_entropy_with_logitsc                       s   e Zd ZdZejejdZejZ	dZ
d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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ed d! Zd"d# Z  ZS )'	Bernoullia  
    Creates a Bernoulli distribution parameterized by :attr:`probs`
    or :attr:`logits` (but not both).

    Samples are binary (0 or 1). They take the value `1` with probability `p`
    and `0` with probability `1 - p`.

    Example::

        >>> m = Bernoulli(torch.tensor([0.3]))
        >>> m.sample()  # 30% chance 1; 70% chance 0
        tensor([ 0.])

    Args:
        probs (Number, Tensor): the probability of sampling `1`
        logits (Number, Tensor): the log-odds of sampling `1`
    )probslogitsTr   Nc                    s   |d k|d kkrt d|d k	r8t|t}t|\| _nt|t}t|\| _|d k	r\| jn| j| _|rrt }n
| j	 }t
t| j||d d S )Nz;Either `probs` or `logits` must be specified, but not both.validate_args)
ValueError
isinstancer   r   r   r   _paramtorchSizesizesuperr   __init__)selfr   r   r   Z	is_scalarbatch_shape	__class__ A/tmp/pip-unpacked-wheel-ua33x9lu/torch/distributions/bernoulli.pyr   #   s    



zBernoulli.__init__c                    sv   |  t|}t|}d| jkr6| j||_|j|_d| jkrV| j||_|j|_t	t|j
|dd | j|_|S )Nr   r   Fr   )Z_get_checked_instancer   r   r   __dict__r   expandr   r   r   r   _validate_args)r   r   Z	_instancenewr   r   r   r   3   s    


zBernoulli.expandc                 O   s   | j j||S N)r   r!   )r   argskwargsr   r   r   _new@   s    zBernoulli._newc                 C   s   | j S r"   r   r   r   r   r   meanC   s    zBernoulli.meanc                 C   s$   | j dk| j }t|| j dk< |S )Ng      ?)r   tor   )r   moder   r   r   r*   G   s    zBernoulli.modec                 C   s   | j d| j   S N   r&   r'   r   r   r   varianceM   s    zBernoulli.variancec                 C   s   t | jddS NT)Z	is_binary)r   r   r'   r   r   r   r   Q   s    zBernoulli.logitsc                 C   s   t | jddS r.   )r   r   r'   r   r   r   r   U   s    zBernoulli.probsc                 C   s
   | j  S r"   )r   r   r'   r   r   r   param_shapeY   s    zBernoulli.param_shapec              
   C   s<   |  |}t   t| j|W  5 Q R  S Q R X d S r"   )Z_extended_shaper   Zno_gradZ	bernoullir   r   )r   Zsample_shapeshaper   r   r   sample]   s    

zBernoulli.samplec                 C   s0   | j r| | t| j|\}}t||dd S Nnone)Z	reduction)r    Z_validate_sampler   r   r
   )r   valuer   r   r   r   log_probb   s    
zBernoulli.log_probc                 C   s   t | j| jddS r2   )r
   r   r   r'   r   r   r   entropyh   s    zBernoulli.entropyc                 C   sH   t jd| jj| jjd}|ddt| j  }|rD|d| j }|S )N   )dtypedevice))r,   )	r   Zaranger   r8   r9   viewlenZ_batch_shaper   )r   r   valuesr   r   r   enumerate_supportk   s
    zBernoulli.enumerate_supportc                 C   s   t | jd| j  fS r+   )r   logr   r'   r   r   r   _natural_paramsr   s    zBernoulli._natural_paramsc                 C   s   t dt | S r+   )r   r?   exp)r   xr   r   r   _log_normalizerv   s    zBernoulli._log_normalizer)NNN)N)T) __name__
__module____qualname____doc__r   Zunit_intervalrealZarg_constraintsbooleanZsupportZhas_enumerate_supportZ_mean_carrier_measurer   r   r%   propertyr(   r*   r-   r	   r   r   r/   r   r   r1   r5   r6   r>   r@   rC   __classcell__r   r   r   r   r      s:   







r   )Znumbersr   r   Z
torch._sixr   Ztorch.distributionsr   Ztorch.distributions.exp_familyr   Ztorch.distributions.utilsr   r   r   r	   Ztorch.nn.functionalr
   r   r   r   r   r   <module>   s   