o
    2h                     @   s.  d Z ddlZddlZddl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 					dWddZdd Z	dXddZdd ZdYddZ						dZddZdd Zd d! Zd"d# Z d$d% Z!d&d' Z"d(d) Z#	*d[d+d*Z$	,	-d\d.d/Z%d]d1d0Z&d^d2d3Z'd_d5d4Z(d`d7d6Z)	8dad9d8Z*d:d; Z+d<d= Z,d>d? Z-d@dA Z.dbdBdCZ/dbdDdEZ0dcdFdGZ1					dddHdIZ2dYdJdKZ3dLdM Z4	dYdNdOZ5dedQdRZ6dSdT Z7G dUdV dVZ8dS )fz(Utilities for probability distributions.    N)constant_op)dtypes)ops)tensor_shape)tensor_util)	array_ops)array_ops_stack)	check_ops)cond)control_flow_ops)
linalg_ops)math_ops)nn)
tf_inspectassert_integer_formc              	   C   s   t j|| |gdb t j| dd} | jjr t W  d   S |p&d| }|du rPztj	tj
tjtjtjtji| jj }W n tyO   td| jjw tj| tt| || j||||dW  d   S 1 snw   Y  dS )ax  Assert that x has integer components (or floats equal to integers).

  Args:
    x: Floating-point `Tensor`
    data: The tensors to print out if the condition is `False`. Defaults to
      error message and first few entries of `x` and `y`.
    summarize: Print this many entries of each tensor.
    message: A string to prefix to the default message.
    int_dtype: A `tf.dtype` used to cast the float to. The default (`None`)
      implies the smallest possible signed int will be used for casting.
    name: A name for this operation (optional).

  Returns:
    Op raising `InvalidArgumentError` if `cast(x, int_dtype) != x`.
  valuesxnameNz{} has non-integer componentszUnrecognized type {})data	summarizemessager   )r   
name_scopeconvert_to_tensordtype
is_integerr   no_opformatr   float16int16float32int32float64int64
base_dtypeKeyError	TypeErrorr   r	   assert_equalr   cast)r   r   r   r   	int_dtyper    r+   c/var/www/html/chatgem/venv/lib/python3.10/site-packages/tensorflow/python/ops/distributions/util.pyr   '   s4   $c                 C   s    t | }tt| |g| S N)r   matrix_transposer   with_dependenciesr	   r(   )matrixmatrix_tr+   r+   r,   assert_symmetricS   s   
r2   $embed_check_nonnegative_integer_formc                 C   s   t j|| gd0 t j| dd} tj| d| dg}| jjs+|t| d| dg7 }t	
|| W  d   S 1 s;w   Y  dS )z>Assert x is a non-negative tensor, and optionally of integers.r   r   r   z'{}' must be non-negative.r   z*'{}' cannot contain fractional components.N)r   r   r   r	   assert_non_negativer   r   r   r   r   r/   )r   r   
assertionsr+   r+   r,   r3   Y   s   

$c                    sP   t j dd t jdd fdd}ttt t|dd S )zReturns whether a and b have the same dynamic shape.

  Args:
    a: `Tensor`
    b: `Tensor`

  Returns:
    `bool` `Tensor` representing if both tensors have the same shape.
  ar   bc                      sB   t t tt tgdttt gdS )Nr   )r   
reduce_allequalr   concatshaper+   r7   r8   r+   r,   all_shapes_equal{   s   z,same_dynamic_shape.<locals>.all_shapes_equalc                   S   s
   t dS )NF)r   constantr+   r+   r+   r,   <lambda>   s   
 z$same_dynamic_shape.<locals>.<lambda>)r   r   tf_condr
   r   r:   r   rank)r7   r8   r>   r+   r=   r,   same_dynamic_shapek   s   

rC   c                 C   sR   | du r| S zt | }W n ty   | }Y nw |du s!|du r#|S t||S )a`  Helper which tries to return a static value.

  Given `x`, extract it's value statically, optionally casting to a specific
  dtype. If this is not possible, None is returned.

  Args:
    x: `Tensor` for which to extract a value statically.
    dtype: Optional dtype to cast to.

  Returns:
    Statically inferred value if possible, otherwise None.
  N)r   constant_valuer'   nparray)r   r   x_r+   r+   r,   maybe_get_static_value   s   rH   Fget_logits_and_probsc              	   C   s   t j||| gd |du | du krtd|du rRt j| d|d} | jjs*td|rB|r2t| } | tj	| ddfW  d   S | t
