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

  The Bernoulli distribution with `probs` parameter, i.e., the probability of a
  `1` outcome (vs a `0` outcome).
  NFTc          	      s   t t }|dk|dkkr"tdt|.}tj|tjdd| _tj|tjdd| _	W dQ R X t
t| j|tj||||d dS )a*  Construct Bernoulli distributions.

    Args:
      logits: An N-D `Tensor` representing the log-odds of a `1` event. Each
        entry in the `Tensor` parameterizes an independent Bernoulli
        distribution where the probability of an event is sigmoid(logits). Only
        one of `logits` or `probs` should be passed in.
      probs: An N-D `Tensor` representing the probability of a `1`
        event. Each entry in the `Tensor` parameterizes an independent
        Bernoulli distribution. Only one of `logits` or `probs` should be passed
        in.
      dtype: The type of the event samples. Default: `int32`.
      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.

    Raises:
      ValueError: If p and logits are passed, or if neither are passed.
    Nz(Must pass probs or logits, but not both.probs)Z
dtype_hintnamelogits)dtypeZreparameterization_typevalidate_argsallow_nan_stats
parametersr   )dictlocals
ValueErrortf
name_scoper   Zconvert_nonref_to_tensorfloat32_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/bernoulli.pyr   (   s     

zBernoulli.__init__c             C   s   dt j| t jdiS )Nr   )r   )r   convert_to_tensorint32)Zsample_shaper"   r"   r#   _param_shapesX   s    zBernoulli._param_shapesc             C   s   t dddS )Nr   )r   r   )r   )clsr"   r"   r#   _params_event_ndims\   s    zBernoulli._params_event_ndimsc             C   s   | j S )zInput argument `logits`.)r   )r    r"   r"   r#   r   `   s    zBernoulli.logitsc             C   s   | j S )zInput argument `probs`.)r   )r    r"   r"   r#   r   e   s    zBernoulli.probsc             C   s    | j d kr| jn| j }t|S )N)r   r   r   shape)r    xr"   r"   r#   _batch_shape_tensorj   s    zBernoulli._batch_shape_tensorc             C   s   | j d kr| jn| j }|jS )N)r   r   r)   )r    r*   r"   r"   r#   _batch_shapen   s    zBernoulli._batch_shapec             C   s   t jg t jdS )N)r   )r   constantr%   )r    r"   r"   r#   _event_shape_tensorr   s    zBernoulli._event_shape_tensorc             C   s
   t g S )N)r   ZTensorShape)r    r"   r"   r#   _event_shapeu   s    zBernoulli._event_shapec             C   sL   |   }t|gt|gd}tj|||jd}t||}t|| jS )Nr   )seedr   )	_probs_parameter_no_checksr   concatr)   r   uniformr   Zlesscast)r    nr0   r   Z	new_shaper3   sampler"   r"   r#   	_sample_nx   s
    zBernoulli._sample_nc             C   s:   |   \}}t||j}tj|d| tj|| S )N   )_outcome_log_probsr   r4   r   mathmultiply_no_nan)r    event
log_probs0
log_probs1r"   r"   r#   	_log_prob   s    zBernoulli._log_probc             C   sZ   | j d kr0t| j}tj| tj|fS t| j }tj| tj|  fS )N)r   r   r$   r   r:   log1plogsoftplus)r    psr"   r"   r#   r9      s
    
zBernoulli._outcome_log_probsc             C   s:   t | j| jdd\}}}}dtj||tj||  S )NT)r   r   return_log_probsg      )_probs_and_log_probsr   r   r   r:   r;   )r    probs0probs1r=   r>   r"   r"   r#   _entropy   s
    zBernoulli._entropyc             C   s   |   S )N)r1   )r    r"   r"   r#   _mean   s    zBernoulli._meanc             C   s   t | j| jdd\}}|| S )NF)r   r   rE   )rF   r   r   )r    rG   rH   r"   r"   r#   	_variance   s    zBernoulli._variancec             C   s   t |  dk| jS )z.Returns `1` if `prob > 0.5` and `0` otherwise.g      ?)r   r4   r1   r   )r    r"   r"   r#   _mode   s    zBernoulli._modec          	   C   s"   |  |p
