
    AVh                        d 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 	 	 	 	 	 d3dZd Z	 d4dZd Zd5dZ	 	 	 	 	 	 d6dZd Zd Zd Zd Z d Z!d Z"	 d7dZ#	 	 d8dZ$d9dZ%d:d Z&d;d!Z'd<d"Z(	 d=d#Z)d$ Z*d% Z+d& Z,d' Z-d>d(Z.d>d)Z/d?d*Z0	 	 	 	 	 d@d+Z1d5d,Z2d- Z3	 d5d.Z4dAd/Z5d0 Z6 G d1 d2      Z7y)Bz(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_inspectc           
         t        j                  || |g      5  t        j                  | d      } | j                  j                  rt        j                         cddd       S |xs dj                  |       }|t	 t        j                  t        j                  t        j                  t        j                  t        j                  t        j                  i| j                  j                     }t'        j(                  | t+        j,                  t+        j,                  | |      | j                        ||||      cddd       S # t         $ r/ t#        dj                  | j                  j$                              w xY w# 1 sw Y   yxY w)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   s         X/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/distributions/util.pyassert_integer_formr-   &   s9   * ~~dAt9- ac*Aww##%  B8??BGENNFLLNNFLLNNFLL
 ''

		 !!	hmmAy1177;   E.55aggllCDDE s,   AF%F=A3E0AF8E>>FF
c                     t        j                  |       }t        j                  t	        j
                  | |      g|       S N)r   matrix_transposer   with_dependenciesr
   r)   )matrixmatrix_ts     r,   assert_symmetricr4   R   s:    ''/(		+	+fh/0&
: :    c                 r   t        j                  || g      5  t        j                  | d      } t        j                  | dj                  |             g}| j                  j                  s |t        | dj                  |             gz  }t        j                  ||       cddd       S # 1 sw Y   yxY w)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   r1   )r   r   
assertionss      r,   $embed_check_nonnegative_integer_formr:   X   s     ~~dA3' =ac*A%%3::1=	?J 77
BII!LN j
 --j!<= = =s   B
B--B6c                     t        j                   d       t        j                  d       fd}t        j                  t	        j
                  t        j                         t        j                              |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                  F   t        j                  t        j                  t        j                  t        j
                         t        j
                        gd      t        j                  t        j
                        t        j
                         gd                  S )Nr   )r   
reduce_allequalr   concatshape)r<   r=   s   r,   all_shapes_equalz,same_dynamic_shape.<locals>.all_shapes_equalz   sv    #Y__Q%78!=#Y__Q%78!=	>? ?r5   c                  ,    t        j                  d      S )NF)r   constant r5   r,   <lambda>z$same_dynamic_shape.<locals>.<lambda>   s     4 4U ; r5   )r   r   tf_condr   r   r@   r   rank)r<   r=   rC   s   `` r,   same_dynamic_shaperJ   j   sg     
AC(!	AC(!
? 
nnY^^A&	q(9:;
= =r5   c                     | | S 	 t        j                  |       }|||S t        j                  ||      S # t        $ r | }Y )w xY w)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.
  )r   constant_valuer(   nparray)r   r   x_s      r,   maybe_get_static_valuerP      sZ     YH		#	#A	&B Z5=I	"e		 
 	
Bs   7 AAc           	         t        j                  ||| g      5  |du | du k(  rt        d      |t        j                  | d|      } | j                  j
                  st        d      |r/|rt        |       } | t        j                  | d      fcddd       S | t        j                  | d      fcddd       S t        j                  |d|      }|j                  j
                  st        d	      |rt        j                  d
      5  t        j                  d|j                        }t        j                  |      g}|r<t        |      }|t        j                   t        j"                  |d      |d      gz  }n|t        j$                  ||d      gz  }t'        j(                  ||      }ddd       t        j                  d      5  |r)t        j*                  |      |fcddd       cddd       S t        j*                  |      t        j,                  d|z        z
  |fcddd       cddd       S # 1 sw Y   xY w# 1 sw Y   nxY w	 ddd       y# 1 sw Y   yxY w)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.r7   z$probs has components greater than 1.g      )r   r   
