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 ddlmZ ddlmZ dgZG dd dejZeeedddZeeejdddZeejedddZ dddZ!dS )zThe Chi2 distribution class.    )absolute_import)division)print_functionN)v2)softplus)distribution)gamma)kullback_leibler)assert_util)distribution_util)
dtype_util)reparameterization)samplers)tensor_utilChi2c                   s   e Zd ZdZd+ 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edd,ddZdd Zdd Zdd Zdd Zd d! Zed"d#d$ Zd%d& Zd'd( Zd)d* Z  ZS )-r   a  Chi2 distribution.

  The Chi2 distribution is defined over positive real numbers using a degrees of
  freedom ('df') parameter.

  #### Mathematical Details

  The probability density function (pdf) is,

  ```none
  pdf(x; df, x > 0) = x**(0.5 df - 1) exp(-0.5 x) / Z
  Z = 2**(0.5 df) Gamma(0.5 df)
  ```

  where:

  * `df` denotes the degrees of freedom,
  * `Z` is the normalization constant, and,
  * `Gamma` is the [gamma function](
    https://en.wikipedia.org/wiki/Gamma_function).

  The Chi2 distribution is a special case of the Gamma distribution -- i.e.,
  `Chi2(df)` represents the same distribution as
  `Gamma(concentration=0.5 * df, rate=0.5)`.
  FTc          	      sf   t t }t|H}tj|gtjd}tj|d|d| _	t
t| j|||tj||d W dQ R X dS )a%  Construct Chi2 distributions with parameter `df`.

    Args:
      df: Floating point tensor, the degrees of freedom of the
        distribution(s). `df` must contain only positive values.
      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.
    )
dtype_hintdf)namedtype)r   validate_argsallow_nan_statsZreparameterization_type
parametersr   N)dictlocalstf
name_scoper   common_dtypefloat32r   Zconvert_nonref_to_tensor_dfsuperr   __init__r   ZFULLY_REPARAMETERIZED)selfr   r   r   r   r   r   )	__class__ f/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow_probability/python/distributions/_numpy/chi2.pyr    D   s    

zChi2.__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_shapese   s    zChi2._param_shapesc             C   s
   t ddS )Nr   )r   )r   )clsr#   r#   r$   _params_event_ndimsi   s    zChi2._params_event_ndimsc             C   s   | j S )N)r   )r!   r#   r#   r$   r   m   s    zChi2.dfc             C   s   t | jS )N)r   shaper   )r!   r#   r#   r$   _batch_shape_tensorq   s    zChi2._batch_shape_tensorc             C   s   | j jS )N)r   r*   )r!   r#   r#   r$   _batch_shapet   s    zChi2._batch_shapec             C   s   t jg t jdS )N)r   )r   Zconstantr&   )r!   r#   r#   r$   _event_shape_tensorw   s    zChi2._event_shape_tensorc             C   s
   t g S )N)r   ZTensorShape)r!   r#   r#   r$   _event_shapez   s    zChi2._event_shapezMNote: See `tf.random.gamma` docstring for sampling details and
      caveats.Nc             C   s*   t j|gd| j tjd| jd| j|dS )Ng      ?)r   )r*   alphabetar   seed)r   r   r   r   r%   r   )r!   nr1   r#   r#   r$   	_sample_n}   s    zChi2._sample_nc             C   sX   d| j  }tjd| jd}tj|d |||  }tj||tj|  }|| S )Ng      ?)r   g      ?)r   r   r%   r   mathZxlogylgammalog)r!   xconcentrationrateZlog_unnormalized_probZlog_normalizationr#   r#   r$   	_log_prob   s    

zChi2._log_probc             C   s   t jd| j d| S )Ng      ?)r   r4   Zigammar   )r!   r7   r#   r#   r$   _cdf   s    z	Chi2._cdfc             C   sJ   d| j  }tjd| jd}|tj| tj| d| tj|  S )Ng      ?)r   g      ?)r   r   r%   r   r4   r6   r5   digamma)r!   r8   r9   r#   r#   r$   _entropy   s    
zChi2._entropyc             C   s   t | jS )N)r   identityr   )r!   r#   r#   r$   _mean   s    z
Chi2._meanc             C   s
   d| j  S )Ng       @)r   )r!   r#   r#   r$   	_variance   s    zChi2._variancezThe mode of a Chi2 distribution is `df - 2` when `df > 2`, and `NaN`
      otherwise. If `self.allow_nan_stats` is `False`, an exception will be
      raised rather than returning `NaN`.c          	   C   sv   t | j}|d }| jr g }n tjdt g | j |ddg}t |" t 	|dk|t
