B
    `'                 @   s   d Z ddlmZ ddlmZ 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 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 G dd dejZdS )z!The Geometric distribution class.    )absolute_import)division)print_functionN)v2)_numpy)distribution)assert_util)distribution_util)
dtype_util)reparameterization)samplers)tensor_utilc                   s   e Zd ZdZd5 fdd	Zedd Zed	d
 Zedd Z	dd Z
dd Zdd Zdd Zd6ddZdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd7d%d&Zd8d'd(Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Z  ZS )9	Geometrica  Geometric distribution.

  The Geometric distribution is parameterized by p, the probability of a
  positive event. It represents the probability that in k + 1 Bernoulli trials,
  the first k trials failed, before seeing a success.

  The pmf of this distribution is:

  #### Mathematical Details

  ```none
  pmf(k; p) = (1 - p)**k * p
  ```

  where:

  * `p` is the success probability, `0 < p <= 1`, and,
  * `k` is a non-negative integer.

  NFTc          	      s   t t }|dk|dkkr"tdt|\}tj||gtjd}tj	||dd| _
tj	||dd| _tt| j|tj||||d W dQ R X dS )aD  Construct Geometric distributions.

    Args:
      logits: Floating-point `Tensor` with shape `[B1, ..., Bb]` where `b >= 0`
        indicates the number of batch dimensions. Each entry represents logits
        for the probability of success for independent Geometric distributions
        and must be in the range `(-inf, inf]`. Only one of `logits` or `probs`
        should be specified.
      probs: Positive floating-point `Tensor` with shape `[B1, ..., Bb]`
        where `b >= 0` indicates the number of batch dimensions. Each entry
        represents the probability of success for independent Geometric
        distributions and must be in the range `(0, 1]`. Only one of `logits`
        or `probs` should be specified.
      validate_args: Python `bool`, default `False`. When `True` distribution
        parameters are checked for validity despite possibly degrading runtime
        performance. When `False` invalid inputs may silently render incorrect
        outputs.
      allow_nan_stats: Python `bool`, default `True`. When `True`, statistics
        (e.g., mean, mode, variance) use the value "`NaN`" to indicate the
        result is undefined. When `False`, an exception is raised if one or
        more of the statistic's batch members are undefined.
      name: Python `str` name prefixed to Ops created by this class.
    Nz(Must pass probs or logits, but not both.)Z
dtype_hintprobs)dtypenamelogits)r   Zreparameterization_typevalidate_argsallow_nan_stats
parametersr   )dictlocals
ValueErrortfZ
name_scoper
   Zcommon_dtypefloat32r   Zconvert_nonref_to_tensor_probs_logitssuperr   __init__r   ZNOT_REPARAMETERIZED)selfr   r   r   r   r   r   r   )	__class__ k/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow_probability/python/distributions/_numpy/geometric.pyr   8   s     

zGeometric.__init__c             C   s   t dddS )Nr   )r   r   )r   )clsr!   r!   r"   _params_event_ndimsg   s    zGeometric._params_event_ndimsc             C   s   | j S )zInput argument `logits`.)r   )r   r!   r!   r"   r   k   s    zGeometric.logitsc             C   s   | j S )zInput argument `probs`.)r   )r   r!   r!   r"   r   p   s    zGeometric.probsc             C   s    | j d kr| jn| j }t|S )N)r   r   r   shape)r   xr!   r!   r"   _batch_shape_tensoru   s    zGeometric._batch_shape_tensorc             C   s   | j d kr| jn| j }|jS )N)r   r   r%   )r   r&   r!   r!   r"   _batch_shapey   s    zGeometric._batch_shapec             C   s   t jg t jdS )N)r   )r   Zconstantint32)r   r!   r!   r"   _event_shape_tensor}   s    zGeometric._event_shape_tensorc             C   s
   t g S )N)r   ZTensorShape)r   r!   r!   r"   _event_shape   s    zGeometric._event_shapec             C   sb   |   }tjt|gt|gdtt	| j
jd|| j
d}ttj|tj|  S )Nr   g      ?)minvalmaxvalseedr   )_probs_parameter_no_checksr   uniformr   concatr%   npZfinfor
   as_numpy_dtyper   Ztinyfloormathloglog1p)r   nr.   r   Zsampledr!   r!   r"   	_sample_n   s    	
zGeometric._sample_nc             C   sL   |   }| jst|}t|dk t|jtj	 d| tj
|  S )Ng        g      ?)r/   r   r   r4   wherer
   r3   r   r2   infr5   r7   )r   r&   r   r!   r!   r"   _log_survival_function   s    
z Geometric._log_survival_functionc          
   C   sR   |   }| jst|}t|dk t|jtj	 t
d| tj|  S )Ng        g      ?)r/   r   r   r4   r:   r
   r3   r   r2   r;   tfp_mathZlog1mexpr5   r7   )r   r&   r   r!   r!   r"   _log_cdf   s    
zGeometric._log_cdfc             C   s4   |   }| jst|}tj|| tj| S )N)r/   r   r   r4   r5   Zxlog1pyr6   )r   r&   r   r!   r!   r"   	_log_prob   s    
zGeometric._log_probc          	   C   s`   |   \}}| jsg }ntj|t| jdddg}t| tj	
|| | S Q R X d S )Ng      ?z4Entropy is undefined when logits = inf or probs = 1.)message)_logits_and_probs_no_checksr   r   Zassert_lessr
   r3   r   r   Zcontrol_dependenciesr5   Zsoftplus)r   r   r   