ValueErrorr   r   is_floatingr(   #embed_check_categorical_event_shaper   softmaxr   sigmoidr   rE   r
   r8   assert_near
reduce_sumassert_less_equalr   r1   loglog1p)rR   rT   multidimensionalvalidate_argsr   r   onedependenciess           r,   get_logits_and_probsre      sd   : ~~dE6?3 1F6T>*ABB}$$V(%Hf\\%%;<< 
6v>&rzz&w771F 1F X%%f7;;1F 1F  !!%gUCE;;""899>>*+ H""2u{{3!55e<=5e<%
##%%eR046 , ))&LN , !22<G!H$ 
	! 
F	 ||E"E)
F 
FO1F 1Fb \\% 8>>#+#>>E
F 
FO1F 1F*H H$
F 
F 
FO1F 1F 1FsV   A7I!I!=AI!B'H?4I!I*	I!=/I,	I!?I	I!I	I!!I*c                     t         j                  dt         j                  dt         j                  dij	                  | j
                  d      S )z7Helper returning True if dtype is known to be unsigned.TF)r   booluint8uint16getr&   dts    r,   _is_known_unsigned_by_dtyperm      s;     kk4llDmmT
 Cu	r5   c                    t         j                  dt         j                  dt         j                  dt         j                  dt         j
                  dt         j                  dt         j                  dij                  | j                  d      S )z5Helper returning True if dtype is known to be signed.TF)
r   r    r"   r$   int8r!   r#   r%   rj   r&   rk   s    r,   _is_known_signed_by_dtyperp      s_     nndnndnndkk4llDllDllD
 Cur5   c                 2    t        |       xs t        |       S )z(Helper returning True if dtype is known.)rm   rp   rk   s    r,   _is_known_dtyperr   	  s    	$R	(	I,Eb,IIr5   c                    t        |       s$t        dj                  | j                              | j                  r8t        dt        j                  | j                        j                  dz   z        S | j                  r)t        j                  | j                        j                  S | j                  t        j                  k(  rt        d      S t        dj                  | j                              )zDHelper returning the largest integer exactly representable by dtype.Unrecognized dtype: {}      )rr   r(   r   r   rX   intrM   finfoas_numpy_dtypenmantr   iinfomaxr&   r   rg   rk   s    r,   _largest_integer_by_dtyper}     s    		
,33BGG<
==^^q288B--.44q89::]]88B%%&***]]fkk!q6M*11"'':;;r5   c                     t        |       s$t        dj                  | j                              t	        |       rydt        |       z  S )zEHelper returning the smallest integer exactly representable by dtype.rt   r   rV   )rr   r(   r   r   rm   r}   rk   s    r,   _smallest_integer_by_dtyper     sA    		
,33BGG<
== $	'+	++r5   c                     t        |       s$t        dj                  | j                              | j                  xs | j
                  t        j                  k(  S )z7Helper returning True if dtype.is_integer or is `bool`.rt   )rr   r(   r   r   r   r&   r   rg   rk   s    r,   _is_integer_like_by_dtyper   %  sA    		
,33BGG<
==		6"--6;;66r5   c                    t        j                  || g      5  t        j                  | d      }|j                  j                  }|j
                  rt        |      nd}|dk(  r$t        dj                  |j                              	 |j                         j                  d      }t        j                  |d         _|j                  d   j                   }|d
k  rt        d      ||kD  r&t        dj                  |j                  ||            |cd	d	d	       S t#        j$                  |d      d   }t'        j(                  t+        j,                  |dd      t+        j.                  t#        j$                  |      d   d
d      t+        j0                  ||dj                  |j                  |            g|      cd	d	d	       S # t        $ r t        d      w xY w# 1 sw Y   y	xY w)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 ({}).rv   zDA categorical-distribution parameter must have at least 1 dimension.rV   Nru   zAA categorical-distribution parameter must have at least 2 events.zZNumber of classes exceeds `dtype` precision, i.e., {} implies shape ({}) cannot exceed {}.x_shaper7   zSNumber of classes exceeds `dtype` precision, i.e., {} dtype cannot exceed {} shape.)r   r   r   r   r&   rX   r}   r(   r   r   	get_shapewith_rank_at_leastrW   r   dimension_valuedimsvaluer   rB   r   r1   r
   assert_rank_at_leastassert_greater_equalr^   )r   r   r   x_dtypemax_event_sizex_shape_static
