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 G dd dejZe eedddZ!dS )zThe Pareto distribution class.    )absolute_import)division)print_functionN)v2)chain)shift)softplus)distribution)kullback_leibler)assert_util)distribution_util)
dtype_util)reparameterization)samplers)tensor_util)DeferredTensorc                   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dZ
dd Zdd Zd0ddZdd Zdd Zdd Zdd Zdd Zed d!d" Zed#d$d% Zd&d' Zd(d) Zd*d+ Zd,d- Z  ZS )1Paretoa  Pareto distribution.

  The Pareto distribution is parameterized by a `scale` and a
  `concentration` parameter.

  #### Mathematical Details

  The probability density function (pdf) is,

  ```none
  pdf(x; alpha, scale, x >= scale) = alpha * scale ** alpha / x ** (alpha + 1)
  ```

  where `concentration = alpha`.

  Note that `scale` acts as a scaling parameter, since
  `Pareto(c, scale).pdf(x) == Pareto(c, 1.).pdf(x / scale)`.

  The support of the distribution is defined on `[scale, infinity)`.
        ?FTc          	      s~   t t }t|` tj||gtjd}tj|d|d| _	tj|d|d| _
tt| j| j	jtj||||d W dQ R X dS )aG  Construct Pareto distribution with `concentration` and `scale`.

    Args:
      concentration: Floating point tensor. Must contain only positive values.
      scale: Floating point tensor, equivalent to `mode`. `scale` also
        restricts the domain of this distribution to be in `[scale, inf)`.
        Must contain only positive values. Default value: `1`.
      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` (i.e. do not validate args).
      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: 'Pareto'.
    )Z
dtype_hintconcentration)namedtypescale)r   Zreparameterization_typevalidate_argsallow_nan_stats
parametersr   N)dictlocalstf
name_scoper   Zcommon_dtypefloat32r   Zconvert_nonref_to_tensor_concentration_scalesuperr   __init__r   r   ZFULLY_REPARAMETERIZED)selfr   r   r   r   r   r   r   )	__class__ h/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow_probability/python/distributions/_numpy/pareto.pyr#   >   s    



zPareto.__init__c             C   s   t dddS )Nr   )r   r   )r   )clsr&   r&   r'   _params_event_ndimsg   s    zPareto._params_event_ndimsc             C   s   | j S )z8Scale parameter and also the lower bound of the support.)r!   )r$   r&   r&   r'   r   k   s    zPareto.scalec             C   s   | j S )z.Concentration parameter for this distribution.)r    )r$   r&   r&   r'   r   p   s    zPareto.concentrationNc             C   s4   t t |d kr| jn|t |d kr,| jn|S )N)r   Zbroadcast_dynamic_shapeshaper   r   )r$   r   r   r&   r&   r'   _batch_shape_tensoru   s    zPareto._batch_shape_tensorc             C   s   t | jj| jjS )N)r   Zbroadcast_static_shaper   r*   r   )r$   r&   r&   r'   _batch_shape{   s    zPareto._batch_shapec             C   s
   t g S )N)r   ZTensorShape)r$   r&   r&   r'   _event_shape~   s    zPareto._event_shapec             C   sr   t | j}t | j}t j|g| j||dgdd}tj|d|| jd}t j	
|t j	| |  }t |S )N)r   r   r   )Zaxisg      ?)maxvalseedr   )r   convert_to_tensorr   r   concatr+   r   uniformr   mathloglog1pexp)r$   nr/   r   r   r*   ZsampledZ
log_sampler&   r&   r'   	_sample_n   s    zPareto._sample_nc          	      sj   t | j t | jt | jr4tj|ddgng &  fdd}| j||t	j
 dS Q R X d S )Nz.`x` is not in the support of the distribution.)messagec                s0   t j  t j   d t j|   S )Ng      ?)r   r3   r4   )z)r   r   r&   r'   log_prob_on_support   s    z-Pareto._log_prob.<locals>.log_prob_on_support)alt)r   r0   r   r   control_dependenciesr   r   assert_greater_equal_extend_supportnpinf)r$   xr;   r&   )r   r   r'   	_log_prob   s     zPareto._log_probc          	      sf   t | j t | jt | jr4tj|ddgng "  fdd}| j||ddS Q R X d S )Nz.`x` is not in the support of the distribution.)r9   c                s       |  d   S )N   r&   )r:   )r   r   r&   r'   prob_on_support   s    z%Pareto._prob.<locals>.prob_on_supportg        )r<   )	r   r0   r   r   r=   r   r   r>   r?   )r$   rB   rE   r&   )r   r   r'   _prob   s     zPareto._probc                s,   t j j|  fddtj dS )Nc                s   t j |  j  S )N)r   r3   r5   r   )rB   )r   r$   r&   r'   <lambda>       z!Pareto._log_cdf.<locals>.<lambda>)r<   )r   r0   r   r?   r@   rA   )r$   rB   r&   )r   r$   r'   _log_cdf   s
    zPareto._log_cdfc                s(   t j j|  fddddS )Nc                s    t jjt j |    S )N)r   r3   expm1r   r4   )rB   )r   r$   r&   r'   rG      rH   zPareto._cdf.<locals>.<lambda>g        )r<   )r   r0   r   r?   )r$   rB   r&   )r   r$   r'   _cdf   s
    zPareto._cdfc                s*   t j j|  fddtjdS )Nc                s   j tj |   S )N)r   r   r3   r4   )rB   )r   r$   r&   r'   rG      rH   z/Pareto._log_survival_function.<locals>.<lambda>)r<   )r   r0   r   r?   r@   rA   )r$   rB   r&   )r   r$   r'   _log_survival_function   s
    zPareto._log_survival_functionzTThe mean of Pareto is defined` if `concentration > 1.`, otherwise it
      is `Inf`.c             C   s:   t | j}t |dk|| j |d  t| jtj	S )Ng      ?rD   )
r   r0   r   wherer   r   as_numpy_dtyper   r@   rA   )r$   r   r&   r&   r'   _mean   s    
zPareto._meanzXThe variance of Pareto is defined` if `concentration > 2.`, otherwise
      it is `Inf`.c             C   sN   t | j}| jd | |d d |d   }t |dk|t| jtj	S )N   g      ?g       @)