assertionsr!   r!   r"   _entropy   s    
zGeometric._entropyc             C   s   t |   S )N)r   exp_logits_parameter_no_checks)r   r!   r!   r"   _mean   s    zGeometric._meanc             C   s   |   \}}t| | S )N)rA   r   rD   )r   r   r   r!   r!   r"   	_variance   s    zGeometric._variancec             C   s   t j|  | jdS )N)r   )r   zerosZbatch_shape_tensorr   )r   r!   r!   r"   _mode   s    zGeometric._modec          	   C   sN   |  |p
d6 | jdkr8tj| jtj| j  S t| jS Q R X dS )z@Logits computed from non-`None` input arg (`probs` or `logits`).logits_parameterN)_name_and_control_scoper   r   r5   r6   r   r7   identity)r   r   r!   r!   r"   rJ      s    
zGeometric.logits_parameterc          	   C   s>   |  |p
d& | jdkr&t| jS tj| jS Q R X dS )z?Probs computed from non-`None` input arg (`probs` or `logits`).probs_parameterN)rK   r   r   rL   r   r5   sigmoid)r   r   r!   r!   r"   rM      s    
zGeometric.probs_parameterc             C   s<   | j d kr0t| j}tj|tj|  S t| j S )N)r   r   convert_to_tensorr   r5   r6   r7   rL   )r   r   r!   r!   r"   rE      s    
z%Geometric._logits_parameter_no_checksc             C   s$   | j d krt| jS tj| j S )N)r   r   rL   r   r5   rN   )r   r!   r!   r"   r/      s    
z$Geometric._probs_parameter_no_checksc             C   sR   | j d kr2t| j}tj|tj|  }nt| j }tj|}||fS )N)r   r   rO   r   r5   r6   r7   rN   )r   r   r   r!   r!   r"   rA      s    
z%Geometric._logits_and_probs_no_checksc             C   s   d S )Nr!   )r   r!   r!   r"   _default_event_space_bijector   s    z'Geometric._default_event_space_bijectorc             C   s"   g }| j s|S |t| |S )N)r   extendr	   Zassert_nonnegative_integer_form)r   r&   rB   r!   r!   r"   _sample_control_dependencies   s
    z&Geometric._sample_control_dependenciesc             C   sn   | j s
g S g }| jd k	rj|t| jkrjt| j}|tj|dd |tj	|t
| jddd |S )Nz"Argument `probs` must be positive.)r@   g      ?z1Argument `probs` must be less than or equal to 1.)r   r   r   Zis_refr   rO   appendr   Zassert_positiveZassert_less_equalr
   r3   r   )r   Zis_initrB   r   r!   r!   r"   _parameter_control_dependencies  s    

z)Geometric._parameter_control_dependencies)NNFTr   )N)N)N)__name__
__module____qualname____doc__r   classmethodr$   propertyr   r   r'   r(   r*   r+   r9   r<   r>   r?   rC   rF   rG   rI   rJ   rM   rE   r/   rA   rP   rR   rT   __classcell__r!   r!   )r    r"   r   "   s:       *


	r   )rX   
__future__r   r   r   numpyr2   Z;tensorflow_probability.python.internal.backend.numpy.compatr   r   Z"tensorflow_probability.python.mathr   r=   Z2tensorflow_probability.python.distributions._numpyr   Z-tensorflow_probability.python.internal._numpyr   r	   r
   Z&tensorflow_probability.python.internalr   r   r   Distributionr   r!   r!   r!   r"   <module>   s   