event_sizes          r,   rY   rY   ,  s   R ~~d$5#67 3/6IJA gg  G.5.A.A!'*q  $fW\\24 40{{}77:n ##N2$67C!&&r*00j	a + , 	,	n	$ CCI6$\\:~DGH 	H ?3 3B ??195b9j//

(
(/1
 
(
(ooa $)+
 
%
%77=v,,80	11" 
#E3 3&  0 / 0 00'3 3s,   A0G&
G)A-G& B$G&G##G&&G/c                    t        j                  || g      5  t        j                  | d      } t        | j                        sD| j                  j
                  s.t        dj                  | j                  j                              t        |      s0|j
                  s$t        dj                  |j                              t        | j                        sEt        |      s:t        dj                  | | j                  j                  |j                              g }|r|t        j                  | d      gz  }| j                  j
                  r,|t        | |d	j                  |j                        
      gz  }nt        | j                        t        |      kD  r=|t        j                  | t        |      dj                  t        |                  gz  }|s^t        | j                        t        |      k  r=|t        j                  | t        |      dj                  t        |                  gz  }|s| cddd       S t!        j"                  ||       cddd       S # 1 sw Y   yxY w)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.r7   zElements must be {}-equivalent.)r+   r   zElements cannot exceed {}.z#Elements cannot be smaller than {}.N)r   r   r   r   r   rX   r(   r   r   r
   r8   r-   r}   r^   r   r   r   r1   )r   target_dtypeassert_nonnegativer   r9   s        r,   "embed_check_integer_casting_closedr     sI   B ~~dA3' 7=ac*A%agg.qww7J7J &&,fQWW\\&:< <%l3$$ &&,f\->->&?A A%agg.%l3 ..4fQ5A5F5F/HI I J

'
'9; j
 	ww 
$7>>##%& j $AGG
,
#L
12 	''),75<<-l;=?
 	

 !&@
