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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gZeejG dd dejZG dd deZG dd deZeeejdddZdS )z%The Deterministic distribution class.    )absolute_import)division)print_functionN)v2)distribution)kullback_leibler)assert_util)
dtype_util)reparameterization)tensor_util)tensorshape_utilDeterministicVectorDeterministicc                   s   e Zd ZdZd fdd	Z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dddZdd Zdd Z  ZS )_BaseDeterministicz+Base class for Deterministic distributions.NFTc	       
   	      s   t |}tj|||gt jd}	tj||	dd| _tj|dkrDdn||	dd| _tj|dkrbdn||	dd| _	|| _
tt| j| jjt| jjrtjntj||||d	 W dQ R X dS )
aK  Initialize a batch of `_BaseDeterministic` distributions.

    The `atol` and `rtol` parameters allow for some slack in `pmf`, `cdf`
    computations, e.g. due to floating-point error.

    ```
    pmf(x; loc)
      = 1, if Abs(x - loc) <= atol + rtol * Abs(loc),
      = 0, otherwise.
    ```

    Args:
      loc: Numeric `Tensor`.  The point (or batch of points) on which this
        distribution is supported.
      atol:  Non-negative `Tensor` of same `dtype` as `loc` and broadcastable
        shape.  The absolute tolerance for comparing closeness to `loc`.
        Default is `0`.
      rtol:  Non-negative `Tensor` of same `dtype` as `loc` and broadcastable
        shape.  The relative tolerance for comparing closeness to `loc`.
        Default is `0`.
      is_vector:  Python `bool`.  If `True`, this is for `VectorDeterministic`,
        else `Deterministic`.
      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.
      parameters: Dict of locals to facilitate copy construction.
      name: Python `str` name prefixed to Ops created by this class.

    Raises:
      ValueError:  If `loc` is a scalar.
    )
dtype_hintloc)r   nameNr   atol)dtyper   rtol)r   Zreparameterization_typevalidate_argsallow_nan_stats
parametersr   )tf
name_scoper	   Zcommon_dtypefloat32r   Zconvert_nonref_to_tensor_loc_atol_rtol
_is_vectorsuperr   __init__r   is_floatingr
   ZFULLY_REPARAMETERIZEDZNOT_REPARAMETERIZED)
selfr   r   r   	is_vectorr   r   r   r   r   )	__class__ o/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow_probability/python/distributions/_numpy/deterministic.pyr!   -   s"    -
z_BaseDeterministic.__init__c             C   s.   | j d d kr| jS | j| jt|  S d S )Nr   )r   r   r   r   abs)r#   r   r&   r&   r'   _slacko   s    z_BaseDeterministic._slackc             C   s   | j S )zCPoint (or batch of points) at which this distribution is supported.)r   )r#   r&   r&   r'   r   v   s    z_BaseDeterministic.locc             C   s   | j S )z6Absolute tolerance for comparing points to `self.loc`.)r   )r#   r&   r&   r'   r   {   s    z_BaseDeterministic.atolc             C   s   | j S )z6Relative tolerance for comparing points to `self.loc`.)r   )r#   r&   r&   r'   r      s    z_BaseDeterministic.rtolc             C   s   t j|  | jdS )N)r   )r   zerosZbatch_shape_tensorr   )r#   r&   r&   r'   _entropy   s    z_BaseDeterministic._entropyc             C   s   t | jS )N)r   identityr   )r#   r&   r&   r'   _mean   s    z_BaseDeterministic._meanc             C   s   t | jS )N)r   Z
zeros_liker   )r#   r&   r&   r'   	_variance   s    z_BaseDeterministic._variancec             C   s   |   S )N)Zmean)r#   r&   r&   r'   _mode   s    z_BaseDeterministic._modec          	   C   s<   ~t | j}t |t j|g| j|d| j|dgddS )N)r   r   )axis)r   convert_to_tensorr   Zbroadcast_toconcat_batch_shape_tensor_event_shape_tensor)r#   nseedr   r&   r&   r'   	_sample_n   s    z_BaseDeterministic._sample_nc             C   s   d S )Nr&   )r#   r&   r&   r'   _default_event_space_bijector   s    z0_BaseDeterministic._default_event_space_bijectorc             C   s   g }|r^| j r^d}t| jjd k	r@t| jjdk r^t|n| jr^|tj	| jd|d | jsp|rlt
g S |t| jkr|tj| jdd |t| jkr|tj| jdd |S )Nz'Argument `loc` must be at least rank 1.   )messagez$Argument "atol" must be non-negativez$Argument "rtol" must be non-negative)r   r   rankr   shape
ValueErrorr   appendr   assert_rank_at_leastAssertionErrorr   Zis_refr   Zassert_non_negativer   )r#   Zis_init
assertionsmsgr&   r&   r'   _parameter_control_dependencies   s*    

