U
    ‰d¯  ã                   @   s^   d dl Z d dlm  mZ d dlmZ d dlmZ d dl	m
Z
mZmZmZ G dd„ deƒZdS )é    N)Úconstraints)ÚDistribution)Úbroadcast_allÚprobs_to_logitsÚlazy_propertyÚlogits_to_probsc                       sÆ   e Zd ZdZe d¡e dd¡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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 )!ÚNegativeBinomialao  
    Creates a Negative Binomial distribution, i.e. distribution
    of the number of successful independent and identical Bernoulli trials
    before :attr:`total_count` failures are achieved. The probability
    of success of each Bernoulli trial is :attr:`probs`.

    Args:
        total_count (float or Tensor): non-negative number of negative Bernoulli
            trials to stop, although the distribution is still valid for real
            valued count
        probs (Tensor): Event probabilities of success in the half open interval [0, 1)
        logits (Tensor): Event log-odds for probabilities of success
    r   ç        ç      ð?)Útotal_countÚprobsÚlogitsNc                    sž   |d k|d kkrt dƒ‚|d k	rDt||ƒ\| _| _| j | j¡| _n"t||ƒ\| _| _| j | j¡| _|d k	rt| jn| j| _| j ¡ }tt	| ƒj
||d d S )Nz;Either `probs` or `logits` must be specified, but not both.©Úvalidate_args)Ú
ValueErrorr   r   r   Ztype_asr   Ú_paramÚsizeÚsuperr   Ú__init__)Úselfr   r   r   r   Úbatch_shape©Ú	__class__© úI/tmp/pip-unpacked-wheel-ua33x9lu/torch/distributions/negative_binomial.pyr      s    
zNegativeBinomial.__init__c                    s„   |   t|¡}t |¡}| j |¡|_d| jkrD| j |¡|_|j|_d| jkrd| j	 |¡|_	|j	|_t
t|ƒj|dd | j|_|S )Nr   r   Fr   )Z_get_checked_instancer   ÚtorchÚSizer   ÚexpandÚ__dict__r   r   r   r   r   Ú_validate_args)r   r   Z	_instanceÚnewr   r   r   r   )   s    


zNegativeBinomial.expandc                 O   s   | j j||ŽS ©N)r   r    )r   ÚargsÚkwargsr   r   r   Ú_new7   s    zNegativeBinomial._newc                 C   s   | j t | j¡ S r!   )r   r   Úexpr   ©r   r   r   r   Úmean:   s    zNegativeBinomial.meanc                 C   s    | j d | j ¡   ¡ jddS )Né   r	   )Úmin)r   r   r%   ÚfloorÚclampr&   r   r   r   Úmode>   s    zNegativeBinomial.modec                 C   s   | j t | j ¡ S r!   )r'   r   Zsigmoidr   r&   r   r   r   ÚvarianceB   s    zNegativeBinomial.variancec                 C   s   t | jddS ©NT)Z	is_binary)r   r   r&   r   r   r   r   F   s    zNegativeBinomial.logitsc                 C   s   t | jddS r.   )r   r   r&   r   r   r   r   J   s    zNegativeBinomial.probsc                 C   s
   | j  ¡ S r!   )r   r   r&   r   r   r   Úparam_shapeN   s    zNegativeBinomial.param_shapec                 C   s   t jj| jt  | j ¡ddS )NF)ZconcentrationÚrater   )r   ÚdistributionsÚGammar   r%   r   r&   r   r   r   Ú_gammaR   s    
þzNegativeBinomial._gammac              
   C   s8   t  ¡ & | jj|d}t  |¡W  5 Q R £ S Q R X d S )N)Úsample_shape)r   Zno_gradr3   ÚsampleZpoisson)r   r4   r0   r   r   r   r5   Y   s    
zNegativeBinomial.samplec                 C   sz   | j r|  |¡ | jt | j ¡ |t | j¡  }t | j| ¡ t d| ¡ t | j¡ }d|| j| dk< || S )Nr
   r	   )r   Z_validate_sampler   ÚFZ
logsigmoidr   r   Úlgamma)r   ÚvalueZlog_unnormalized_probZlog_normalizationr   r   r   Úlog_prob^   s    
ÿ
ÿzNegativeBinomial.log_prob)NNN)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Zgreater_than_eqZhalf_open_intervalÚrealZarg_constraintsZnonnegative_integerZsupportr   r   r$   Úpropertyr'   r,   r-   r   r   r   r/   r3   r   r   r5   r9   Ú__classcell__r   r   r   r   r      s2   
þ






r   )r   Ztorch.nn.functionalÚnnZ
functionalr6   Ztorch.distributionsr   Z torch.distributions.distributionr   Ztorch.distributions.utilsr   r   r   r   r   r   r   r   r   Ú<module>   s
   