'''/='>***<8>EE.|<>@
 	

 m7= 7=n --j!<o7= 7= 7=s   H(I*I**I3c                 V   t        j                  || |g      5  t        j                  | d      } t        j                  |d      }t        j                  | dz         }t        j                  |dz         }t        j
                  |dg      }||z
  cddd       S # 1 sw Y   yxY w)	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   countsrv   rV   axisN)r   r   r   r   lgammar]   )r   r   r   total_permutationscounts_factorialredundant_permutationss         r,   log_combinationsr     s    2 ~~dAv;/ 7ac*A""69F!Q/vz2%001AM 667 7 7s   A;BB(c                    t        j                  |d| g      5  t        j                  | d      } || cddd       S t        j                  |       } ||      }t        j
                  | |      }ddd       |S # 1 sw Y   S xY w)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_transformr2   r   N)r   r   r   r   matrix_diag_partmatrix_set_diag)r2   	transformr   diagtransformed_diagtransformed_mats         r,   r   r     s    d ~~d3fX> J""69FJ J
 %%f-D //8HIOJ 
J 
s   A;3A;;Bc           
         t        j                  || |g      5  t        j                  | d      } t        j                  |d      }t        j                  |       t        j                  |      }| j                         j                  }|||dk  r| cddd       S t        j                  |      t        |      |z  z  }|dk(  r| cddd       S t        j                  t        j                  |      |      }t        j                  | |      cddd       S t        j                   |       }t        j"                  t%        j&                  |d      t%        j(                  | |      |t%        j(                  ||      z
        }t%        j*                  d|      }t%        j*                  ||      }t        j,                  ||gd      }t        j                  | |      cddd       S # 1 sw Y   yxY w)	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   shiftNru   r   )perm)r   r   r   r
   assert_integerr   rL   r   ndimsrM   signabsrollaranger   	transposerI   where_v2r   lessmodrangerA   )r   r   r   shift_value_staticr   r   firstlasts           r,   rotate_transposer   F  s   H ~~dAu:. &/ac*A!!%g6EU#$33E:KKME/;	&/ &/ 77#56
 
!E
)+	q	 &/ &/ WWRYYu%'9:d  .&/ &/< nnQe  
--q
!
,,vu
%
(,,ue,
,.e nnQ&e^^E5)dtUmQ/d  .M&/ &/ &/s   A=G.!*G.?G.CG..G7c           
      0   t        j                  || ||f      5  t        j                  | d      } | j                  t        j
                  k7  r+t        | d| j                  dt        j
                        t        j                  |       }||r|n|cddd       S t        j                  |d      }t        j                  |d      }|j                  |j                  k7  r*t        |d|j                  d	|d|j                        t        j                  |      d
   }t        j                  t        j                  ||gd
      t        j                  | d
|      gt        j                  | |d      g      cddd       S # 1 sw Y   yxY w)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.dtype=z which is not Ntrue_vectorfalse_vectorz does not match r   rV   )r   r   r   r   r   rg   r(   r   rL   r   rB   slicerA   r   where)r   r   r   r   cond_value_staticr   s         r,   pick_vectorr     sa   4 ~~dD+|#DE J  F3DzzV[[ TZZ6 7 7#2248$-[<J J ''-HK((NKLL...))<9K9KMN N 	$Q'A??+|4a8			D!Q	'(9??4B+G*HJJ J Js   A<F!C!FFc                 .   t        j                  || |g      5  d fd}fd} ||       } ||      }|!|t        j                  ||      cddd       S  ||       } ||      }t        j                  ||      cddd       S # 1 sw Y   yxY w)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                 N    t        j                  | dt        j                        S )NrB   rS   )r   r   r   r#   r   s    r,   make_shape_tensorz8prefer_static_broadcast_shape.<locals>.make_shape_tensor  s    ""17&,,GGr5   c                     t        | t        j                        r| S t        j                   |             }|t        j                  |      S y r/   )
isinstancer   TensorShaper   rL   )ss_r   s     r,   get_tensor_shapez7prefer_static_broadcast_shape.<locals>.get_tensor_shape  sG    	A|//	0%%&7&:;b	''++r5   c                     t        | t        j                        s |       S | j                         r | j	                               S t        d      )Nz6Cannot broadcast from partially defined `TensorShape`.)r   r   r   is_fully_definedas_listrW   )r   r   s    r,   get_shape_tensorz7prefer_static_broadcast_shape.<locals>.get_shape_tensor  sM    <334 ##	
			 -- 0 1 1r5   N)r   r   r   broadcast_static_shapebroadcast_dynamic_shape)shape1shape2r   r   r   shape1_shape2_r   s          @r,   prefer_static_broadcast_shaper     s     ~~dFF#34 ?H1 v&Gv&Gw2--gw?1? ?4 v&Gv&G,,Wg>9? ? ?s   7B%BBc                 >    t        t        j                  |             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   rI   r   s    r,   prefer_static_rankr     s     
Y^^A.	//r5   c                 >    t        t        j                  |             S )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   rB   r   s    r,   prefer_static_shaper     s     
Y__Q/	00r5   c                 8    t        j                  |       }||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`.
  )r   rL   )r   static_xs     r,   r   r     s$     ''*(O	
(r5   c                     | yt        |       |z   j                  d      }t        t        j                  |      j                         dd d      dz  S )z2Generate a new seed, from the given seed and salt.Nzutf-8      i)strencoderw   hashlibmd5	hexdigest)seedsaltstrings      r,   gen_new_seedr     sN    	\I$$W-&	W[[ **,Ra0"	5
	BBr5   c           
         t        j                  |d| g      5  t        j                  | d      } t        j                  | j
                  j                  d      d         	 t        j                  | j
                  j                  d   j                        }t        j                  dd	|z  z         d
z
  }|t        j                  |      k7  rt        dj                  |            t        j                  |      }| j
                  dd j                  ||g      }nt!        j
                  |       d   }t#        j$                  t#        j                  dt#        j$                  d|z  t&        j(                        z         t&        j                        }| j
                  j                  d      dd j                  ddg      }t+        |       }|r%| t!        j,                  | d|df   |dz
  g      g}n$| d|df   t!        j,                  | |dz
  g      g}|j/                         r|j1                         n0t!        j2                  t!        j
                  |       dd ||ggd      }t!        j4                  t!        j2                  |d      |      } t!        j6                  | |rdnd|rdnd      } | j9                  |       | cddd       S # 1 sw Y   yxY w)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   rv   rV   Ng      ?       @g      ?zGInput right-most shape ({}) does not correspond to a triangular matrix.ru   r   .r   r   )	num_lower	num_upper)r   r   r   r   r   rB   r   rM   r#   r   r   sqrtfloorrW   r   concatenater   r   r*   r   r"   r   reverser   r   rA   reshapematrix_band_part	set_shape)	r   upperr   mr   static_final_shaper   x_list	new_shapes	            r,   r   r     s{   V ~~d-qc: Eac*A##	""1%b)+267 ((177<<#))
*a
''$a-
 3
&a	
bhhqk	 >>DfQiI 	I
((1+a773B<33QF;
//!
R
 a --
--x}}QU&..II
Ja 7755a8"=II,J q!E9$$QsABwZuqykBCf#qr'
I--auqykBCf(:(K(K(M""$yq1#26A?aH  	)**6;YGA""	5abEbq	KAKK"#KE E Es   J2KKc           
         t        j                  |d| g      5  t        j                  | d      } t        j                  | j
                  j                  d      d         	 tt        j                  | j
                  j                  d   j                        }t        j                  ||dz   z  dz        }| j
                  dd	 j                  |g      }nQt        j
                  |       d   }||dz   z  dz  }| j
                  j                  d      dd	 j                  dg      }t        |       }|r| d
dddf   }| d
ddddf   }n/t        j                  | d
dddf   |dz
  g      }| d
ddddf   }t        j                  t        j                  ||dz
  g      |dz
  g      }	||	z   }
t        j                  |
t        j                   t        j
                  |       dd	 ||dz
  z  ggd            }t        j                   ||d
d||z
  f   gd      }|j#                  |       |cddd       S # 1 sw Y   yxY w)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   ru   rV   Nrv   .r   r   )r   r   r   r   r   rB   r   rM   r#   r   r   r   r   r   r   r   rA   r   )r   r   r   r   r   r   r   initial_elementstriangular_portionrotated_triangular_portionconsolidated_matrixend_sequenceys                r,   r   r     s9   L ~~d5qcB ac*A##	""1%b)+267
((177<<#))
*a
((AQKA%
&a773B<33QC8
//!
R
 aA;1
a7755a8"=II&q!E319S!"aZ="**1S"aZ=	{KS#2#q[>!*!2!2,EAI;?ai[" -/II$$)//!,Sb1AQK=AJLL 	*Lfq1uf,EFRPAKK"#9  s   HH>>Ic                    d }d }t        j                  |d| ||g      5  | <t        j                  | d      } t        j                   ||             dddd	df   } |,t        j                  |d
      }t        j                  |      }|<t        j                  |d      }t        j                   ||            dd	dddf   } || ||      cddd       S # 1 sw Y   yxY w)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                     t        j                  t        j                  |       dd dggd      }t        j                  || j                        }t        j                  || |gd      S )zBPrepends and appends a zero to every vector in a batch of vectors.NrV   rv   r   r   r   )r   rA   rB   zerosr   )r   rB   zs      r,   _padztridiag.<locals>._pad  sX    iooa0"5s;!DEQWW-AQ1IB//r5   c                  L    d}| D ]  }|||}||z  } |t        d      |S )z&Adds list of Tensors, ignoring `None`.Nz6Must specify at least one of `below`, `diag`, `above`.)rW   )r   r   r  s      r,   _addztridiag.<locals>._add  sI    A 	
9	Q 	yOPPHr5   tridiagNbelowr   .rV   rv   r   above)r   r   r   r   matrix_diag)r
  r   r  r   r  r  s         r,   r	  r	    s    B0 ~~dItU';< $##E8e##DK0crc12>e""4f5d""4(d##E8e##DK0ab#2#>e tU#$ $ $s   B4CC(c                    t        j                  |d| |g      5  t        j                  | d      } |Gt        j                  | ||      }|r"t        j                  |      }||fcddd       S |cddd       S t        j                  || j                  d      }| t        j                  t        j                  |            z   }t        j                  ||d      }	t        j                  t        j                  |	      t        j                  |	      |	      }	t        j                  |      t        j                  ||	z
        z  }
t        j                   |
||      }|st        j"                  |	|      }	t        j                  |      }|	t        j                  ||z        z   }|r||fcddd       S |cddd       S # 1 sw Y   yxY w)	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   r_   r   
reduce_maxr   is_inf
zeros_liker   expr]   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_xs               r,   r  r    s   @ ~~d7$C   F3Dy&&t$Kd	!!$'Sy    	atzz<AX\\!_55J(($NN
 ''')=)=n)MN 	a8<<