| jtjS Q R X d S )Ng       @zMode not defined when df <= 2.)message)r   r%   r   r   r
   Zassert_lessZonesr   Zcontrol_dependencieswherer   Zas_numpy_dtypenpnan)r!   r   mode
assertionsr#   r#   r$   _mode   s    
z
Chi2._modec             C   s   t j| jdS )N)r   )softplus_bijectorZSoftplusr   )r!   r#   r#   r$   _default_event_space_bijector   s    z"Chi2._default_event_space_bijectorc             C   s&   g }| j s|S |tj|dd |S )NzSample must be non-negative.)rA   )r   appendr
   Zassert_non_negative)r!   r7   rF   r#   r#   r$   _sample_control_dependencies   s    z!Chi2._sample_control_dependenciesc             C   s8   | j s
g S g }|t| jkr4|tj| jdd |S )NzArgument `df` must be positive.)rA   )r   r   Zis_refr   rJ   r
   Zassert_positive)r!   Zis_initrF   r#   r#   r$   _parameter_control_dependencies   s    z$Chi2._parameter_control_dependencies)FTr   )N)__name__
__module____qualname____doc__r    staticmethodr'   classmethodr)   propertyr   r+   r,   r-   r.   r   ZAppendDocstringr3   r:   r;   r=   r?   r@   rG   rI   rK   rL   __classcell__r#   r#   )r"   r$   r   )   s0     c             C   s"   t d| j dd|j d|pddS )zECalculate the batched KL divergence KL(c0 || c1) with c0 and c1 Chi2.g      ?Zkl_chi2_chi2)concentration0rate0concentration1rate1r   )_kl_gamma_gammar   )c0c1r   r#   r#   r$   _kl_chi2_chi2   s    
r\   c             C   s    t d| j d|j|j|pddS )zGCalculate batched KL divergence KL(c0 || g1) with c0 Chi2 and g1 Gamma.g      ?Zkl_chi2_gamma)rU   rV   rW   rX   r   )rY   r   r8   r9   )rZ   Zg1r   r#   r#   r$   _kl_chi2_gamma   s    r]   c             C   s    t | j| jd|j d|pddS )zGCalculate batched KL divergence KL(g0 || c1) with g0 Gamma and c1 Chi2.g      ?Zkl_gamma_chi2)rU   rV   rW   rX   r   )rY   r8   r9   r   )Zg0r[   r   r#   r#   r$   _kl_gamma_chi2   s    

r^   c       
   	   C   s   t |p
d tj| |||gt jd}t j| |d}t j||d}t j||d}t j||d}	|| t j| t j| t j| |t j	|  |t j	|	  ||	| d   S Q R X dS )a  Calculate batched KL divergence KL(g0 || g1) with given Gamma parameters.

  Args:
    concentration0: Concentration of first Gamma distribution (g0).
    rate0: Rate of first Gamma distirbution (g0).
    concentration1: Concentration of second Gamma distribution (g1).
    rate1: Rate of second Gamma distirbution (g1).
    name: Python `str` name to use for created operations.
      Default value: `None` (i.e., `'kl_gamma_gamma'`).

  Returns:
    kl_gamma_gamma: `Tensor`. The batchwise KL(g0 || g1).
  Zkl_gamma_gamma)r   )r   g      ?N)
r   r   r   r   r   r%   r4   r<   r5   r6   )
rU   rV   rW   rX   r   r   Zg0_concentrationZg0_rateZg1_concentrationZg1_rater#   r#   r$   rY      s    LrY   )N)N)N)N)"rP   
__future__r   r   r   numpyrC   Z;tensorflow_probability.python.internal.backend.numpy.compatr   r   Z.tensorflow_probability.python.bijectors._numpyr   rH   Z2tensorflow_probability.python.distributions._numpyr   r   r	   Z-tensorflow_probability.python.internal._numpyr
   r   r   Z&tensorflow_probability.python.internalr   r   r   __all__Distributionr   Z
RegisterKLr\   Gammar]   r^   rY   r#   r#   r#   r$   <module>   s2     