j| ddfW  d   S t j|d|d}|jjsbtd	|rt d
< td|j}t|g}|rt|}|tjt
|d|ddg7 }n|tj||ddg7 }t||}W d   n1 sw   Y  t d4 |rt
||fW  d   W  d   S t
|t
d|  |fW  d   W  d   S 1 sw   Y  W d   dS 1 sw   Y  dS )a  Converts logit to probabilities (or vice-versa), and returns both.

  Args:
    logits: Floating-point `Tensor` representing log-odds.
    probs: Floating-point `Tensor` representing probabilities.
    multidimensional: Python `bool`, default `False`. If `True`, represents
      whether the last dimension of `logits` or `probs`, a `[N1, N2, ...  k]`
      dimensional tensor, representing the logit or probability of `shape[-1]`
      classes.
    validate_args: Python `bool`, default `False`. When `True`, either assert `0
      <= probs <= 1` (if not `multidimensional`) or that the last dimension of
      `probs` sums to one.
    name: A name for this operation (optional).
    dtype: `tf.DType` to prefer when converting args to `Tensor`s.

  Returns:
    logits, probs: Tuple of `Tensor`s. If `probs` has an entry that is `0` or
      `1`, then the corresponding entry in the returned logit will be `-Inf` and
      `Inf` respectively.

  Raises:
    ValueError: if neither `probs` nor `logits` were passed in, or both were.
  r   Nz(Must pass probs or logits, but not both.logitsr   r   z!logits must having floating type.probsr   z probs must having floating type.validate_probsg      ?zprobs does not sum to 1.r4   z$probs has components greater than 1.g      )r   r   
ValueErrorr   r   is_floatingr'   #embed_check_categorical_event_shaper   softmaxr   sigmoidr   r?   r	   r5   assert_near
reduce_sumassert_less_equalr   r/   loglog1p)rJ   rL   multidimensionalvalidate_argsr   r   onedependenciesr+   r+   r,   rI      s^   
1'"c                 C   s    t jdt jdt jdi| jdS )z7Helper returning True if dtype is known to be unsigned.TF)r   booluint8uint16getr%   dtr+   r+   r,   _is_known_unsigned_by_dtype   s   
rc   c                 C   s8   t jdt jdt jdt jdt jdt jdt jdi| j	dS )z5Helper returning True if dtype is known to be signed.TF)
r   r   r!   r#   int8r    r"   r$   r`   r%   ra   r+   r+   r,   _is_known_signed_by_dtype   s   
re   c                 C   s   t | pt| S )z(Helper returning True if dtype is known.)rc   re   ra   r+   r+   r,   _is_known_dtype
  s   rf   c                 C   sp   t | std| j| jrtdt| jj	d  S | j
r&t| jjS | jtjkr0tdS td| j)zDHelper returning the largest integer exactly representable by dtype.Unrecognized dtype: {}      )rf   r'   r   r   rP   intrE   finfoas_numpy_dtypenmantr   iinfomaxr%   r   r]   ra   r+   r+   r,   _largest_integer_by_dtype  s   rp   c                 C   s0   t | std| jt| rdS dt|  S )zEHelper returning the smallest integer exactly representable by dtype.rg   r   rN   )rf   r'   r   r   rc   rp   ra   r+   r+   r,   _smallest_integer_by_dtype  s
   rq   c                 C   s*   t | std| j| jp| jtjkS )z7Helper returning True if dtype.is_integer or is `bool`.rg   )rf   r'   r   r   r   r%   r   r]   ra   r+   r+   r,   _is_integer_like_by_dtype&  s   rr   rQ   c                 C   sV  t j|| gd t j| dd}|jj}|jrt|nd}|dkr)td|j	z	|
 d}W n ty=   tdw t|d d	url|jd j}|d
k rUtd||krctd|j	|||W  d	   S tj|ddd }ttj|dddtjt|d d
ddtj||d|j	|dg|W  d	   S 1 sw   Y  d	S )a  Embeds checks that categorical distributions don't have too many classes.

  A categorical-type distribution is one which, e.g., returns the class label
  rather than a one-hot encoding.  E.g., `Categorical(probs)`.

  Since distributions output samples in the same dtype as the parameters, we
  must ensure that casting doesn't lose precision. That is, the
  `parameter.dtype` implies a maximum number of classes. However, since shape is
  `int32` and categorical variables are presumed to be indexes into a `Tensor`,
  we must also ensure that the number of classes is no larger than the largest
  possible `int32` index, i.e., `2**31-1`.

  In other words the number of classes, `K`, must satisfy the following
  condition:

  ```python
  K <= min(
      int(2**31 - 1),  # Largest float as an index.
      {
          dtypes.float16: int(2**11),   # Largest int as a float16.
          dtypes.float32: int(2**24),
          dtypes.float64: int(2**53),
      }.get(categorical_param.dtype.base_dtype, 0))
  ```

  Args:
    categorical_param: Floating-point `Tensor` representing parameters of
      distribution over categories. The rightmost shape is presumed to be the
      number of categories.
    name: A name for this operation (optional).

  Returns:
    categorical_param: Input `Tensor` with appropriate assertions embedded.

  Raises:
    TypeError: if `categorical_param` has an unknown `dtype`.
    ValueError: if we can statically identify `categorical_param` as being too
      large (for being closed under int32/float casting).
  r   categorical_paramr   r   z3Unable to validate size of unrecognized dtype ({}).ri   zDA categorical-distribution parameter must have at least 1 dimension.rN   Nrh   zAA categorical-distribution parameter must have at least 2 events.zZNumber of classes exceeds `dtype` precision, i.e., {} implies shape ({}) cannot exceed {}.x_shaper4   zSNumber of classes exceeds `dtype` precision, i.e., {} dtype cannot exceed {} shape.)r   r   r   r   r%   rP   rp   r'   r   r   	get_shapewith_rank_at_leastrO   r   dimension_valuedimsvaluer   r<   r   r/   r	   assert_rank_at_leastassert_greater_equalrV   )rs   r   r   x_dtypemax_event_sizex_shape_static