^(CDD %00	; ((>n
--.
/CHLL/E)EFFD3Y7 8 9  s   AG0G;D5G:GGc           
         t        j                  |d| g      5  t        j                  | d      } t        j                  t        j
                  | j                  j                        j                        dz   }t        j                  | t        j                  |            }t        j                  | |       }t        j                  |       }| }t        j                  t        j                  ||      t        j                   |       |       } | t        j                  t        j"                  |               z   }t        j                  ||t        j                  |||            cddd       S # 1 sw Y   yxY w)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   rM   r_   rx   r   ry   epsr   r   r  greaterr   r   
logical_orr  expm1)r   r   	thresholdis_too_smallis_too_largetoo_small_valuetoo_large_valuer  s           r,   r#  r#  {  s&     ~~d.s; %>ac*A. rxx 6 67;;<rAI==BFF9$56L##A	z2Lll1oOO 	L,79L9LQ9O		A 	
HLL(..!,,--Ao<!<>G%> %> %>s   EE22E;c                     t        j                  | j                  j                  t	        j
                  |            |         }||S t        j                  |       |   S )z)Returns the size of a specific dimension.)r   r   rB   r   rM   r   r   )r   r   r   s      r,   dimension_sizer.    sQ     ""gg  .t46!]H		D	!!r5   c           	      "   t        j                  |d| g      5  | t        j                  j                  j                  d      \  }}|j                  |j                        }|j                  |j                        }|t        j                  j                  |dd      z  }t        j                  |d|	      }t        j                  |d