z2_BaseDeterministic._parameter_control_dependencies)NNFFTNr   )N)__name__
__module____qualname____doc__r!   r)   propertyr   r   r   r+   r-   r.   r/   r7   r8   rC   __classcell__r&   r&   )r%   r'   r   )   s&         :
	r   c                   sb   e Zd ZdZd fdd	Zedd Zdd	d
Zdd ZdddZ	dd Z
dd Zdd Z  ZS )r   a  Scalar `Deterministic` distribution on the real line.

  The scalar `Deterministic` distribution is parameterized by a [batch] point
  `loc` on the real line.  The distribution is supported at this point only,
  and corresponds to a random variable that is constant, equal to `loc`.

  See [Degenerate rv](https://en.wikipedia.org/wiki/Degenerate_distribution).

  #### Mathematical Details

  The probability mass function (pmf) and cumulative distribution function (cdf)
  are

  ```none
  pmf(x; loc) = 1, if x == loc, else 0
  cdf(x; loc) = 1, if x >= loc, else 0
  ```

  #### Examples

  ```python
  # Initialize a single Deterministic supported at zero.
  constant = tfp.distributions.Deterministic(0.)
  constant.prob(0.)
  ==> 1.
  constant.prob(2.)
  ==> 0.

  # Initialize a [2, 2] batch of scalar constants.
  loc = [[0., 1.], [2., 3.]]
  x = [[0., 1.1], [1.99, 3.]]
  constant = tfp.distributions.Deterministic(loc)
  constant.prob(x)
  ==> [[1., 0.], [0., 1.]]
  ```

  NFTc          	      s,   t t }tt| j|||||||d dS )a  Initialize a scalar `Deterministic` distribution.

    The `atol` and `rtol` parameters allow for some slack in `pmf`, `cdf`
    computations, e.g. due to floating-point error.

    ```
    pmf(x; loc)
      = 1, if Abs(x - loc) <= atol + rtol * Abs(loc),
      = 0, otherwise.
    ```

    Args:
      loc: Numeric `Tensor` of shape `[B1, ..., Bb]`, with `b >= 0`.
        The point (or batch of points) on which this distribution is supported.
      atol:  Non-negative `Tensor` of same `dtype` as `loc` and broadcastable
        shape.  The absolute tolerance for comparing closeness to `loc`.
        Default is `0`.
      rtol:  Non-negative `Tensor` of same `dtype` as `loc` and broadcastable
        shape.  The relative tolerance for comparing closeness to `loc`.
        Default is `0`.
      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.
    )r   r   r   r   r   r   N)dictlocalsr    r   r!   )r#   r   r   r   r   r   r   r   )r%   r&   r'   r!      s    %

zDeterministic.__init__c             C   s   t ddddS )Nr   )r   r   r   )rJ   )clsr&   r&   r'   _params_event_ndims  s    z!Deterministic._params_event_ndimsc          	   C   s8   t t |d kr| jn|t t | jt | jS )N)r   broadcast_dynamic_shaper<   r   r   r   )r#   r   r&   r&   r'   r3     s    z!Deterministic._batch_shape_tensorc             C   s    t | jjt | jj| jjS )N)r   broadcast_static_shaper   r<   r   r   )r#   r&   r&   r'   _batch_shape  s    zDeterministic._batch_shapec             C   s   ~t jg t jdS )N)r   )r   Zconstantint32)r#   r   r&   r&   r'   r4     s    z!Deterministic._event_shape_tensorc             C   s
   t g S )N)r   ZTensorShape)r#   r&   r&   r'   _event_shape"  s    zDeterministic._event_shapec             C   sF   t | j}t| jr| jnt j}t jt || | 	|k|dS )N)r   )
r   r1   r   r	   r"   r   r   castr(   r)   )r#   xr   Z
prob_dtyper&   r&   r'   _prob%  s    zDeterministic._probc             C   s*   t | j}t j||| | k| jdS )N)r   )r   r,   r   rS   r)   r   )r#   rT   r   r&   r&   r'   _cdf,  s    zDeterministic._cdf)NNFTr   )N)N)rD   rE   rF   rG   r!   classmethodrM   r3   rP   r4   rR   rU   rV   rI   r&   r&   )r%   r'   r      s   %    )

