o
    ?e/                     @   s  d 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dlmZ ddlmZ ddgZedgdG dd dejZG dd deZeeedddZdS )zThe Gamma distribution class.    N)constant_op)dtypes)ops)tensor_shape)	array_ops)	check_ops)control_flow_ops)math_ops)nn)
random_ops)distribution)kullback_leibler)util)deprecation)	tf_exportGamma"GammaWithSoftplusConcentrationRatezdistributions.Gamma)v1c                       s   e Zd ZdZejdddd			 d0 f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edd1d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ed+d,d- Zd.d/ Z  ZS )2r   a	  Gamma distribution.

  The Gamma distribution is defined over positive real numbers using
  parameters `concentration` (aka "alpha") and `rate` (aka "beta").

  #### Mathematical Details

  The probability density function (pdf) is,

  ```none
  pdf(x; alpha, beta, x > 0) = x**(alpha - 1) exp(-x beta) / Z
  Z = Gamma(alpha) beta**(-alpha)
  ```

  where:

  * `concentration = alpha`, `alpha > 0`,
  * `rate = beta`, `beta > 0`,
  * `Z` is the normalizing constant, and,
  * `Gamma` is the [gamma function](
    https://en.wikipedia.org/wiki/Gamma_function).

  The cumulative density function (cdf) is,

  ```none
  cdf(x; alpha, beta, x > 0) = GammaInc(alpha, beta x) / Gamma(alpha)
  ```

  where `GammaInc` is the [lower incomplete Gamma function](
  https://en.wikipedia.org/wiki/Incomplete_gamma_function).

  The parameters can be intuited via their relationship to mean and stddev,

  ```none
  concentration = alpha = (mean / stddev)**2
  rate = beta = mean / stddev**2 = concentration / mean
  ```

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

  Warning: The samples of this distribution are always non-negative. However,
  the samples that are smaller than `np.finfo(dtype).tiny` are rounded
  to this value, so it appears more often than it should.
  This should only be noticeable when the `concentration` is very small, or the
  `rate` is very large. See note in `tf.random.gamma` docstring.

  Samples of this distribution are reparameterized (pathwise differentiable).
  The derivatives are computed using the approach described in
  (Figurnov et al., 2018).

  #### Examples

  ```python
  import tensorflow_probability as tfp
  tfd = tfp.distributions

  dist = tfd.Gamma(concentration=3.0, rate=2.0)
  dist2 = tfd.Gamma(concentration=[3.0, 4.0], rate=[2.0, 3.0])
  ```

  Compute the gradients of samples w.r.t. the parameters:

  ```python
  concentration = tf.constant(3.0)
  rate = tf.constant(2.0)
  dist = tfd.Gamma(concentration, rate)
  samples = dist.sample(5)  # Shape [5]
  loss = tf.reduce_mean(tf.square(samples))  # Arbitrary loss function
  # Unbiased stochastic gradients of the loss function
  grads = tf.gradients(loss, [concentration, rate])
  ```

  References:
    Implicit Reparameterization Gradients:
      [Figurnov et al., 2018]
      (http://papers.nips.cc/paper/7326-implicit-reparameterization-gradients)
      ([pdf](http://papers.nips.cc/paper/7326-implicit-reparameterization-gradients.pdf))
  
2019-01-01zThe TensorFlow Distributions library has moved to TensorFlow Probability (https://github.com/tensorflow/probability). You should update all references to use `tfp.distributions` instead of `tf.distributions`.TZ	warn_onceFc              	      s   t t }tj|||gdB}t|rt|t|gng ! tj|dd| _	tj|dd| _
t| j	| j
g W d   n1 sDw   Y  W d   n1 sSw   Y  tt| j| j	j||tj|| j	| j
g|d dS )a  Construct Gamma with `concentration` and `rate` parameters.

    The parameters `concentration` and `rate` must be shaped in a way that
    supports broadcasting (e.g. `concentration + rate` is a valid operation).

    Args:
      concentration: Floating point tensor, the concentration params of the
        distribution(s). Must contain only positive values.
      rate: Floating point tensor, the inverse scale params of the
        distribution(s). Must contain only positive values.
      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.

    Raises:
      TypeError: if `concentration` and `rate` are different dtypes.
    valuesconcentrationnamerateN)dtypevalidate_argsallow_nan_statsZreparameterization_type
parametersZgraph_parentsr   )dictlocalsr   
name_scopeZcontrol_dependenciesr   assert_positiver   identity_concentration_rateassert_same_float_dtypesuperr   __init__r   r   ZFULLY_REPARAMETERIZEDselfr   r   r   r   r   r   	__class__ j/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/ops/distributions/gamma.pyr)   |   s>   
%



zGamma.__init__c                 C   s    t tdtj| tjdgd S )Nr   r   r      )r    zipr   Zconvert_to_tensorr   int32)Zsample_shaper.   r.   r/   _param_shapes   s   zGamma._param_shapesc                 C      | j S )zConcentration parameter.)r%   r+   r.   r.   r/   r         zGamma.concentrationc                 C   r6   )zRate parameter.)r&   r7   r.   r.   r/   r      r8   z
Gamma.ratec                 C   s   t t | jt | jS N)r   Zbroadcast_dynamic_shapeshaper   r   r7   r.   r.   r/   _batch_shape_tensor   s   

