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dZdd ZG dd dejZdS )z#The Kumaraswamy distribution class.    )absolute_import)division)print_functionN)v2)_numpy)invert)kumaraswamy_cdf)sigmoid)transformed_distribution)uniform)assert_util)distribution_util)
dtype_util)tensor_utilKumaraswamyzuNote: `x` must have dtype `self.dtype` and be in
`[0, 1].` It must have a shape compatible with `self.batch_shape()`.c             C   s,   t jg | jd}t j| | t j| S )av  Compute the harmonic number from its analytic continuation.

  Derivation from [here](
  https://en.wikipedia.org/wiki/Digamma_function#Relation_to_harmonic_numbers)
  and [Euler's constant](
  https://en.wikipedia.org/wiki/Euler%E2%80%93Mascheroni_constant).

  Args:
    x: input float.

  Returns:
    z: The analytic continuation of the harmonic number for the input.
  )dtype)tfonesr   mathZdigamma)xZone r   m/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow_probability/python/distributions/_numpy/kumaraswamy.py_harmonic_number,   s    r   c                   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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   au  Kumaraswamy distribution.

  The Kumaraswamy distribution is defined over the `(0, 1)` interval using
  parameters
  `concentration1` (aka 'alpha') and `concentration0` (aka 'beta').  It has a
  shape similar to the Beta distribution, but is easier to reparameterize.

  #### Mathematical Details

  The probability density function (pdf) is,

  ```none
  pdf(x; alpha, beta) = alpha * beta * x**(alpha - 1) * (1 - x**alpha)**(beta -
  1)
  ```

  where:

  * `concentration1 = alpha`,
  * `concentration0 = beta`,

  Distribution parameters are automatically broadcast in all functions; see
  examples for details.

  #### Examples

  ```python
  # Create a batch of three Kumaraswamy distributions.
  alpha = [1, 2, 3]
  beta = [1, 2, 3]
  dist = Kumaraswamy(alpha, beta)

  dist.sample([4, 5])  # Shape [4, 5, 3]

  # `x` has three batch entries, each with two samples.
  x = [[.1, .4, .5],
       [.2, .3, .5]]
  # Calculate the probability of each pair of samples under the corresponding
  # distribution in `dist`.
  dist.prob(x)         # Shape [2, 3]
  ```

  ```python
  # Create batch_shape=[2, 3] via parameter broadcast:
  alpha = [[1.], [2]]      # Shape [2, 1]
  beta = [3., 4, 5]        # Shape [3]
  dist = Kumaraswamy(alpha, beta)

  # alpha broadcast as: [[1., 1, 1,],
  #                      [2, 2, 2]]
  # beta broadcast as:  [[3., 4, 5],
  #                      [3, 4, 5]]
  # batch_Shape [2, 3]
  dist.sample([4, 5])  # Shape [4, 5, 2, 3]

  x = [.2, .3, .5]
  # x will be broadcast as [[.2, .3, .5],
  #                         [.2, .3, .5]],
  # thus matching batch_shape [2, 3].
  dist.prob(x)         # Shape [2, 3]
  ```

        ?FTc       	   	      s   t t }t|}tj||gtjd}tj|d|d}tj|d|d}t	j
|||d| _t||}tt| jtjtj||dtjg |d|dtj| j|d||d	 W d
Q R X d
S )a@  Initialize a batch of Kumaraswamy distributions.

    Args:
      concentration1: Positive floating-point `Tensor` indicating mean
        number of successes; aka 'alpha'. Implies `self.dtype` and
        `self.batch_shape`, i.e.,
        `concentration1.shape = [N1, N2, ..., Nm] = self.batch_shape`.
      concentration0: Positive floating-point `Tensor` indicating mean
        number of failures; aka 'beta'. Otherwise has same semantics as
        `concentration1`.
      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.
    )Z
dtype_hintconcentration1)namer   concentration0)r   r   validate_args)r   )lowhighallow_nan_stats)r   )distributionbijector
parametersr   N)dictlocalsr   Z
name_scoper   Zcommon_dtypefloat32r   Zconvert_nonref_to_tensorr   ZKumaraswamyCDF_kumaraswamy_cdfr   Zget_broadcast_shapesuperr   __init__r   ZUniformzerosr   r   ZInvert)	selfr   r   r   r    r   r#   r   Zbatch_shape)	__class__r   r   r)      s.    