event_sizer+   r+   r,   rQ   -  sd   )
!$Tembed_check_casting_closedc              	   C   s  t j|| gd t j| dd} t| js"| jjs"td| jjt|s1|js1td|jt| jsFt|sFtd| | jj|jg }|rT|t	j
| ddg7 }| jjrg|t| |d	|jd
g7 }n8t| jt|kr|t	j| t|dt|dg7 }|st| jt|k r|t	j| t|dt|dg7 }|s| W  d   S t|| W  d   S 1 sw   Y  dS )a  Ensures integers remain unaffected despite casting to/from int/float types.

  Example integer-types: `uint8`, `int32`, `bool`.
  Example floating-types: `float32`, `float64`.

  The largest possible integer representable by an IEEE754 floating-point is
  `2**(1 + mantissa_bits)` yet the largest possible integer as an int-type is
  `2**(bits - 1) - 1`. This function ensures that a `Tensor` purporting to have
  integer-form values can be cast to some other type without loss of precision.

  The smallest representable integer is the negative of the largest
  representable integer, except for types: `uint8`, `uint16`, `bool`. For these
  types, the smallest representable integer is `0`.

  Args:
    x: `Tensor` representing integer-form values.
    target_dtype: TF `dtype` under which `x` should have identical values.
    assert_nonnegative: `bool` indicating `x` should contain nonnegative values.
    name: A name for this operation (optional).

  Returns:
    x: Input `Tensor` with appropriate assertions embedded.

  Raises:
    TypeError: if `x` is neither integer- nor floating-type.
    TypeError: if `target_dtype` is neither integer- nor floating-type.
    TypeError: if neither `x` nor `target_dtype` are integer-type.
  r   r   r   z+{}.dtype must be floating- or integer-type.z4target_dtype ({}) must be floating- or integer-type.zIAt least one of {}.dtype ({}) and target_dtype ({}) must be integer-type.zElements must be non-negative.r4   zElements must be {}-equivalent.)r*   r   zElements cannot exceed {}.z#Elements cannot be smaller than {}.N)r   r   r   rr   r   rP   r'   r   r   r	   r5   r   rp   rV   rq   r{   r   r/   )r   target_dtypeassert_nonnegativer   r6   r+   r+   r,   "embed_check_integer_casting_closed  s   !



7$r   log_combinationsc                 C   s   t j|| |gd0 t j| dd} t j|dd}t| d }t|d }tj|dgd}|| W  d   S 1 s<w   Y  dS )	aX  Multinomial coefficient.

  Given `n` and `counts`, where `counts` has last dimension `k`, we compute
  the multinomial coefficient as:

  ```n! / sum_i n_i!```

  where `i` runs over all `k` classes.

  Args:
    n: Floating-point `Tensor` broadcastable with `counts`. This represents `n`
      outcomes.
    counts: Floating-point `Tensor` broadcastable with `n`. This represents
      counts in `k` classes, where `k` is the last dimension of the tensor.
    name: A name for this operation (optional).

  Returns:
    `Tensor` representing the multinomial coefficient between `n` and `counts`.
  r   nr   countsri   rN   axisN)r   r   r   r   lgammarU   )r   r   r   total_permutationscounts_factorialredundant_permutationsr+   r+   r,   r     s   $c                 C   s|   t |d| g, t j| dd} |du r| W  d   S t| }||}t| |}W d   |S 1 s7w   Y  |S )a  Transform diagonal of [batch-]matrix, leave rest of matrix unchanged.

  Create a trainable covariance defined by a Cholesky factor:

  ```python
  # Transform network layer into 2 x 2 array.
  matrix_values = tf.contrib.layers.fully_connected(activations, 4)
  matrix = tf.reshape(matrix_values, (batch_size, 2, 2))

  # Make the diagonal positive. If the upper triangle was zero, this would be a
  # valid Cholesky factor.
  chol = matrix_diag_transform(matrix, transform=tf.nn.softplus)

  # LinearOperatorLowerTriangular ignores the upper triangle.
  operator = LinearOperatorLowerTriangular(chol)
  ```

  Example of heteroskedastic 2-D linear regression.

  ```python
  tfd = tfp.distributions

  # Get a trainable Cholesky factor.
  matrix_values = tf.contrib.layers.fully_connected(activations, 4)
  matrix = tf.reshape(matrix_values, (batch_size, 2, 2))
  chol = matrix_diag_transform(matrix, transform=tf.nn.softplus)

  # Get a trainable mean.
  mu = tf.contrib.layers.fully_connected(activations, 2)

  # This is a fully trainable multivariate normal!
  dist = tfd.MultivariateNormalTriL(mu, chol)

  # Standard log loss. Minimizing this will "train" mu and chol, and then dist
  # will be a distribution predicting labels as multivariate Gaussians.
  loss = -1 * tf.reduce_mean(dist.log_prob(labels))
  ```

  Args:
    matrix:  Rank `R` `Tensor`, `R >= 2`, where the last two dimensions are
      equal.
    transform:  Element-wise function mapping `Tensors` to `Tensors`. To be
      applied to the diagonal of `matrix`. If `None`, `matrix` is returned
      unchanged. Defaults to `None`.
    name:  A name to give created ops. Defaults to "matrix_diag_transform".

  Returns:
    A `Tensor` with same shape and `dtype` as `matrix`.
  matrix_diag_transformr0   r   N)r   r   r   r   matrix_diag_partmatrix_set_diag)r0   	transformr   diagtransformed_diagtransformed_matr+   r+   r,   r   	  s   2

		r   rotate_transposec              
   C   sd  t j|| |gd t j| dd} t j|dd}t| t|}|  j}|durk|durk|dk r<| W  d   S t	