r   r0   r   r   rM   r   rN   r   r@   rA   )r$   r   Zvalid_variancer&   r&   r'   	_variance   s    
zPareto._variancec             C   s    t | j}t || j|dS )N)r   )r   r0   r   Zbroadcast_tor+   )r$   r   r&   r&   r'   _mode   s    zPareto._modec             C   s   | j r||S |dkr"t| jn|}||k }|t|||}|dkrZtjg |jd}n*|dkrttjg |jd}nt	| j|}t|||S )a  Returns `f(x)` if x is in the support, and `alt` otherwise.

    Given `f` which is defined on the support of this distribution
    (e.g. x > scale), extend the function definition to the real line
    by defining `f(x) = alt` for `x < scale`.

    Args:
      x: Floating-point Tensor to evaluate `f` at.
      scale: Floating-point Tensor by which to verify `x` validity.
      f: Lambda that takes in a tensor and returns a tensor. This represents the
        function who we want to extend the domain of definition.
      alt: Python or numpy literal representing the value to use for extending
        the domain.

    Returns:
      Tensor representing an extension of `f(x)`.
    Ng        )r   g      ?)
r   r   r0   r   rM   zerosr   Zonesr   rN   )r$   rB   r   fr<   Z
is_invalidyr&   r&   r'   r?      s    zPareto._extend_supportc             C   s^   | j s
g S g }|t| jkr4|tj| jdd |t| jkrZ|tj| jdd |S )Nz!`concentration` must be positive.)r9   z`scale` must be positive.)r   r   Zis_refr   appendr   Zassert_positiver   )r$   Zis_initZ
assertionsr&   r&   r'   _parameter_control_dependencies   s    z&Pareto._parameter_control_dependenciesc             C   s:   t | jdd }tjtj|| jdtj| jdg| jdS )Nc             S   s   | S )Nr&   )rB   r&   r&   r'   rG     rH   z6Pareto._default_event_space_bijector.<locals>.<lambda>)r   r   )r   )	r   r   chain_bijectorZChainshift_bijectorZShiftr   softplus_bijectorZSoftplus)r$   Zdeferred_scaler&   r&   r'   _default_event_space_bijector  s    
z$Pareto._default_event_space_bijector)r   FTr   )NN)N)__name__
__module____qualname____doc__r#   classmethodr)   propertyr   r   r+   r,   r-   r8   rC   rF   rI   rK   rL   r   ZAppendDocstringrO   rQ   rR   r?   rW   r[   __classcell__r&   r&   )r%   r'   r   (   s2      $

	 r   c          	   C   s   t |p
d t | j}t |j}t | j}t |j}t ||k|t j|t j|  t j| t j| ||  d t	| j
tjS Q R X dS )a4  Calculate the batched KL divergence KL(a || b) with a and b Pareto.

  Args:
    a: instance of a Pareto distribution object.
    b: instance of a Pareto distribution object.
    name: (optional) Name to use for created operations.
      default is 'kl_pareto_pareto'.

  Returns:
    Batchwise KL(a || b)
  Zkl_pareto_paretog      ?N)r   r   r0   r   r   rM   r3   r4   r   rN   r   r@   rA   )abr   Za_scaleZb_scaleZa_concentrationZb_concentrationr&   r&   r'   _kl_pareto_pareto  s    >re   )N)"r_   
__future__r   r   r   numpyr@   Z;tensorflow_probability.python.internal.backend.numpy.compatr   r   Z.tensorflow_probability.python.bijectors._numpyr   rX   r   rY   r   rZ   Z2tensorflow_probability.python.distributions._numpyr	   r
   Z-tensorflow_probability.python.internal._numpyr   r   r   Z&tensorflow_probability.python.internalr   r   r   Z9tensorflow_probability.python.util._numpy.deferred_tensorr   Distributionr   Z
RegisterKLre   r&   r&   r&   r'   <module>   s*    g
