
    AVh=:                     ^   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dZ edg       G d dej4                               Z G d de      Z ej:                  ee      dd       Zy)zThe Beta 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BetaBetaWithSoftplusConcentrationzuNote: `x` must have dtype `self.dtype` and be in
`[0, 1].` It must have a shape compatible with `self.batch_shape()`.zdistributions.Beta)v1c                       e Zd ZdZ ej
                  ddd      	 	 	 	 	 d fd	       Zed        Ze	d        Z
e	d	        Ze	d
        Zd Zd Zd Zd ZddZ ej&                  e      d        Z ej&                  e      d        Z ej&                  e      d        Z ej&                  e      d        Zd Zd Zd Zd Zd Z ej&                  d      d        Zd Zd Z  xZ!S )r   a`  Beta distribution.

  The Beta distribution is defined over the `(0, 1)` interval using parameters
  `concentration1` (aka "alpha") and `concentration0` (aka "beta").

  #### Mathematical Details

  The probability density function (pdf) is,

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

  where:

  * `concentration1 = alpha`,
  * `concentration0 = beta`,
  * `Z` is the normalization constant, and,
  * `Gamma` is the [gamma function](
    https://en.wikipedia.org/wiki/Gamma_function).

  The concentration parameters represent mean total counts of a `1` or a `0`,
  i.e.,

  ```none
  concentration1 = alpha = mean * total_concentration
  concentration0 = beta  = (1. - mean) * total_concentration
  ```

  where `mean` in `(0, 1)` and `total_concentration` is a positive real number
  representing a mean `total_count = concentration1 + concentration0`.

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

  Warning: The samples can be zero due to finite precision.
  This happens more often when some of the concentrations are very small.
  Make sure to round the samples to `np.finfo(dtype).tiny` before computing the
  density.

  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

  # Create a batch of three Beta distributions.
  alpha = [1, 2, 3]
  beta = [1, 2, 3]
  dist = tfd.Beta(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 = tfd.Beta(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]
  ```

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

  ```python
  alpha = tf.constant(1.0)
  beta = tf.constant(2.0)
  dist = tfd.Beta(alpha, beta)
  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, [alpha, beta])
  ```

  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	warn_oncec           
         t        t                     }t        j                  |||g      5 }| j	                  t        j
                  |d      |      | _        | j	                  t        j
                  |d      |      | _        t        j                  | j                  | j                  g       | j                  | j                  z   | _
        ddd       t        t        | 7  | j                  j                  ||t        j                   || j                  | j                  | j                  g|       y# 1 sw Y   gxY w)a9  Initialize a batch of Beta 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.
    valuesconcentration1nameconcentration0N)dtypevalidate_argsallow_nan_statsreparameterization_type
parametersgraph_parentsr   )dictlocalsr   
name_scope!_maybe_assert_valid_concentrationconvert_to_tensor_concentration1_concentration0r   assert_same_float_dtype_total_concentrationsuperr   __init__r    r   FULLY_REPARAMETERIZEDselfr   r   r!   r"   r   r$   	__class__s          X/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/distributions/beta.pyr0   zBeta.__init__   s*   D fhJ	nn%E	F 	N$!CC


5E
F
d "CC


5E
F
d ''


 4 4)6 7"&"6"69M9M"Md	N 
$''--#' , B B++++002   		N 	Ns   B"D66D?c           	      ~    t        t        ddgt        j                  | t        j
                        gdz              S )Nr   r   r       )r&   zipr   r*   r   int32)sample_shapes    r5   _param_shapeszBeta._param_shapes   s>    	+,			|6<<	@AAEG H H    c                     | j                   S )z6Concentration parameter associated with a `1` outcome.)r+   r3   s    r5   r   zBeta.concentration1        r=   c                     | j                   S )z6Concentration parameter associated with a `0` outcome.)r,   r?   s    r5   r   zBeta.concentration0   r@   r=   c                     | j                   S )z Sum of concentration parameters.)r.   r?   s    r5   total_concentrationzBeta.total_concentration   s     $$$r=   c                 @    t        j                  | j                        S N)r   shaperC   r?   s    r5   _batch_shape_tensorzBeta._batch_shape_tensor   s    ??43344r=   c                 6    | j                   j                         S rE   )rC   	get_shaper?   s    r5   _batch_shapezBeta._batch_shape   s    ##--//r=   c                 L    t        j                  g t        j                        S )Nr7   )r   constantr   r:   r?   s    r5   _event_shape_tensorzBeta._event_shape_tensor   s    &,,77r=   c                 ,    t        j                  g       S rE   )r   TensorShaper?   s    r5   _event_shapezBeta._event_shape   s    ##B''r=   c           	         t        j                  | j                  | j                        | j                  z  }t        j                  | j                  | j                        | j
                  z  }t        j                  |g|| j                  |      }t        j                  |g|| j                  t        j                  |d            }|||z   z  }|S )Nr7   )rF   alphar    seedbeta)