zKumaraswamy.__init__c             C   s   t dddS )Nr   )r   r   )r$   )clsr   r   r   _params_event_ndims   s    zKumaraswamy._params_event_ndimsc             C   s   | j jS )z6Concentration parameter associated with a `1` outcome.)r'   r   )r+   r   r   r   r      s    zKumaraswamy.concentration1c             C   s   | j jS )z6Concentration parameter associated with a `0` outcome.)r'   r   )r+   r   r   r   r      s    zKumaraswamy.concentration0c             C   sP   t | j}t | j}dd|  dd|  t|  t j| t j| S )N   g      ?)r   convert_to_tensorr   r   r   r   log)r+   abr   r   r   _entropy   s    zKumaraswamy._entropyc             C   s    t | jtj|| j   S )N)tfp_mathZlog1mexpr   r   r   log1pr   )r+   r   r   r   r   _log_cdf   s    zKumaraswamy._log_cdfNc             C   s   |dkrt | jn|}|dkr,t | jn|}|| }t |t |}t |t |}d||  }t j|t	|| S )z%Compute the n'th (uncentered) moment.Nr/   )
r   r0   r   r   Zbroadcast_toshaper   r1   r5   Zlbeta)r+   nr   r   Ztotal_concentrationZexpanded_concentration1Zexpanded_concentration0Zbeta_argr   r   r   _log_moment   s    
zKumaraswamy._log_momentc             C   s   t | dS )Nr/   )r   expr:   )r+   r   r   r   _mean   s    zKumaraswamy._meanc             C   sr   t | j}t | j}| jd||d}| jd||d}tjt j|d| gddddgddd\}}|t | S )	N   )r   r   r/   )axisg      ?T)r?   Zreturn_sign)	r   r0   r   r   r:   r5   Zreduce_weighted_logsumexpstackr;   )r+   r   r   Zlog_moment2Zlog_moment1Zlswesignr   r   r   	_variance   s    zKumaraswamy._variancea  Note: The mode is undefined when `concentration1 <= 1` or
      `concentration0 <= 1`. If `self.allow_nan_stats` is `True`, `NaN`
      is used for undefined modes. If `self.allow_nan_stats` is `False` an
      exception is raised when one or more modes are undefined.c             C   s   t | j}t | j}|d || d  d|  }| jrbt |dk|dk@ |t| jt	j
S ttjt jg |jd|ddtjt jg |jd|ddg|S )Nr/   g      ?)r   z'Mode undefined for concentration1 <= 1.)messagez'Mode undefined for concentration0 <= 1.)r   r0   r   r   r    wherer   Zas_numpy_dtyper   npnanr   Zwith_dependenciesr   Zassert_lessr   )r+   r2   r3   moder   r   r   _mode   s     zKumaraswamy._modec             C   s   t j| jdS )N)r   )sigmoid_bijectorZSigmoidr   )r+   r   r   r   _default_event_space_bijector  s    z)Kumaraswamy._default_event_space_bijectorc             C   s   | j j |S )N)r"   _parameter_control_dependencies)r+   Zis_initr   r   r   rK     s    z+Kumaraswamy._parameter_control_dependenciesc             C   sF   g }| j s|S |tj|dd |tj|tg |jdd |S )z Checks the validity of a sample.zSample must be non-negative.)rC   z)Sample must be less than or equal to `1`.)r   appendr   Zassert_non_negativeZassert_less_equalr   r   r   )r+   r   Z
assertionsr   r   r   _sample_control_dependencies	  s    
z(Kumaraswamy._sample_control_dependencies)r   r   FTr   )NN)__name__
__module____qualname____doc__r)   classmethodr.   propertyr   r   r4   r7   r:   r<   rB   r   ZAppendDocstringrH   rJ   rK   rM   __classcell__r   r   )r,   r   r   >   s&   ?    /
)rQ   
__future__r   r   r   numpyrE   Z;tensorflow_probability.python.internal.backend.numpy.compatr   r   Z"tensorflow_probability.python.mathr   r5   Z.tensorflow_probability.python.bijectors._numpyr   r   r	   rI   Z2tensorflow_probability.python.distributions._numpyr
   r   Z-tensorflow_probability.python.internal._numpyr   r   r   r   __all__Z_kumaraswamy_sample_noter   ZTransformedDistributionr   r   r   r   r   <module>   s&   