d
 |  S Q R X dS )z@Logits computed from non-`None` input arg (`probs` or `logits`).logits_parameterN)_name_and_control_scope_logits_parameter_no_checks)r    r   r"   r"   r#   rM      s    zBernoulli.logits_parameterc             C   s<   | j d kr0t| j}tj|tj|  S t| j S )N)r   r   r$   r   r:   rA   r@   identity)r    r   r"   r"   r#   rO      s    
z%Bernoulli._logits_parameter_no_checksc          	   C   s"   |  |p
d
 |  S Q R X dS )z?Probs computed from non-`None` input arg (`probs` or `logits`).probs_parameterN)rN   r1   )r    r   r"   r"   r#   rQ      s    zBernoulli.probs_parameterc             C   s$   | j d krt| jS tj| j S )N)r   r   rP   r   r:   sigmoid)r    r"   r"   r#   r1      s    
z$Bernoulli._probs_parameter_no_checksc             C   s   d S )Nr"   )r    r"   r"   r#   _default_event_space_bijector   s    z'Bernoulli._default_event_space_bijectorc             C   s   t || j| j| jS )N)(maybe_assert_bernoulli_param_correctnessr   r   r   )r    is_initr"   r"   r#   _parameter_control_dependencies   s    z)Bernoulli._parameter_control_dependenciesc             C   sD   g }| j s|S |t| |tj|tjg |j	ddd |S )N)r   z)Sample must be less than or equal to `1`.)message)
r   extendr	   Zassert_nonnegative_integer_formappendr   assert_less_equalr   Zonesr   )r    r*   
assertionsr"   r"   r#   _sample_control_dependencies   s    
z&Bernoulli._sample_control_dependencies)N)N)N)!__name__
__module____qualname____doc__r   r%   r   staticmethodr&   classmethodr(   propertyr   r   r+   r,   r.   r/   r7   r?   r9   rI   rJ   rK   rL   rM   rO   rQ   r1   rS   rV   r\   __classcell__r"   r"   )r!   r#   r   !   s:   *


r   c             C   s   | r:|dkr|dfn|df\}}t |js:td||sBg S g }|dk	r| t|krt|}t	d|j}|t
j|ddt
j||ddg7 }|S )	z5Return assertions for `Bernoulli`-type distributions.Nr   r   z(Argument `{}` must having floating type.g      ?z!probs has components less than 0.)rW   z$probs has components greater than 1.)r
   Zis_floatingr   	TypeErrorformatr   Zis_refr   r$   r-   r   Zassert_non_negativerZ   )rU   r   r   r   r*   r   r[   Zoner"   r"   r#   rT      s$    
rT   NTc             C   s   d}| dk|dkkst d|dkrht| }|rB|d| |f7 }|rd|tj| tj|f7 }|S t|}|r|tj| tj|f7 }|r|tj| tj|  f7 }|S )zFGet parts/all of (1 - p, p, Log[1 - p], Log[p]);  only one conversion.r"   NzProvide exactly one.r8   )AssertionErrorr   r$   r:   r@   rA   rR   rB   )r   r   return_probsrE   Z	to_returnrC   rD   r"   r"   r#   rF      s    

"rF   c          	   C   s   t |p
dl |  }| }t|d\}}}}t|dd\}	}
t j||t j|
| t j|| t j|	| S Q R X dS )aZ  Calculate the batched KL divergence KL(a || b) with a and b Bernoulli.

  Args:
    a: instance of a Bernoulli distribution object.
    b: instance of a Bernoulli distribution object.
    name: Python `str` name to use for created operations.
      Default value: `None` (i.e., `'kl_bernoulli_bernoulli'`).

  Returns:
    Batchwise KL(a || b)
  Zkl_bernoulli_bernoulli)r   F)r   rh   N)r   r   rO   rF   r:   r;   )abr   Za_logitsZb_logitsZone_minus_papaZlog_one_minus_paZlog_paZlog_one_minus_pbZlog_pbr"   r"   r#   _kl_bernoulli_bernoulli  s    (rl   )NNTT)N)r`   
__future__r   r   r   Z;tensorflow_probability.python.internal.backend.numpy.compatr   r   Z2tensorflow_probability.python.distributions._numpyr   r   Z-tensorflow_probability.python.internal._numpyr   r	   r
   Z&tensorflow_probability.python.internalr   r   r   Distributionr   rT   rF   Z
RegisterKLrl   r"   r"   r"   r#   <module>   s*    ,   