|	      }||fcddd       S t        |       \  }}t        j                  |d|	      }t        j                  |d|	      }|t        j                  |dddd
      z  }d } ||       ||      }}|"| ||k7  rt        dj                  ||            |rwt        j                   t#        |d      t#        |d      d      g}	t        j$                  |	      5  t'        j(                  |      }t'        j(                  |      }ddd       ||fcddd       S # 1 sw Y   xY w# 1 sw Y   yxY w)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   )degrv   T)ordr  gridrS   rT   unnormalized_probsrV   )r2  r   r  r   c                 d    t        j                  | j                  j                  d      d         S )z:Returns the static size of a specific dimension or `None`.rv   rV   )r   r   rB   r   r   s    r,   _static_event_sizez=process_quadrature_grid_and_probs.<locals>._static_event_size  s'    ))!''*D*DQ*G*KLLr5   zm`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`sr7   )r   r   rM   
polynomialhermite	hermgaussastypery   linalgnormr   tupler   rW   r   r
   r)   r.  control_dependenciesr   identity)
quadrature_grid_and_probsr   rb   r   r3  rT   r6  r   r   r9   s
             r,   r0  r0    s   6 ~~d?013 % (MM))333:kdE[[--.dll5//0eryy~~eT~::e""4fEBd##EuEe5[% % 12KD%  F%@D!!%.B%PE	Z__UTPPEM e$&8&>qA}	
a 006q!> 	> 


 
 U,T+ACj ##J/ *!!$'""5)* ;K% %D* *E% %s+   B>H!CH9+G9$H9H	>HHc                 *   t        j                  |d| ||g      5  t        j                  | d      } t        j                  || j                  d      }t        j                  |d      }|j                  j                  s.t        dj                  |j                  j                              |s|st        d      | j                  j                  | j                  j                  nt        j                  | d
      }t        j                  |d      }t        j                  |      }||}|dk  r||z   }t        j                  |      }	|dk\  s| j                  j                  | j                  d	| }