c                   sb   e Zd ZdZd fdd	Zedd Zdd	d
Zdd ZdddZ	dd Z
dd Zdd Z  ZS )r   a  Vector `Deterministic` distribution on `R^k`.

  The `VectorDeterministic` distribution is parameterized by a [batch] point
  `loc in R^k`.  The distribution is supported at this point only,
  and corresponds to a random variable that is constant, equal to `loc`.

  See [Degenerate rv](https://en.wikipedia.org/wiki/Degenerate_distribution).

  #### Mathematical Details

  The probability mass function (pmf) is

  ```none
  pmf(x; loc)
    = 1, if All[Abs(x - loc) <= atol + rtol * Abs(loc)],
    = 0, otherwise.
  ```

  #### Examples

  ```python
  tfd = tfp.distributions

  # Initialize a single VectorDeterministic supported at [0., 2.] in R^2.
  constant = tfd.Deterministic([0., 2.])
  constant.prob([0., 2.])
  ==> 1.
  constant.prob([0., 3.])
  ==> 0.

  # Initialize a [3] batch of constants on R^2.
  loc = [[0., 1.], [2., 3.], [4., 5.]]
  constant = tfd.VectorDeterministic(loc)
  constant.prob([[0., 1.], [1.9, 3.], [3.99, 5.]])
  ==> [1., 0., 0.]
  ```

  NFTc          
      s.   t t }tt| j|||d||||d dS )a  Initialize a `VectorDeterministic` distribution on `R^k`, for `k >= 0`.

    Note that there is only one point in `R^0`, the 'point' `[]`.  So if `k = 0`
    then `self.prob([]) == 1`.

    The `atol` and `rtol` parameters allow for some slack in `pmf`
    computations, e.g. due to floating-point error.

    ```
    pmf(x; loc)
      = 1, if All[Abs(x - loc) <= atol + rtol * Abs(loc)],
      = 0, otherwise
    ```

    Args:
      loc: Numeric `Tensor` of shape `[B1, ..., Bb, k]`, with `b >= 0`, `k >= 0`
        The point (or batch of points) on which this distribution is supported.
      atol:  Non-negative `Tensor` of same `dtype` as `loc` and broadcastable
        shape.  The absolute tolerance for comparing closeness to `loc`.
        Default is `0`.
      rtol:  Non-negative `Tensor` of same `dtype` as `loc` and broadcastable
        shape.  The relative tolerance for comparing closeness to `loc`.
        Default is `0`.
      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.
    T)r   r   r$   r   r   r   r   N)rJ   rK   r    r   r!   )r#   r   r   r   r   r   r   r   )r%   r&   r'   r!   Y  s    (

zVectorDeterministic.__init__c             C   s   t ddddS )Nr9   )r   r   r   )rJ   )rL   r&   r&   r'   rM     s    z'VectorDeterministic._params_event_ndimsc          	   C   s@   t t |d kr| jn|t t | jt | jd d S )N)r   rN   r<   r   r   r   )r#   r   r&   r&   r'   r3     s    z'VectorDeterministic._batch_shape_tensorc             C   s(   t | jjt | jj| jjd d S )NrX   )r   rO   r   r<   r   r   )r#   r&   r&   r'   rP     s    z VectorDeterministic._batch_shapec             C   s    t |d kr| jn|dd  S )NrX   )r   r<   r   )r#   r   r&   r&   r'   r4     s    z'VectorDeterministic._event_shape_tensorc             C   s   | j jdd  S )NrX   )r   r<   )r#   r&   r&   r'   rR     s    z VectorDeterministic._event_shapec             C   s:   t | j}t jt jt || | |kdd| jdS )NrX   )r0   )r   )r   r1   r   rS   Z
reduce_allr(   r)   r   )r#   rT   r   r&   r&   r'   rU     s     zVectorDeterministic._probc          
   C   sV   g }| j s|S |t|d |tj|  tt|t	|d dd |S )Nr9   zDArgument `x` not defined in the same space R**k as this distribution)r:   )
r   r>   r   r?   Zassert_equalZevent_shape_tensorr   Zgatherr<   r;   )r#   rT   rA   r&   r&   r'   _sample_control_dependencies  s     
z0VectorDeterministic._sample_control_dependencies)NNFTr   )N)N)rD   rE   rF   rG   r!   rW   rM   r3   rP   r4   rR   rU   rY   rI   r&   r&   )r%   r'   r   1  s   &    -

c          	   C   s(   t |p
d || j S Q R X dS )aV  Calculate the batched KL divergence `KL(a || b)` with `a` Deterministic.

  Args:
    a: instance of a Deterministic distribution object.
    b: instance of a Distribution distribution object.
    name: (optional) Name to use for created operations. Default is
      'kl_deterministic_distribution'.

  Returns:
    Batchwise `KL(a || b)`.
  Zkl_deterministic_distributionN)r   r   Zlog_probr   )abr   r&   r&   r'   _kl_deterministic_distribution  s    r\   )N)rG   
__future__r   r   r   abcsixZ;tensorflow_probability.python.internal.backend.numpy.compatr   r   Z2tensorflow_probability.python.distributions._numpyr   r   Z-tensorflow_probability.python.internal._numpyr   r	   Z&tensorflow_probability.python.internalr
   r   r   __all__add_metaclassABCMetaDistributionr   r   r   Z
RegisterKLr\   r&   r&   r&   r'   <module>   s.   
 w 