|t||  }|dkrT| W  d   S t	t	||}tj| |dW  d   S t| }tt|dt| ||t|| }td|}t||}t||gd}tj| |dW  d   S 1 sw   Y  dS )	a)  Circularly moves dims left or right.

  Effectively identical to:

  ```python
  numpy.transpose(x, numpy.roll(numpy.arange(len(x.shape)), shift))
  ```

  When `validate_args=False` additional graph-runtime checks are
  performed. These checks entail moving data from to GPU to CPU.

  Example:

  ```python
  x = tf.random.normal([1, 2, 3, 4])  # Tensor of shape [1, 2, 3, 4].
  rotate_transpose(x, -1).shape == [2, 3, 4, 1]
  rotate_transpose(x, -2).shape == [3, 4, 1, 2]
  rotate_transpose(x,  1).shape == [4, 1, 2, 3]
  rotate_transpose(x,  2).shape == [3, 4, 1, 2]
  rotate_transpose(x,  7).shape == rotate_transpose(x, 3).shape  # [2, 3, 4, 1]
  rotate_transpose(x, -7).shape == rotate_transpose(x, -3).shape  # [4, 1, 2, 3]
  ```

  Args:
    x: `Tensor`.
    shift: `Tensor`. Number of dimensions to transpose left (shift<0) or
      transpose right (shift>0).
    name: Python `str`. The name to give this op.

  Returns:
    rotated_x: Input `Tensor` with dimensions circularly rotated by shift.

  Raises:
    TypeError: if shift is not integer type.
  r   r   r   shiftNrh   r   )perm)r   r   r   r	   assert_integerr   rD   ru   ndimsrE   signabsrollaranger   	transposerB   where_v2r   lessmodranger;   )r   r   r   shift_value_staticr   r   firstlastr+   r+   r,   r   G  s<   $






$pick_vectorc              
   C   s  t j|| ||fdv t j| dd} | jtjkr#td| | jtjf t| }|dur9|r0|n|W  d   S t j|dd}t j|dd}|j|jkrYtd||j||jf t	
|d	 }t	t	||gd	t	| d	|gt	| |d
gW  d   S 1 sw   Y  dS )a  Picks possibly different length row `Tensor`s based on condition.

  Value `Tensor`s should have exactly one dimension.

  If `cond` is a python Boolean or `tf.constant` then either `true_vector` or
  `false_vector` is immediately returned. I.e., no graph nodes are created and
  no validation happens.

  Args:
    cond: `Tensor`. Must have `dtype=tf.bool` and be scalar.
    true_vector: `Tensor` of one dimension. Returned when cond is `True`.
    false_vector: `Tensor` of one dimension. Returned when cond is `False`.
    name: Python `str`. The name to give this op.
  Example:  ```python pick_vector(tf.less(0, 5), tf.range(10, 12), tf.range(15,
    18))  # [10, 11] pick_vector(tf.less(5, 0), tf.range(10, 12), tf.range(15,
    18))  # [15, 16, 17] ```

  Returns:
    true_or_false_vector: `Tensor`.

  Raises:
    TypeError: if `cond.dtype != tf.bool`
    TypeError: if `cond` is not a constant and
      `true_vector.dtype != false_vector.dtype`
  r   r
   r   z%s.dtype=%s which is not %sNtrue_vectorfalse_vectorz&%s.dtype=%s does not match %s.dtype=%sr   rN   )r   r   r   r   r   r]   r'   r   rD   r   r<   slicer;   r   where)r
   r   r   r   cond_value_staticr   r+   r+   r,   r     s0   

$prefer_static_broadcast_shapec                    s   t j|| |gdC dd   fdd} fdd}|| }||}|dur7|dur7t||W  d   S || }||}t||W  d   S 1 sOw   Y  dS )	a  Convenience function which statically broadcasts shape when possible.

  Args:
    shape1:  `1-D` integer `Tensor`.  Already converted to tensor!
    shape2:  `1-D` integer `Tensor`.  Already converted to tensor!
    name:  A string name to prepend to created ops.

  Returns:
    The broadcast shape, either as `TensorShape` (if broadcast can be done
      statically), or as a `Tensor`.
  r   c                 S   s   t j| dtjdS )Nr<   rK   )r   r   r   r"   r   r+   r+   r,   make_shape_tensor  s   z8prefer_static_broadcast_shape.<locals>.make_shape_tensorc                    s4   t | tjr| S t | }|d urt|S d S r-   )
