o
    ?e-                     @   s   d 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dZedgdG dd dejZdS )z#The Multinomial distribution class.    )dtypes)ops)	array_ops)	check_ops)control_flow_ops)map_fn)math_ops)nn_ops)
random_ops)distribution)util)deprecation)	tf_exportMultinomiala  For each batch of counts, `value = [n_0, ...
,n_{k-1}]`, `P[value]` is the probability that after sampling `self.total_count`
draws from this Multinomial distribution, the number of draws falling in class
`j` is `n_j`. Since this definition is [exchangeable](
https://en.wikipedia.org/wiki/Exchangeable_random_variables); different
sequences have the same counts so the probability includes a combinatorial
coefficient.

Note: `value` must be a non-negative tensor with dtype `self.dtype`, have no
fractional components, and such that
`tf.reduce_sum(value, -1) = self.total_count`. Its shape must be broadcastable
with `self.probs` and `self.total_count`.zdistributions.Multinomial)v1c                       s   e Zd ZdZejdddd					 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 Zdd Zd)ddZeedd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Z  ZS )*r   a3
  Multinomial distribution.

  This Multinomial distribution is parameterized by `probs`, a (batch of)
  length-`K` `prob` (probability) vectors (`K > 1`) such that
  `tf.reduce_sum(probs, -1) = 1`, and a `total_count` number of trials, i.e.,
  the number of trials per draw from the Multinomial. It is defined over a
  (batch of) length-`K` vector `counts` such that
  `tf.reduce_sum(counts, -1) = total_count`. The Multinomial is identically the
  Binomial distribution when `K = 2`.

  #### Mathematical Details

  The Multinomial is a distribution over `K`-class counts, i.e., a length-`K`
  vector of non-negative integer `counts = n = [n_0, ..., n_{K-1}]`.

  The probability mass function (pmf) is,

  ```none
  pmf(n; pi, N) = prod_j (pi_j)**n_j / Z
  Z = (prod_j n_j!) / N!
  ```

  where:
  * `probs = pi = [pi_0, ..., pi_{K-1}]`, `pi_j > 0`, `sum_j pi_j = 1`,
  * `total_count = N`, `N` a positive integer,
  * `Z` is the normalization constant, and,
  * `N!` denotes `N` factorial.

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

  #### Pitfalls

  The number of classes, `K`, must not exceed:
  - the largest integer representable by `self.dtype`, i.e.,
    `2**(mantissa_bits+1)` (IEE754),
  - the maximum `Tensor` index, i.e., `2**31-1`.

  In other words,

  ```python
  K <= min(2**31-1, {
    tf.float16: 2**11,
    tf.float32: 2**24,
    tf.float64: 2**53 }[param.dtype])
  ```

  Note: This condition is validated only when `self.validate_args = True`.

  #### Examples

  Create a 3-class distribution, with the 3rd class is most likely to be drawn,
  using logits.

  ```python
  logits = [-50., -43, 0]
  dist = Multinomial(total_count=4., logits=logits)
  ```

  Create a 3-class distribution, with the 3rd class is most likely to be drawn.

  ```python
  p = [.2, .3, .5]
  dist = Multinomial(total_count=4., probs=p)
  ```

  The distribution functions can be evaluated on counts.

  ```python
  # counts same shape as p.
  counts = [1., 0, 3]
  dist.prob(counts)  # Shape []

  # p will be broadcast to [[.2, .3, .5], [.2, .3, .5]] to match counts.
  counts = [[1., 2, 1], [2, 2, 0]]
  dist.prob(counts)  # Shape [2]

  # p will be broadcast to shape [5, 7, 3] to match counts.
  counts = [[...]]  # Shape [5, 7, 3]
  dist.prob(counts)  # Shape [5, 7]
  ```

  Create a 2-batch of 3-class distributions.

  ```python
  p = [[.1, .2, .7], [.3, .3, .4]]  # Shape [2, 3]
  dist = Multinomial(total_count=[4., 5], probs=p)

  counts = [[2., 1, 1], [3, 1, 1]]
  dist.prob(counts)  # Shape [2]

  dist.sample(5) # Shape [5, 2, 3]
  ```
  z
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_onceNFc              	      s   t t }tj||||gd3}tj|dd| _|r!t| j| _tj||d||d\| _	| _
| jdtjf | j
 | _W d   n1 sEw   Y  tt| j| j
jtj|||| j| j	| j
g|d dS )	a  Initialize a batch of Multinomial distributions.

    Args:
      total_count: Non-negative floating point tensor with shape broadcastable
        to `[N1,..., Nm]` with `m >= 0`. Defines this as a batch of
        `N1 x ... x Nm` different Multinomial distributions. Its components
        should be equal to integer values.
      logits: Floating point tensor representing unnormalized log-probabilities
        of a positive event with shape broadcastable to
        `[N1,..., Nm, K]` `m >= 0`, and the same dtype as `total_count`. Defines
        this as a batch of `N1 x ... x Nm` different `K` class Multinomial
        distributions. Only one of `logits` or `probs` should be passed in.
      probs: Positive floating point tensor with shape broadcastable to
        `[N1,..., Nm, K]` `m >= 0` and same dtype as `total_count`. Defines
        this as a batch of `N1 x ... x Nm` different `K` class Multinomial
        distributions. `probs`'s components in the last portion of its shape
        should sum to `1`. Only one of `logits` or `probs` should be passed in.
      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total_count)nameT)logitsprobsZmultidimensionalvalidate_argsr   .N)dtypeZreparameterization_typer   allow_nan_stats