t        j                   |	d	n(t        j"                  | j                  |      |	||z   z  z         }| j                  |dz   d	 }|
j%                  |j%                  |            }n"d	}nt        j&                  |dk  ||z   |      }d	}t        j(                  | t        j*                  t-        j.                  |r|nd|r|ndg      |d|t0        j2                        |      } || j5                  |       | cd	d	d	       S # 1 sw Y   y	xY w)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   r   r  countz(`count.dtype` (`{}`) must be `int`-like.z/At least one of `front`, `back` must be `True`.Nr   r   r   rv   rV   )indicesdepthr   on_valuer   )paddingsconstant_values)r   r   r   r   r   r(   r   r   rW   rB   r   r   rI   r   rL   r   r   dimension_at_indexr   r   rB  one_hotr	   stackr   r#   r   )r   r   frontbackr   rC  r   r   axis_count_headmiddletailfinal_shapes                 r,   rB  rB    sO   2 ~~dEAue#45 +ac*A!!%qwwWEE!!%g6E;;!!@GG
++

  HII2	G9 
   F3D&&t,Ed	t|))%0f	!qww}}0wwu~))&.$++AGGT:VT\>  wwtaxy!&&v'9'9$'?@q%$,=dk	""#))B"=?,,  		A kk+W+ + +s   I$J		Jc                  6   t         j                  j                  t         j                  j                         d   d         \  } }}}|j	                  |i        |j	                  |i       }i }| D ]  }|j	                  |      ||<    |j                  |       |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.
  rv   r   )r   _inspectgetargvaluesrK  popupdate)	arg_namesvariable_arg_namekeyword_arg_name
local_varskeyword_args
final_argsarg_names          r,   parent_frame_argumentsr`  I  s    " &&



#
#
%a
(
+- =) 0* .."B' 0"5,*  4h%>>(3Jx4L!	r5   c                       e Zd ZdZddZd Zy)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                 b   || _         |rg }t        |j                               D ]`  }||   }t        d |D              rt	        d|z        |j                         }d|v rt	        d|z        |j                  d|d|       b | xj                   ddj                  |      z   z  c_         yy)	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              3   <   K   | ]  }|j                           y wr/   )isspace).0r   s     r,   	<genexpr>z+AppendDocstring.__init__.<locals>.<genexpr>  s     (qqyy{(s   z(Parameter name "%s" contains whitespace.
z1Parameter description for "%s" contains newlines.z*  `z`: z

##### `kwargs`:

N)_additional_notesortedkeysanyrW   lstripappendjoin)selfadditional_notekwargs_dictbulletskeyr   s         r,   __init__zAppendDocstring.__init__  s     ,Dg((*+ 5#C (C((G#MN
N5=CcIK KU345  9DIIg<N NO r5   c                     t        j                        fd       }|j                  | j                  |_        |S |xj                  d| j                  z  z  c_        |S )Nc                       | i |S r/   rF   )argskwargsfns     r,   _fnz%AppendDocstring.__call__.<locals>._fn  s       r5   z
%s)	functoolswraps__doc__ri  )rp  rz  r{  s    ` r,   __call__zAppendDocstring.__call__  s^    __R! ! {{))ck J 
kkVd3333kJr5   ) N)__name__
__module____qualname__r~  ru  r  rF   r5   r,   rb  rb  n  s    (P6
r5   rb  )NNNNr-   )r:   r/   )NNFFre   N)rY   )Tembed_check_casting_closed)r   )NN)r   )r   )r   )FN)NNNN)NNFFN)FFr   rv   N)8r~  r|  r   numpyrM   tensorflow.python.frameworkr   r   r   r   r   tensorflow.python.opsr   r	   r
   r   rH   r   r   r   r   tensorflow.python.utilr   r-   r4   r:   rJ   rP   re   rm   rp   rr   r}   r   r   rY   r   r   r   r   r   r   r   r   r   r   r   r   r	  r  r#  r.  r0  rB  r`  rb  rF   r5   r,   <module>r     sZ   /    3 . + 4 3 + 1 + 1 2 , * $ - ""& $"&2)X: 3=$=>2 !%#*/',4#NFb
J
<,7 B\B ;?,HX=v7D;|J/Z+J` (G*?Z	0	1CpfBJA$J !%#'(-*/#'\D5>r" ,0@FDN"J: :r5   