isinstancer   TensorShaper   rD   )ss_r   r+   r,   get_tensor_shape  s   
z7prefer_static_broadcast_shape.<locals>.get_tensor_shapec                    s0   t | tjs
 | S |  r |  S td)Nz6Cannot broadcast from partially defined `TensorShape`.)r   r   r   is_fully_definedas_listrO   )r   r   r+   r,   get_shape_tensor  s
   z7prefer_static_broadcast_shape.<locals>.get_shape_tensorN)r   r   r   broadcast_static_shapebroadcast_dynamic_shape)shape1shape2r   r   r   shape1_shape2_r+   r   r,   r     s   

$c                 C      t t| S )zReturn static rank of tensor `x` if available, else `tf.rank(x)`.

  Args:
    x: `Tensor` (already converted).

  Returns:
    Numpy array (if static rank is obtainable), else `Tensor`.
  )prefer_static_valuer   rB   r   r+   r+   r,   prefer_static_rank     	r   c                 C   r   )zReturn static shape of tensor `x` if available, else `tf.shape(x)`.

  Args:
    x: `Tensor` (already converted).

  Returns:
    Numpy array (if static shape is obtainable), else `Tensor`.
  )r   r   r<   r   r+   r+   r,   prefer_static_shape  r   r   c                 C   s   t | }|dur|S | S )zReturn static value of tensor `x` if available, else `x`.

  Args:
    x: `Tensor` (already converted).

  Returns:
    Numpy array (if static value is obtainable), else `Tensor`.
  N)r   rD   )r   static_xr+   r+   r,   r     s   
	r   c                 C   s>   | du rdS t | | d}tt| dd dd@ S )z2Generate a new seed, from the given seed and salt.Nzutf-8      i)strencoderj   hashlibmd5	hexdigest)seedsaltstringr+   r+   r,   gen_new_seed  s    r   c           	   	   C   s  t j|d| gd t j| dd} t| jdd durSt| jj	d j
}tdd	|  d
 }|t|krAtd|t|}| jdd ||g}n+t| d }tjtdtjd| tjd tjd}| jddd ddg}t| }|r| tj| d|df |d gdg}n| d|df tj| |d gdg}| r| ntjt| dd ||ggdd}ttj|dd|} tj| |rdnd|rdndd} | | | W  d   S 1 sw   Y  dS )a  Creates a (batch of) triangular matrix from a vector of inputs.

  Created matrix can be lower- or upper-triangular. (It is more efficient to
  create the matrix as upper or lower, rather than transpose.)

  Triangular matrix elements are filled in a clockwise spiral. See example,
  below.

  If `x.get_shape()` is `[b1, b2, ..., bB, d]` then the output shape is
  `[b1, b2, ..., bB, n, n]` where `n` is such that `d = n(n+1)/2`, i.e.,
  `n = int(np.sqrt(0.25 + 2. * m) - 0.5)`.

  Example:

  ```python
  fill_triangular([1, 2, 3, 4, 5, 6])
  # ==> [[4, 0, 0],
  #      [6, 5, 0],
  #      [3, 2, 1]]

  fill_triangular([1, 2, 3, 4, 5, 6], upper=True)
  # ==> [[1, 2, 3],
  #      [0, 5, 6],
  #      [0, 0, 4]]
  ```

  For comparison, a pure numpy version of this function can be found in
  `util_test.py`, function `_fill_triangular`.

  Args:
    x: `Tensor` representing lower (or upper) triangular elements.
    upper: Python `bool` representing whether output matrix should be upper
      triangular (`True`) or lower triangular (`False`, default).
    name: Python `str`. The name to give this op.

  Returns:
    tril: `Tensor` with lower (or upper) triangular elements filled from `x`.

  Raises:
    ValueError: if `x` cannot be mapped to a triangular matrix.
  fill_triangularr   r   r   ri   rN   Ng      ?       @g      ?zGInput right-most shape ({}) does not correspond to a triangular matrix.rh   r   .r   r   )	num_lower	num_upper)r   r   r   r   rw   r<   rv   rE   r"   rx   ry   sqrtfloorrO   r   concatenater   r   r)   r   r!   r   reverser   r   r;   reshapematrix_band_part	set_shape)	r   upperr   mr   static_final_shaper   x_list	new_shaper+   r+   r,   r     sJ   +