parametersZgraph_parentsr   )dictlocalsr   Z
name_scopeZconvert_to_tensor_total_countdistribution_util$embed_check_nonnegative_integer_formZget_logits_and_probs_logits_probsr   newaxis	_mean_valsuperr   __init__r   r   ZNOT_REPARAMETERIZED)selfr   r   r   r   r   r   r   	__class__ p/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/ops/distributions/multinomial.pyr$      s:   
*

zMultinomial.__init__c                 C      | j S )z,Number of trials used to construct a sample.)r   r%   r(   r(   r)   r         zMultinomial.total_countc                 C   r*   )z Vector of coordinatewise logits.)r   r+   r(   r(   r)   r      r,   zMultinomial.logitsc                 C   r*   )z0Probability of drawing a `1` in that coordinate.)r    r+   r(   r(   r)   r      r,   zMultinomial.probsc                 C   s   t | jd d S Nr   shaper"   r+   r(   r(   r)   _batch_shape_tensor      zMultinomial._batch_shape_tensorc                 C   s   | j  dd d S N   r.   r"   	get_shapeZwith_rank_at_leastr+   r(   r(   r)   _batch_shape      zMultinomial._batch_shapec                 C   s   t | jdd  S r-   r/   r+   r(   r(   r)   _event_shape_tensor   r2   zMultinomial._event_shape_tensorc                 C   s   | j  ddd  S r3   r5   r+   r(   r(   r)   _event_shape   r8   zMultinomial._event_shapec           
         s   t j| jtjd}|  d  tj| jd |j	d| }tj|dtj
f | jj	d| j }t|d g}t|dg } fdd}tj|||g| j	d}tj|g dd	}tg|   ggd}	t||	}|S )
N)r   r   ).r   .r.   c                    sX   | d | d }}t |tjdf |}tj|dgd}tjtj| ddd}|S )	Nr   r4   .r.   )r0   )depth)Zaxis)r
   Zmultinomialr   r!   reshaper   
reduce_sumZone_hot)argsr   Zn_drawxknseedr(   r)   _sample_single  s   z-Multinomial._sample_n.<locals>._sample_single)r4   r      )perm)r   castr   r   Zint32Zevent_shape_tensorr   	ones_liker   r   r!   r=   r   Z	transposeconcatZbatch_shape_tensor)
r%   rC   rD   Zn_drawsr   Zflat_logitsZflat_ndrawsrE   r@   Zfinal_shaper(   rA   r)   	_sample_n   s.   zMultinomial._sample_nc                 C   s   |  || | S N)_log_unnormalized_prob_log_normalizationr%   countsr(   r(   r)   	_log_prob  s   zMultinomial._log_probc                 C   s"   |  |}t|t| j dS r-   )_maybe_assert_valid_sampler   r>   r	   Zlog_softmaxr   rO   r(   r(   r)   rM     s   
z"Multinomial._log_unnormalized_probc                 C   s   |  |}t| j| S rL   )rR   r   Zlog_combinationsr   rO   r(   r(   r)   rN     s   
zMultinomial._log_normalizationc                 C   s   t | jS rL   )r   identityr"   r+   r(   r(   r)   _mean  s   zMultinomial._meanc              
   C   sR   | j t| jdtjf  }tt| jdtjf |dtjd d f  | 	 S N.)
r   r   rI   r   r!   Zmatrix_set_diagr   matmulr"   	_variancer%   pr(   r(   r)   _covariance"  s   zMultinomial._covariancec                 C   s,   | j t| jdtjf  }| j| j|  S rU   )r   r   rI   r   r!   r"   rX   r(   r(   r)   rW   ,  s   zMultinomial._variancec                 C   s8   | j s|S t|}ttj| jt	|dddg|S )zBCheck counts for proper shape, values, then return tensor version.r.   z%counts must sum to `self.total_count`)message)
r   r   r   r   Zwith_dependenciesr   Zassert_equalr   r   r>   rO   r(   r(   r)   rR   1  s   
z&Multinomial._maybe_assert_valid_sample)NNFTr   rL   )__name__
__module____qualname____doc__r   
deprecatedr$   propertyr   r   r   r1   r7   r9   r:   rK   r   ZAppendDocstring_multinomial_sample_noterQ   rM   rN   rT   rZ   rW   rR   __classcell__r(   r(   r&   r)   r   3   s@    _
;



!

N)r_   Ztensorflow.python.frameworkr   r   Ztensorflow.python.opsr   r   r   r   r   r	   r
   Z#tensorflow.python.ops.distributionsr   r   r   Ztensorflow.python.utilr   Z tensorflow.python.util.tf_exportr   __all__rb   Distributionr   r(   r(   r(   r)   <module>   s&   
