B
    `A,                 @   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 G dd dejZdS )z"The Triangular distribution class.    )absolute_import)division)print_functionN)v2)sigmoid)distribution)assert_util)
dtype_util)reparameterization)samplers)tensor_utilc                   s   e Zd ZdZd, 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dZdd Zdd Zd.ddZdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Z  ZS )/
TriangularaU  Triangular distribution with `low`, `high` and `peak` parameters.

  #### Mathematical Details

  The Triangular distribution is specified by two line segments in the plane,
  such that:

    * The first line segment starts at `(a, 0)` and ends at `(c, z)`.
    * The second line segment starts at `(c, z)` and ends at `(b, 0)`.

    ```none
    y

    ^
  z |           o  (c,z)
    |          / \
    |         /   \
    |        /     \
    | (a,0) /       \ (b,0)
  0 +------o---------o-------> x
    0      a    c    b
  ```

  where:
  * a <= c <= b, a < b
  * `low = a`,
  * `high = b`,
  * `peak = c`,
  * `z = 2 / (b - a)`

  The parameters `low`, `high` and `peak` must be shaped in a way that supports
  broadcasting (e.g., `high - low` is a valid operation).

  #### Examples

  ```python
  import tensorflow_probability as tfp; tfp = tfp.experimental.substrates.numpy
  tfd = tfp.distributions

  # Specify a single Triangular distribution.
  u1 = tfd.Triangular(low=3., high=4., peak=3.5)
  u1.mean()
  # ==> 3.5

  # Specify two different Triangular distributions.
  u2 = tfd.Triangular(low=[1., 2.], high=[3., 4.], peak=[2., 3.])
  u2.mean()
  # ==> [2., 3.]

  # Specify three different Triangular distributions by leveraging broadcasting.
  u3 = tfd.Triangular(low=3., high=[5., 6., 7.], peak=3.)
  u3.mean()
  # ==> [3.6666, 4., 4.3333]
  ```

                ?      ?FTc       	   	      s   t t }t|r}t|||gtj}tj|d|d| _	tj|d|d| _
tj|d|d| _tt| j| j	jtj||||d W dQ R X dS )a[  Initialize a batch of Triangular distributions.

    Args:
      low: Floating point tensor, lower boundary of the output interval. Must
        have `low < high`.
        Default value: `0`.
      high: Floating point tensor, upper boundary of the output interval. Must
        have `low < high`.
        Default value: `1`.
      peak: Floating point tensor, mode of the output interval. Must have
        `low <= peak` and `peak <= high`.
        Default value: `0.5`.
      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.
        Default value: `False`.
      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.
        Default value: `True`.
      name: Python `str` name prefixed to Ops created by this class.
        Default value: `'Triangular'`.

    Raises:
      InvalidArgumentError: if `validate_args=True` and one of the following is
        True:
        * `low >= high`.
        * `peak > high`.
        * `low > peak`.
    low)namedtypehighpeak)r   Zreparameterization_typevalidate_argsallow_nan_stats
parametersr   N)dictlocalstfZ
name_scoper	   Zcommon_dtypefloat32r   Zconvert_nonref_to_tensor_low_high_peaksuperr   __init__r   r
   ZFULLY_REPARAMETERIZED)	selfr   r   r   r   r   r   r   r   )	__class__ l/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow_probability/python/distributions/_numpy/triangular.pyr!   ]   s     '

zTriangular.__init__c             C   s   t ddddS )Nr   )r   r   r   )r   )clsr$   r$   r%   _params_event_ndims   s    zTriangular._params_event_ndimsc             C   s   | j S )zLower boundary of the interval.)r   )r"   r$   r$   r%   r      s    zTriangular.lowc             C   s   | j S )zUpper boundary of the interval.)r   )r"   r$   r$   r%   r      s    zTriangular.highc             C   s   | j S )z/Peak of the distribution. Lies in the interval.)r   )r"   r$   r$   r%   r      s    zTriangular.peakc             C   s   | j | j | j| j  S )zPdf evaluated at the peak.)r   r   r   )r"   r$   r$   r%   _pdf_at_peak   s    zTriangular._pdf_at_peakNc          
   C   sP   t t |d kr| jn|t t |d kr0| jn|t |d krF| jn|S )N)r   Zbroadcast_dynamic_shapeshaper   r   r   )r"   r   r   r   r$   r$   r%   _batch_shape_tensor   s
    zTriangular._batch_shape_tensorc             C   s    t | jjt | jj| jjS )N)r   Zbroadcast_static_shaper   r)   r   r   )r"   r$   r$   r%   _batch_shape   s    zTriangular._batch_shapec             C   s
   t g S )N)r   ZTensorShape)r"   r$   r$   r%   _event_shape   s    zTriangular._event_shapec       	   
   C   s   t | j}t | j}t | j}tj|dd}t j|g| j|||dgdd}tj	|| j
|d}|| }t ||| | k |t || ||   |t d| | ||   S )N
triangular)Zsalt)r   r   r   r   )Zaxis)r)   r   seedg      ?)r   convert_to_tensorr   r   r   r   Zsanitize_seedconcatr*   uniformr   wheresqrt)	r"   nr.   r   r   r   r)   Zsamplesinterval_lengthr$   r$   r%   	_sample_n   s    zTriangular._sample_nc             C   s   t | j}t | j}t | j}|| }t ||k||k@ d||  |||   d||  |||   }t ||k ||kB t ||S )Ng       @)r   r/   r   r   r   r2   
zeros_like)r"   xr   r   r   r5   result_inside_intervalr$   r$   r%   _prob   s    zTriangular._probc          	   C   s   t | j}t | j}t | j}|| }t ||k||k@ t j|||||   dt j|||||    }t ||k t ||}t ||kt 	||S )Ng      ?)
r   r/   r   r   r   r2   mathsquared_differencer7   Z	ones_like)r"   r8   r   r   r   r5   r9   Zresult_if_not_bigr$   r$   r%   _cdf   s    zTriangular._cdfc             C   s"   dt d tj| j| j  S )Ng      ?g       @)nplogr   r;   r   r   )r"   r$   r$   r%   _entropy   s    zTriangular._entropyc             C   s   | j | j | j d S )Ng      @)r   r   r   )r"   r$   r$   r%   _mean  s    zTriangular._meanc             C   sR   t | j}t | j}t | j}t j||t j|| t j|| d S )Ng      B@)r   r/   r   r   r   r;   r<   )r"   r   r   r   r$   r$   r%   	_variance  s
    zTriangular._variancec             C   s   t j| j| j| jdS )N)r   r   r   )sigmoid_bijectorZSigmoidr   r   r   )r"   r$   r$   r%   _default_event_space_bijector  s    z(Triangular._default_event_space_bijectorc             C   s   | j s
g S t| j}t| j}t| j}g }|t| jkrh|t| jkrh|t	j
||dd |t| jkr|t| jkr|t	j||dd |t| jkr|t| jkr|t	j||dd |S )Nz(triangular not defined when low >= high.)messagez'triangular not defined when low > peak.z(triangular not defined when peak > high.)r   r   r/   r   r   r   r   Zis_refappendr   Zassert_lessassert_less_equal)r"   Zis_initr   r   r   
assertionsr$   r$   r%   _parameter_control_dependencies  s*    z*Triangular._parameter_control_dependenciesc             C   sB   g }| j s|S |tj|| jdd |tj|| jdd |S )Nz.Sample must be greater than or equal to `low`.)rE   z,Sample must be less than or equal to `high`.)r   rF   r   Zassert_greater_equalr   rG   r   )r"   r8   rH   r$   r$   r%   _sample_control_dependencies*  s    z'Triangular._sample_control_dependencies)r   r   r   FTr   )NNN)N)__name__
__module____qualname____doc__r!   classmethodr'   propertyr   r   r   r(   r*   r+   r,   r6   r:   r=   r@   rA   rB   rD   rI   rJ   __classcell__r$   r$   )r#   r%   r   #   s0   8     2

	r   )rN   
__future__r   r   r   numpyr>   Z;tensorflow_probability.python.internal.backend.numpy.compatr   r   Z.tensorflow_probability.python.bijectors._numpyr   rC   Z2tensorflow_probability.python.distributions._numpyr   Z-tensorflow_probability.python.internal._numpyr   r	   Z&tensorflow_probability.python.internalr
   r   r   Distributionr   r$   r$   r$   r%   <module>   s   