%&$"
$r   c              	   C   s  t j|d| gd t j| dd} t| jdd dur?t| jj	d j
}t||d  d }| jdd	 |g}nt| d }||d  d }| jddd	 dg}t| }|rw| d
dddf }| d
ddddf }ntj| d
dddf |d gd}| d
ddddf }tjtj||d gd|d gd}	||	 }
t|
tjt| dd	 ||d  ggdd}tj||d
d|| f gdd}|| |W  d   S 1 sw   Y  dS )a  Creates a vector from a (batch of) triangular matrix.

  The vector is created from the lower-triangular or upper-triangular portion
  depending on the value of the parameter `upper`.

  If `x.shape` is `[b1, b2, ..., bB, n, n]` then the output shape is
  `[b1, b2, ..., bB, d]` where `d = n (n + 1) / 2`.

  Example:

  ```python
  fill_triangular_inverse(
    [[4, 0, 0],
     [6, 5, 0],
     [3, 2, 1]])

  # ==> [1, 2, 3, 4, 5, 6]

  fill_triangular_inverse(
    [[1, 2, 3],
     [0, 5, 6],
     [0, 0, 4]], upper=True)

  # ==> [1, 2, 3, 4, 5, 6]
  ```

  Args:
    x: `Tensor` representing lower (or upper) triangular elements.
    upper: Python `bool` representing whether output matrix should be upper
      triangular (`True`) or lower triangular (`False`, default).
    name: Python `str`. The name to give this op.

  Returns:
    flat_tril: (Batch of) vector-shaped `Tensor` representing vectorized lower
      (or upper) triangular elements from `x`.
  fill_triangular_inverser   r   r   rh   rN   Nri   .r   r   )r   r   r   r   rw   r<   rv   rE   r"   rx   ry   r   r   r   r   r   r;   r   )r   r   r   r   r   r   r   initial_elementstriangular_portionrotated_triangular_portionconsolidated_matrixend_sequenceyr+   r+   r,   r     sD   &"("
$r   c                 C   s   dd }dd }t |d| ||gT | dur.t j| dd} t|| d	dd
ddf } |dur>t j|dd}t|}|durYt j|dd}t||d	dddd
f }|| ||W  d   S 1 siw   Y  dS )a'  Creates a matrix with values set above, below, and on the diagonal.

  Example:

  ```python
  tridiag(below=[1., 2., 3.],
          diag=[4., 5., 6., 7.],
          above=[8., 9., 10.])
  # ==> array([[  4.,   8.,   0.,   0.],
  #            [  1.,   5.,   9.,   0.],
  #            [  0.,   2.,   6.,  10.],
  #            [  0.,   0.,   3.,   7.]], dtype=float32)
  ```

  Warning: This Op is intended for convenience, not efficiency.

  Args:
    below: `Tensor` of shape `[B1, ..., Bb, d-1]` corresponding to the below
      diagonal part. `None` is logically equivalent to `below = 0`.
    diag: `Tensor` of shape `[B1, ..., Bb, d]` corresponding to the diagonal
      part.  `None` is logically equivalent to `diag = 0`.
    above: `Tensor` of shape `[B1, ..., Bb, d-1]` corresponding to the above
      diagonal part.  `None` is logically equivalent to `above = 0`.
    name: Python `str`. The name to give this op.

  Returns:
    tridiag: `Tensor` with values set above, below and on the diagonal.

  Raises:
    ValueError: if all inputs are `None`.
  c                 S   sF   t jt | dd dggdd}t j|| jd}t j|| |gddS )zBPrepends and appends a zero to every vector in a batch of vectors.NrN   ri   r   r   r   )r   r;   r<   zerosr   )r   r<   zr+   r+   r,   _pad  s   "ztridiag.<locals>._padc                  W   sB   d}| D ]}|du rq|du r|}q||7 }q|du rt d|S )z&Adds list of Tensors, ignoring `None`.Nz6Must specify at least one of `below`, `diag`, `above`.)rO   )r   r   r   r+   r+   r,   _add  s   
ztridiag.<locals>._addtridiagNbelowr   .rN   ri   r   above)r   r   r   r   matrix_diag)r   r   r   r   r   r   r+   r+   r,   r     s   ! 
 
$r   c                 C   sT  t |d| |g t j| dd} |du r8tj| ||d}|r/t|}||fW  d   S |W  d   S t j|| jdd}| tt	| }tj
||dd}	tt|	t|	|	}	t|t||	  }
tj|
||d}|s|t|	|}	t|}|	t||  }|r||fW  d   S |W  d   S 1 sw   Y  dS )	a  Computes `log(abs(sum(weight * exp(elements across tensor dimensions))))`.

  If all weights `w` are known to be positive, it is more efficient to directly
  use `reduce_logsumexp`, i.e., `tf.reduce_logsumexp(logx + tf.math.log(w))` is
  more
  efficient than `du.reduce_weighted_logsumexp(logx, w)`.

  Reduces `input_tensor` along the dimensions given in `axis`.
  Unless `keep_dims` is true, the rank of the tensor is reduced by 1 for each
  entry in `axis`. If `keep_dims` is true, the reduced dimensions
  are retained with length 1.

  If `axis` has no entries, all dimensions are reduced, and a
  tensor with a single element is returned.

  This function is more numerically stable than log(sum(w * exp(input))). It
  avoids overflows caused by taking the exp of large inputs and underflows
  caused by taking the log of small inputs.

  For example:

  ```python
  x = tf.constant([[0., 0, 0],
                   [0, 0, 0]])

  w = tf.constant([[-1., 1, 1],
                   [1, 1, 1]])

  du.reduce_weighted_logsumexp(x, w)
  # ==> log(-1*1 + 1*1 + 1*1 + 1*1 + 1*1 + 1*1) = log(4)

  du.reduce_weighted_logsumexp(x, w, axis=0)
  # ==> [log(-1+1), log(1+1), log(1+1)]

  du.reduce_weighted_logsumexp(x, w, axis=1)
  # ==> [log(-1+1+1), log(1+1+1)]

  du.reduce_weighted_logsumexp(x, w, axis=1, keep_dims=True)
  # ==> [[log(-1+1+1)], [log(1+1+1)]]

  du.reduce_weighted_logsumexp(x, w, axis=[0, 1])
  # ==> log(-1+5)
  ```

  Args:
    logx: The tensor to reduce. Should have numeric type.
    w: The weight tensor. Should have numeric type identical to `logx`.
    axis: The dimensions to reduce. If `None` (the default), reduces all
      dimensions. Must be in the range `[-rank(input_tensor),
      rank(input_tensor))`.
    keep_dims: If true, retains reduced dimensions with length 1.
    return_sign: If `True`, returns the sign of the result.
    name: A name for the operation (optional).

  Returns:
    lswe: The `log(abs(sum(weight * exp(x))))` reduced tensor.
    sign: (Optional) The sign of `sum(weight * exp(x))`.
  reduce_weighted_logsumexplogxr   N)r   keepdimswr   r   T)r   r   r   r   reduce_logsumexpr   	ones_liker   rW   r   