zGamma._batch_shape_tensorc                 C   s   t | j | j S r9   )r   Zbroadcast_static_shaper   	get_shaper   r7   r.   r.   r/   _batch_shape   s   zGamma._batch_shapec                 C   s   t jg tjdS )Nr1   )r   Zconstantr   r4   r7   r.   r.   r/   _event_shape_tensor   s   zGamma._event_shape_tensorc                 C   s
   t g S r9   )r   ZTensorShaper7   r.   r.   r/   _event_shape   s   
zGamma._event_shapezMNote: See `tf.random.gamma` docstring for sampling details and
      caveats.Nc                 C   s   t j|g| j| j| j|dS )N)r:   alphabetar   seed)r   Zrandom_gammar   r   r   )r+   nrB   r.   r.   r/   	_sample_n   s   zGamma._sample_nc                 C   s   |  ||   S r9   )_log_unnormalized_prob_log_normalizationr+   xr.   r.   r/   	_log_prob      zGamma._log_probc                 C   s   |  |}t| j| j| S r9   )_maybe_assert_valid_sampler	   Zigammar   r   rG   r.   r.   r/   _cdf   s   
z
Gamma._cdfc                 C   s&   |  |}t| jd || j|  S N      ?)rK   r	   Zxlogyr   r   rG   r.   r.   r/   rE      s   
zGamma._log_unnormalized_probc                 C   s   t | j| jt | j  S r9   )r	   lgammar   logr   r7   r.   r.   r/   rF      s   
zGamma._log_normalizationc                 C   s4   | j t| j t| j  d| j  t| j   S rM   )r   r	   rP   r   rO   digammar7   r.   r.   r/   _entropy   s   


zGamma._entropyc                 C   s   | j | j S r9   r0   r7   r.   r.   r/   _mean   s   zGamma._meanc                 C   s   | j t| j S r9   )r   r	   Zsquarer   r7   r.   r.   r/   	_variance   rJ   zGamma._variancec                 C   s   t | j| j S r9   )r	   sqrtr   r   r7   r.   r.   r/   _stddev   rJ   zGamma._stddevzThe mode of a gamma distribution is `(shape - 1) / rate` when
      `shape > 1`, and `NaN` otherwise. If `self.allow_nan_stats` is `False`,
      an exception will be raised rather than returning `NaN`.c                 C   sv   | j d | j }| jr(tj|  tjtj| j	
 ddd}t| j dk||S ttjtg | j	| j ddg|S )NrN   r1   nanr   z,mode not defined when any concentration <= 1)message)r   r   r   r   fillZbatch_shape_tensornparrayrW   r   Zas_numpy_dtypeZwhere_v2r   with_dependenciesr   Zassert_lessZones)r+   moderW   r.   r.   r/   _mode  s"   zGamma._modec                 C   s0   t j|g| jd | js|S tt |g|S )N)Ztensorsr   )r   r'   r   r   r   r\   r#   rG   r.   r.   r/   rK     s   z Gamma._maybe_assert_valid_sample)FTr   r9   )__name__
__module____qualname____doc__r   
deprecatedr)   staticmethodr5   propertyr   r   r;   r=   r>   r?   distribution_utilZAppendDocstringrD   rI   rL   rE   rF   rR   rS   rT   rV   r^   rK   __classcell__r.   r.   r,   r/   r   *   sL    P2



c                       s8   e Zd ZdZejdddd			 d	 fdd	Z  ZS )
r   z4`Gamma` with softplus of `concentration` and `rate`.r   zMUse `tfd.Gamma(tf.nn.softplus(concentration), tf.nn.softplus(rate))` instead.Tr   Fc                    st   t t }tj|||gd}tt| jtj|ddtj|dd|||d W d    n1 s0w   Y  || _	d S )Nr   Zsoftplus_concentrationr   Zsoftplus_rate)r   r   r   r   r   )
r    r!   r   r"   r(   r   r)   r
   Zsoftplus_parametersr*   r,   r.   r/   r)   "  s   


z+GammaWithSoftplusConcentrationRate.__init__)FTr   )r_   r`   ra   rb   r   rc   r)   rg   r.   r.   r,   r/   r     s    c                 C   s   t j|d| j| j|j|jgd= | j|j t| j t|j t| j |jt| j  |jt|j  | j|j| j d   W  d   S 1 sPw   Y  dS )aV  Calculate the batched KL divergence KL(g0 || g1) with g0 and g1 Gamma.

  Args:
    g0: instance of a Gamma distribution object.
    g1: instance of a Gamma distribution object.
    name: (optional) Name to use for created operations.
      Default is "kl_gamma_gamma".

  Returns:
    kl_gamma_gamma: `Tensor`. The batchwise KL(g0 || g1).
  Zkl_gamma_gammar   rN   N)r   r"   r   r   r	   rQ   rO   rP   )Zg0g1r   r.   r.   r/   _kl_gamma_gamma9  s"   




$rj   r9   )rb   numpyrZ   Ztensorflow.python.frameworkr   r   r   r   Ztensorflow.python.opsr   r   r   r	   r
   r   Z#tensorflow.python.ops.distributionsr   r   r   rf   Ztensorflow.python.utilr   Z tensorflow.python.util.tf_exportr   __all__Distributionr   r   Z
RegisterKLrj   r.   r.   r.   r/   <module>   s4   
 u