r   	ones_likerC   r    r   r   r   random_gammadistribution_utilgen_new_seed)r3   nrS   expanded_concentration1expanded_concentration0gamma1_samplegamma2_samplebeta_samples           r5   	_sample_nzBeta._sample_n   s    '11  

46:6I6IJ'11  

46:6I6IJ++c%jj	M
 ++c%jj++D&9	;M
  ==#@AKr=   c                 F    | j                  |      | j                         z
  S rE   )_log_unnormalized_prob_log_normalizationr3   xs     r5   	_log_probzBeta._log_prob  s!    &&q)D,C,C,EEEr=   c                 J    t        j                  | j                  |            S rE   )r
   expre   rc   s     r5   _probz
Beta._prob	  s    <<q)**r=   c                 J    t        j                  | j                  |            S rE   )r
   log_cdfrc   s     r5   _log_cdfzBeta._log_cdf  s    <<		!%%r=   c                 X    t        j                  | j                  | j                  |      S rE   )r
   betaincr   r   rc   s     r5   rk   z	Beta._cdf  s#    D//1D1DaHHr=   c                     | j                  |      }t        j                  | j                  dz
  |      | j                  dz
  t        j
                  |       z  z   S N      ?)_maybe_assert_valid_sampler
   xlogyr   r   log1prc   s     r5   ra   zBeta._log_unnormalized_prob  sS    ''*ANN4..3Q7  2%);;< =r=   c                     t        j                  | j                        t        j                  | j                        z   t        j                  | j                        z
  S rE   )r
   lgammar   r   rC   r?   s    r5   rb   zBeta._log_normalization  sG    OOD//0ood1123ood6678 9r=   c                 B   | j                         | j                  dz
  t        j                  | j                        z  z
  | j                  dz
  t        j                  | j                        z  z
  | j
                  dz
  t        j                  | j
                        z  z   S )Nrq          @)rb   r   r
   digammar   rC   r?   s    r5   _entropyzBeta._entropy  s    !#x'7'78K8K'L
L	M#x'7'78K8K'L
L	M $$r)D4456	78r=   c                 4    | j                   | j                  z  S rE   )r+   r.   r?   s    r5   _meanz
Beta._mean'  s    $";";;;r=   c                 j    | j                         d| j                         z
  z  d| j                  z   z  S rp   )r|   rC   r?   s    r5   	_variancezBeta._variance*  s.    ::<2

,-d6N6N1NOOr=   a  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           	         | j                   dz
  | j                  dz
  z  }| j                  rt        j                  | j                         t        j                  t        j                  | j                  j                               d      }t        j                  | j                   dkD  | j                  dkD        }t        j                  |||      S t        j                   t#        j$                  t        j&                  g | j                        | j                   d      t#        j$                  t        j&                  g | j                        | j                  d      g|      S )	Nrq   rx   r7   nanr   z'Mode undefined for concentration1 <= 1.messagez'Mode undefined for concentration0 <= 1.)r   rC   r"   r   fillbatch_shape_tensornparrayr   r    as_numpy_dtyper
   logical_andr   where_v2r	   with_dependenciesr   assert_lessones)r3   moder   
is_defineds       r5   _modez
Beta._mode-  s#    "$)A)AB)FGDNN