reduce_maxr   is_inf
zeros_liker   exprU   squeeze)r   r   r   	keep_dimsreturn_signr   lswesgn
log_absw_xmax_log_absw_xwx_over_max_absw_xsum_wx_over_max_absw_xr+   r+   r,   r     s>   @

$r   c              
   C   s   t j|d| gdY t j| dd} tt| jjjd }t	
| t|}t	| | }t	| }| }tt	||t| | } | t	t	|    }t||t|||W  d   S 1 sew   Y  dS )ac  Computes the inverse softplus, i.e., x = softplus_inverse(softplus(x)).

  Mathematically this op is equivalent to:

  ```none
  softplus_inverse = log(exp(x) - 1.)
  ```

  Args:
    x: `Tensor`. Non-negative (not enforced), floating-point.
    name: A name for the operation (optional).

  Returns:
    `Tensor`. Has the same type/shape as input `x`.
  softplus_inverser   r   r   r   N)r   r   r   rE   rW   rk   r   rl   epsr   r   r   greaterr   r   
logical_orr   expm1)r   r   	thresholdis_too_smallis_too_largetoo_small_valuetoo_large_valuer   r+   r+   r,   r  |  s"   
$r  c                 C   s6   t | jt|| }|dur|S t| | S )z)Returns the size of a specific dimension.N)r   rw   r<   rv   rE   r   r   )r   r   r   r+   r+   r,   dimension_size  s   r  c           
   	   C   s  t |d| g | du rItjjjdd\}}||j}||j}|tjj	|ddd }t j
|d|d	}t j
|d
|d	}||fW  d   S t| \}}t j
|d|d	}t j
|d|d	}|tj	|dddd
d }dd }||||}}|dur|dur||krtd||n2|rtjt|ddt|ddddg}	t |	 t|}t|}W d   n1 sw   Y  ||fW  d   S 1 sw   Y  dS )a  Validates quadrature grid, probs or computes them as necessary.

  Args:
    quadrature_grid_and_probs: Python pair of `float`-like `Tensor`s
      representing the sample points and the corresponding (possibly
      normalized) weight.  When `None`, defaults to:
        `np.polynomial.hermite.hermgauss(deg=8)`.
    dtype: The expected `dtype` of `grid` and `probs`.
    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.
    name: Python `str` name prefixed to Ops created by this class.

  Returns:
     quadrature_grid_and_probs: Python pair of `float`-like `Tensor`s
      representing the sample points and the corresponding (possibly
      normalized) weight.

  Raises:
    ValueError: if `quadrature_grid_and_probs is not None` and
      `len(quadrature_grid_and_probs[0]) != len(quadrature_grid_and_probs[1])`
  !process_quadrature_grid_and_probsNr   )degri   T)ordr   gridrK   rL   unnormalized_probsrN   )r  r   r   r   c                 S   s   t | jdd S )z:Returns the static size of a specific dimension or `None`.ri   rN   )r   rw   r<   rv   r   r+   r+   r,   _static_event_size  s   z=process_quadrature_grid_and_probs.<locals>._static_event_sizezm`quadrature_grid_and_probs` must be a `tuple` of same-length zero-th-dimension `Tensor`s (saw lengths {}, {})r   zX`quadrature_grid_and_probs` must be a `tuple` of same-length zero-th-dimension `Tensor`sr4   )r   r   rE   
polynomialhermite	hermgaussastyperl   linalgnormr   tupler   rO   r   r	   r(   r  control_dependenciesr   identity)
quadrature_grid_and_probsr   rZ   r   r  rL   r  r   r   r6   r+   r+   r,   r    sJ   


$r  ri   c              
   C   s  t |d| ||g t j| dd} t j|| jdd}t j|dd}|jjs/td|jj|s7|s7td| j	j
