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dlmZ ddlmZ dgZG dd„ dejƒZdS )zThe PERT distribution.é    )Úabsolute_import)Údivision)Úprint_functionN)Úv2)Úchain)Úscale)Úshift)Úsigmoid)Úbeta)Údistribution)Útransformed_distribution)Úassert_util)Ú
dtype_util)Úprefer_static)Úreparameterization)Útensor_utilÚPERTc                   sÜ   e Zd ZdZd/‡ fdd„	Zd0dd„Ze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d1dd„Zd2d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d+d,„ Zd-d.„ Z‡  ZS )3r   a/  Modified PERT distribution for modeling expert predictions.

  The PERT distribution is a loc-scale family of Beta distributions
  fit onto a real interval between `low` and `high` values set by the user,
  along with a `peak` to indicate the expert's most frequent prediction.
  [1](https://en.wikipedia.org/wiki/PERT_distribution), and `temperature` to
  control how sharp the peak is.

  The distribution is similar to a [Triangular distribution]
  (https://en.wikipedia.org/wiki/Triangular_distribution)
  (i.e. `tfd.Triangular`) but with a smooth peak.

  #### Mathematical Details

  In terms of a Beta distribution, PERT can be expressed as

  ```none
  PERT ~ loc + scale * Beta(concentration1, concentration0)
  ```
  where

  ```none
  loc = low
  scale = high - low
                                      peak - low
  concentration1 = 1 + temperature * ------------
                                      high - low

                                      high - peak
  concentration0 = 1 + temperature * ------------
                                      high - low
  temperature > 0
  ```
  The support is `[low, high]`.  The `peak` must fit in that interval:
  `low < peak < high`.  The `temperature` is a positive parameter that
  controls the shape of the distribution. Higher values yield a sharper peak.

  The standard PERT distribution is obtained when `temperature = 4`.

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

  # Single PERT distribution
  dist = tfd.PERT(low=1., peak=7., high=11., temperature=4.)
  dist.sample(10)
  dist.prob(7.)
  dist.prob(0.) # Returns nan when the input is outside the support.

  # Multiple PERT distributions with varying temperature (broadcasted)
  dist = tfd.PERT(low=1., peak=7., high=11., temperature=[1., 2., 3., 4.])
  dist.sample(10)
  dist.prob(7.)
  dist.prob([[7.],[5.]])

  # Multiple PERT distributions with varying peak
  dist = tfd.PERT(low=1., peak=[2., 5., 8.], high=11., temperature=4.)
  dist.sample(10)
  dist.sample([10, 5])
  ```
  ç      @Fc       
   	      s    t tƒ ƒ}t |¡‚}t ||||gtj¡}	tj|d|	d| _	tj|d|	d| _
tj|d|	d| _tj|d|	d| _tt| ƒj||tj||	|d W d Q R X d S )NÚlow)ÚnameÚdtypeÚpeakÚhighÚtemperature)Úvalidate_argsÚallow_nan_statsZreparameterization_typeÚ
parametersr   r   )ÚdictÚlocalsÚtfZ
name_scoper   Zcommon_dtypeÚfloat32r   Zconvert_nonref_to_tensorÚ_lowÚ_peakÚ_highÚ_temperatureÚsuperr   Ú__init__r   ZFULLY_REPARAMETERIZED)
Úselfr   r   r   r   r   r   r   r   r   )Ú	__class__© úf/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow_probability/python/distributions/_numpy/pert.pyr&   l   s&    

zPERT.__init__Nc             C   sÔ   |d krt  | j¡n|}|d kr,t  | j¡n|}|d krDt  | j¡n|}|d kr\t  | j¡n|}|| }d|||  |  }d|||  |  }tjtj	||| j
dt tj|dtjt  |t |¡¡dg¡dS )Ng      ð?)Úconcentration1Úconcentration0r   )r   )r   )r   Zbijector)r   Úconvert_to_tensorr   r   r   r   r   ZTransformedDistributionr
   ÚBetar   Úchain_bijectorZChainÚshift_bijectorZShiftÚscale_bijectorZScaleZbroadcast_tor   Úshape)r'   r   r   r   r   r   r+   r,   r)   r)   r*   Ú_transformed_beta‰   s"    
zPERT._transformed_betac             C   s   t dddddS )Nr   )r   r   r   r   )r   )Úclsr)   r)   r*   Ú_params_event_ndims¢   s    zPERT._params_event_ndimsc             C   s   | j S )N)r!   )r'   r)   r)   r*   r   §   s    zPERT.lowc             C   s   | j S )N)r"   )r'   r)   r)   r*   r   «   s    z	PERT.peakc             C   s   | j S )N)r#   )r'   r)   r)   r*   r   ¯   s    z	PERT.highc             C   s   | j S )N)r$   )r'   r)   r)   r*   r   ³   s    zPERT.temperaturec             C   s   dS )Nr)   r)   )r'   r)   r)   r*   Ú_event_shape·   s    zPERT._event_shapec             C   s&   t  tj| jj| jj| jj| jjf¡S )N)	Ú	functoolsÚreducer   Zbroadcast_static_shaper   r2   r   r   r   )r'   r)   r)   r*   Ú_batch_shapeº   s    zPERT._batch_shapec          
   C   sf   t  tjt |d kr| jn|¡t |d kr0| jn|¡t |d krF| jn|¡t |d kr\| jn|¡f¡S )N)	r7   r8   r   Zbroadcast_shaper2   r   r   r   r   )r'   r   r   r   r   r)   r)   r*   Ú_batch_shape_tensor¿   s    zPERT._batch_shape_tensorc             C   s   |   ¡ j||dS )N)Úseed)r3   Úsample)r'   Únr;   r)   r)   r*   Ú	_sample_nÌ   s    zPERT._sample_nc             C   s   |   ¡  |¡S )N)r3   Zlog_prob)r'   Úxr)   r)   r*   Ú	_log_probÏ   s    zPERT._log_probc             C   s   |   ¡  |¡S )N)r3   Zlog_cdf)r'   r?   r)   r)   r*   Ú_log_cdfÒ   s    zPERT._log_cdfc             C   s   |   ¡  ¡ S )N)r3   Zentropy)r'   r)   r)   r*   Ú_entropyÕ   s    zPERT._entropyc             C   s   |   ¡  ¡ S )N)r3   Úmean)r'   r)   r)   r*   Ú_meanØ   s    z
PERT._meanc             C   s   t  | j¡S )N)r   r-   r   )r'   r)   r)   r*   Ú_modeÛ   s    z
PERT._modec             C   sP   t  | j¡}t  | j¡}t  | j¡}| j|||d ¡ }|| ||  |d  S )N)r   r   r   g      @)r   r-   r   r   r   r3   rC   )r'   r   r   r   rC   r)   r)   r*   Ú	_varianceÞ   s    zPERT._variancec             C   s   |   ¡  |¡S )N)r3   Zquantile)r'   Úvaluer)   r)   r*   Ú	_quantileç   s    zPERT._quantilec             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"PERT._default_event_space_bijectorc             C   s°   | j s
g S g }d }|t | j¡krFt | j¡}| tj	|| jdd¡ |t | j
¡kr†|d krjt | j¡n|}| tj	| j
|dd¡ |t | j¡kr¬| tj| jdd¡ |S )Nz"`peak` must be greater than `low`.)Úmessagez#`high` must be greater than `peak`.z`temperature` must be positive.)r   r   Zis_refr   r   r-   r   Úappendr   Zassert_greaterr   r   Zassert_positive)r'   Zis_initÚ
assertionsr   r)   r)   r*   Ú_parameter_control_dependenciesî   s&    z$PERT._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`.)rK   z,Sample must be less than or equal to `high`.)r   rL   r   Zassert_greater_equalr   Zassert_less_equalr   )r'   r?   rM   r)   r)   r*   Ú_sample_control_dependencies  s    

z!PERT._sample_control_dependencies)r   FFr   )NNNN)NNNN)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r&   r3   Úclassmethodr5   Úpropertyr   r   r   r   r6   r9   r:   r>   r@   rA   rB   rD   rE   rF   rH   rJ   rN   rO   Ú__classcell__r)   r)   )r(   r*   r   ,   s8   >   
   
	
	) rS   Ú
__future__r   r   r   r7   Z;tensorflow_probability.python.internal.backend.numpy.compatr   r   Z.tensorflow_probability.python.bijectors._numpyr   r/   r   r1   r   r0   r	   rI   Z2tensorflow_probability.python.distributions._numpyr
   r   r   Z-tensorflow_probability.python.internal._numpyr   r   r   Z&tensorflow_probability.python.internalr   r   Ú__all__ÚDistributionr   r)   r)   r)   r*   Ú<module>   s&   