!
!
#
((266!:!:!<
=c ''(;(;b(@(,(;(;b(@Bj
D#66--NN2TZZ0=	? 	NN2TZZ0=	?	/ 	 	r=   c                 b    |s|S t        j                  t        j                  |d      g|      S )z1Checks the validity of a concentration parameter.z)Concentration parameter must be positive.r   )r	   r   r   assert_positive)r3   concentrationr!   s      r5   r)   z&Beta._maybe_assert_valid_concentrationG  s=    --!!?	A/ 	 r=   c           
          | j                   s|S t        j                  t        j                  |d      t        j
                  |t        j                  g | j                        d      g|      S )z Checks the validity of a sample.zsample must be positiver   zsample must be less than `1`.)	r!   r	   r   r   r   r   r   r   r    rc   s     r5   rr   zBeta._maybe_assert_valid_sampleQ  sd    h--!!!-FGNN2tzz*3	5/ 	
 
r=   )NNFTr   rE   )"__name__
__module____qualname____doc__r   
deprecatedr0   staticmethodr<   propertyr   r   rC   rG   rJ   rM   rP   r_   rW   AppendDocstring_beta_sample_notere   rh   rl   rk   ra   rb   rz   r|   r~   r   r)   rr   __classcell__r4   s   @r5   r   r   .   s   hT ;'
  #""#..` H H
         % %508($ %$$%67F 8F %$$%67+ 8+ %$$%67& 8& %$$%67I 8I=
9
8<P %$$CD
D
*

r=   c                   Z     e Zd ZdZ ej
                  ddd      	 	 	 d fd	       Z xZS )r   zFBeta with softplus transform of `concentration1` and `concentration0`.r   zWUse `tfd.Beta(tf.nn.softplus(concentration1), tf.nn.softplus(concentration2))` instead.Tr   c                 (   t        t                     }t        j                  |||g      5 }t        t
        |   t        j                  |d      t        j                  |d      |||       d d d        || _	        y # 1 sw Y   || _	        y xY w)Nr   softplus_concentration1r   softplus_concentration0)r   r   r!   r"   r   )
r&   r'   r   r(   r/   r   r0   r   softplus_parametersr2   s          r5   r0   z&BetaWithSoftplusConcentration.__init__a  s     fhJ	n&4&6 
7 	:>)49^*CE^*CE%) : 	 "D	 "Ds   ABB)FTr   )r   r   r   r   r   r   r0   r   r   s   @r5   r   r   ^  s;    N;2	 ##3"
"r=   c           
          d fd	}t        j                  |d j                   j                   j                  j                  j                  j                  g      5   |dd      t        j                   j                         |d      z  z
  t        j                   j                         |d      z  z
  t        j                   j                         |d	      z  z   cd
d
d
       S # 1 sw Y   y
xY w)a4  Calculate the batchwise KL divergence KL(d1 || d2) with d1 and d2 Beta.

  Args:
    d1: instance of a Beta distribution object.
    d2: instance of a Beta distribution object.
    name: (optional) Name to use for created operations.
      default is "kl_beta_beta".

  Returns:
    Batchwise KL(d1 || d2)
  c                 `    t        |       }t        |       }|r||z
  S  |        |       z
  S rE   )getattr)fnis_propertyfn1fn2d1d2s       r5   deltaz_kl_beta_beta.<locals>.delta  s2    
"b/C
"b/C%C#I:CECEM:r=   kl_beta_betar   rb   F)r   r   r   rC   N)T)r   r(   r   r   rC   r
   ry   )r   r   r   r   s   ``  r5   _kl_beta_betar   z  s    ; ~~dN4  0 &E:r001E:J4KKLr001E:J4KKL  6 67,-./0 0 0s   $BC33C<rE   )r   numpyr   tensorflow.python.frameworkr   r   r   r   tensorflow.python.opsr   r   r	   r
   r   r   #tensorflow.python.ops.distributionsr   r   r   rW   tensorflow.python.utilr    tensorflow.python.util.tf_exportr   __all__r   Distributionr   r   
RegisterKLr    r=   r5   <module>r      s    #  3 . + 4 + + 2 * $ , < @ I . 6 #H  #$%l
<$$ l
 &l
^	"D "8 T4(0 )0r=   