d	urA| j	j
ntj| d
d}t j|dd}t|}|d	ur|}|dk rb|| }t|}	|dksq| j	j
d	ur| j	d	| }
t|	d	u rd	nt| j	||	||   }| j	|d d	 }|
||}nd	}nt|dk || |}d	}tj| tjt|r|nd|r|ndg|d|tjd|d} |d	ur| | | W  d	   S 1 sw   Y  d	S )aZ  Pads `value` to the front and/or back of a `Tensor` dim, `count` times.

  Args:
    x: `Tensor` input.
    axis: Scalar `int`-like `Tensor` representing the single dimension to pad.
      (Negative indexing is supported.)
    front: Python `bool`; if `True` the beginning of the `axis` dimension is
      padded with `value`, `count` times. If `False` no front padding is made.
    back: Python `bool`; if `True` the end of the `axis` dimension is padded
      with `value`, `count` times. If `False` no end padding is made.
    value: Scalar `int`-like `Tensor` representing the actual value added to the
      front and/or back of the `axis` dimension of `x`.
    count: Scalar `int`-like `Tensor` representing number of elements added to
      the front and/or back of the `axis` dimension of `x`. E.g., if `front =
      back = True` then `2 * count` elements are added.
    name: Python `str` name prefixed to Ops created by this function.

  Returns:
    pad: The padded version of input `x`.

  Raises:
    ValueError: if both `front` and `back` are `False`.
    TypeError: if `count` is not `int`-like.
  padr   r   ry   r   countz(`count.dtype` (`{}`) must be `int`-like.z/At least one of `front`, `back` must be `True`.Nr   r   r   ri   rN   )indicesdepthr   on_valuer   )paddingsconstant_values)r   r   r   r   r   r'   r   r   rO   r<   r   r   rB   r   rD   r   r   dimension_at_indexr   r   r  one_hotr   stackr   r"   r   )r   r   frontbackry   r  r   r   axis_count_headmiddletailfinal_shaper+   r+   r,   r    sd   



$r  c                  C   s   t jt j d d \} }}}tjdkr||i }n||i  ||i }i }| D ]}tjdkr;|| ||< q-||||< q-|| |S )aL  Returns parent frame arguments.

  When called inside a function, returns a dictionary with the caller's function
  arguments. These are positional arguments and keyword arguments (**kwargs),
  while variable arguments (*varargs) are excluded.

  When called at global scope, this will return an empty dictionary, since there
  are no arguments.

  WARNING: If caller function argument names are overloaded before invoking
  this method, then values will reflect the overloaded value. For this reason,
  we recommend calling `parent_frame_arguments` at the beginning of the
  function.
  ri   r   )      )	r   _inspectgetargvaluesr'  sysversion_infor`   popupdate)	arg_namesvariable_arg_namekeyword_arg_name
local_varskeyword_args
final_argsarg_namer+   r+   r,   parent_frame_argumentsJ  s   



r?  c                   @   s"   e Zd ZdZdddZdd ZdS )	AppendDocstringaL  Helper class to promote private subclass docstring to public counterpart.

  Example:

  ```python
  class TransformedDistribution(Distribution):
    @distribution_util.AppendDocstring(
      additional_note="A special note!",
      kwargs_dict={"foo": "An extra arg."})
    def _prob(self, y, foo=None):
      pass
  ```

  In this case, the `AppendDocstring` decorator appends the `additional_note` to
  the docstring of `prob` (not `_prob`) and adds a new `kwargs`
  section with each dictionary item as a bullet-point.

  For a more detailed example, see `TransformedDistribution`.
   Nc                 C   s   || _ |rHg }t| D ],}|| }tdd |D r"td| | }d|v r0td| |d||f  q|  j dd| 7  _ dS dS )	a  Initializes the AppendDocstring object.

    Args:
      additional_note: Python string added as additional docstring to public
        version of function.
      kwargs_dict: Python string/string dictionary representing specific kwargs
        expanded from the **kwargs input.

    Raises:
      ValueError: if kwargs_dict.key contains whitespace.
      ValueError: if kwargs_dict.value contains newlines.
    c                 s   s    | ]}|  V  qd S r-   )isspace).0r   r+   r+   r,   	<genexpr>  s    z+AppendDocstring.__init__.<locals>.<genexpr>z(Parameter name "%s" contains whitespace.
z1Parameter description for "%s" contains newlines.z*  `%s`: %sz

##### `kwargs`:

N)_additional_notesortedkeysanyrO   lstripappendjoin)selfadditional_notekwargs_dictbulletskeyry   r+   r+   r,   __init__  s   zAppendDocstring.__init__c                    sD   t   fdd}|jd u r| j|_|S | jd| j 7  _|S )Nc                     s    | i |S r-   r+   )argskwargsfnr+   r,   _fn  s   z%AppendDocstring.__call__.<locals>._fnz
%s)	functoolswraps__doc__rF  )rM  rV  rW  r+   rU  r,   __call__  s   
zAppendDocstring.__call__)rA  N)__name__
__module____qualname__rZ  rR  r[  r+   r+   r+   r,   r@  u  s    
r@  )NNNNr   )r3   r-   )NNFFrI   N)rQ   )Tr   )r   )NN)r   )r   )r   )FN)NNNN)NNFFN)FFr   ri   N)9rZ  rX  r   r4  numpyrE   tensorflow.python.frameworkr   r   r   r   r   tensorflow.python.opsr   r   r	   r
   rA   r   r   r   r   tensorflow.python.utilr   r   r2   r3   rC   rH   rI   rc   re   rf   rp   rq   rr   rQ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r?  r@  r+   r+   r+   r,   <module>   s   
,


Q		
a

[
"
>
M0
-

s
EE

b9

CG+