
    6biN                         S r SSKrSSKrSSKJs  Jr  SSKJ	r	  S r
SS jrSS jrS r   SS jrS	 rS
 rS rS rS rS rS rg)z%Utilities used by convolution layers.    N)backendc                     U S:X  a$  US:X  a  gUS:X  a  gUS:X  a  g[        SU S	35      eU S
:X  a$  US:X  a  gUS:X  a  gUS:X  a  g[        SU S	35      e[        SU  S35      e)Nchannels_last   NWC   NHWC   NDHWCzInput rank not supported: z. Expected values are [3, 4, 5]channels_firstNCWNCHWNCDHWzInvalid data_format: z9. Expected values are ["channels_first", "channels_last"])
ValueError)data_formatndims     W/home/james-whalen/.local/lib/python3.13/site-packages/tf_keras/src/utils/conv_utils.pyconvert_data_formatr      s    o%19QYQY,TF 30 0  
(	(19QYQY,TF 30 0 
 #K= 1F F
 	
    c           	      .   SU SU SU  3n[        U [        5      (       a  U 4U-  nO; [        U 5      n[        U5      U:w  a  [	        U5      eU H  n [        U5        M     U(       a  U Vs1 s H  owS:  d  M
  UiM     nnSn	OU Vs1 s H  owS::  d  M
  UiM     nnSn	U(       a  US	U S
U	 S3-  n[	        U5      eU$ ! [         a    [	        U5      ef = f! [        [        4 a     USU S[        U5       3-  n[	        U5      ef = fs  snf s  snf )a[  Transforms non-negative/positive integer/integers into an integer tuple.

Args:
  value: The value to validate and convert. Could an int, or any iterable of
    ints.
  n: The size of the tuple to be returned.
  name: The name of the argument being validated, e.g. "strides" or
    "kernel_size". This is only used to format error messages.
  allow_zero: A ValueError will be raised if zero is received
    and this param is False. Defaults to `False`.

Returns:
  A tuple of n integers.

Raises:
  ValueError: If something else than an int/long or iterable thereof or a
  negative value is
    passed.
zThe `z` argument must be a tuple of z integers. Received: zincluding element z	 of type r   z>= 0z> 0z including z( that does not satisfy the requirement `z`.)
isinstanceinttuple	TypeErrorr   lentype)
valuenname
allow_zero	error_msgvalue_tuplesingle_valuevunqualified_valuesreq_msgs
             r   normalize_tupler'   9   sf   * v3A3 7$g	' 
 %hl	(,K {q Y'''L,L! ( )4>AAa>)4?AQa?,-6wirC	
	 ##9  	(Y''	( 	* ,( 7 ./1	 !++, ? @s/   C C.	D;D
	DDC0D
c                     U c  gUS;   d   eXS-
  US-
  -  -   nUS;   a  U nOUS:X  a  X-
  S-   nOUS:X  a  X-   S-
  nWU-   S-
  U-  $ )a  Determines output length of a convolution given input length.

Args:
    input_length: integer.
    filter_size: integer.
    padding: one of "same", "valid", "full", "causal"
    stride: integer.
    dilation: dilation rate, integer.

Returns:
    The output length (integer).
N>   fullsamevalidcausal   )r*   r,   r+   r)    )input_lengthfilter_sizepaddingstridedilationdilated_filter_sizeoutput_lengths          r   conv_output_lengthr6   v   s     9999%qX\(JJ$$$	G	$:Q>	F	$:Q>F"Q&611r   c                 |    U c  gUS;   d   eUS:X  a  US-  nOUS:X  a  SnOUS:X  a  US-
  nU S-
  U-  SW-  -
  U-   $ )	zDetermines input length of a convolution given output length.

Args:
    output_length: integer.
    filter_size: integer.
    padding: one of "same", "valid", "full".
    stride: integer.

Returns:
    The input length (integer).
N>   r)   r*   r+   r*      r+   r   r)   r-   r.   )r5   r0   r1   r2   pads        r   conv_input_lengthr:      sj     ////&Q	G		F	AoA'!c'1K??r   c                    US;   d   eU c  gXS-
  US-
  -  -   nUc;  US:X  a  X-  [        X-
  S5      -   nU$ US:X  a  X-  XA-   S-
  -
  nU$ US:X  a  X-  nW$ US:X  a  US-  nOUS:X  a  SnOUS:X  a  US-
  nU S-
  U-  U-   SW-  -
  U-   nU$ )	a  Determines output length of a transposed convolution given input length.

Args:
    input_length: Integer.
    filter_size: Integer.
    padding: one of `"same"`, `"valid"`, `"full"`.
    output_padding: Integer, amount of padding along the output dimension.
      Can be set to `None` in which case the output length is inferred.
    stride: Integer.
    dilation: Integer.

Returns:
    The output length (integer).
>   r)   r*   r+   Nr-   r+   r   r)   r8   r*   )max)r/   r0   r1   output_paddingr2   r3   lengthr9   s           r   deconv_output_lengthr?      s    , //// qX\ BBK g!*S1Eq-IIF" M! !*f.BQ.FGF M !*F M f"CC/C A'+5C?.P 	 Mr   c                 ~    U c  [         R                  " 5       n U R                  5       nUS;  a  [        SU  35      eU$ )N>   r   r   zWThe `data_format` argument must be one of "channels_first", "channels_last". Received: )r   image_data_formatlowerr   )r   r   s     r   normalize_data_formatrC      sN    }))+++-K==<<A7D
 	
 r   c                     [        U [        [        45      (       a  U $ U R                  5       nUS;  a  [	        SU 35      eU$ )N>   r*   r+   r,   zqThe `padding` argument must be a list/tuple or one of "valid", "same" (or "causal", only for `Conv1D). Received: )r   listr   rB   r   )r   r1   s     r   normalize_paddingrF      sO    %$''kkmG11 	#
 	

 Nr   c                 @   US;  a  [        SU S35      e[        U 5      n[        U[        5      (       a  U4U-  n[        U[        5      (       a  U4U-  n[        U5      n[        U5      nXT:w  d  Xd:w  a  [	        SU SU SU 35      e[        XX#5      nX-   n[        R                  " U[        5      n	U V
s/ s H  n
[        U
5      PM     nn
[        R                  " U6  H1  n[        XXU5      n[        R                  " U6  H
  nSXU-   '   M     M3     U	$ s  sn
f )a  Compute a mask representing the connectivity of a convolution operation.

Assume a convolution with given parameters is applied to an input having N
spatial dimensions with `input_shape = (d_in1, ..., d_inN)` to produce an
output with shape `(d_out1, ..., d_outN)`. This method returns a boolean
array of shape `(d_in1, ..., d_inN, d_out1, ..., d_outN)` with `True`
entries indicating pairs of input and output locations that are connected by
a weight.

Example:

  >>> input_shape = (4,)
  >>> kernel_shape = (2,)
  >>> strides = (1,)
  >>> padding = "valid"
  >>> conv_kernel_mask(input_shape, kernel_shape, strides, padding)
  array([[ True, False, False],
         [ True,  True, False],
         [False,  True,  True],
         [False, False,  True]])

  where rows and columns correspond to inputs and outputs respectively.


Args:
  input_shape: tuple of size N: `(d_in1, ..., d_inN)`, spatial shape of the
    input.
  kernel_shape: tuple of size N, spatial shape of the convolutional kernel /
    receptive field.
  strides: tuple of size N, strides along each spatial dimension.
  padding: type of padding, string `"same"` or `"valid"`.
    `"valid"` means no padding. `"same"` results in padding evenly to
    the left/right or up/down of the input such that output has the same
    height/width dimension as the input.

Returns:
  A boolean 2N-D `np.ndarray` of shape
  `(d_in1, ..., d_inN, d_out1, ..., d_outN)`, where `(d_out1, ..., d_outN)`
  is the spatial shape of the output. `True` entries in the mask represent
  pairs of input-output locations that are connected by a weight.

Raises:
  ValueError: if `input_shape`, `kernel_shape` and `strides` don't have the
      same number of dimensions.
  NotImplementedError: if `padding` is not in {`"same"`, `"valid"`}.
>   r*   r+   Padding type 8 not supported. Only "valid" and "same" are implemented.UNumber of strides, input and kernel dimensions must all match. Received: stride_dims=
, in_dims=, kernel_dims=T)NotImplementedErrorr   r   r   r   conv_output_shapenpzerosboolrange	itertoolsproductconv_connected_inputs)input_shapekernel_shapestridesr1   in_dimskernel_dimsstride_dimsoutput_shape
mask_shapemaskdimoutput_axes_ticksoutput_positioninput_axes_ticksinput_positions                  r   conv_kernel_maskrd      sS   ^ ''!G9 %7 7
 	

 +G,$$$0'3*w&l#Kg,K!7,,7= 9i~k]<
 	
 %7L +J88J%D/;<|s|<$,,.?@0
 (//1ABN59D/12 C	 A K =s   :Dc              #     #    US;  a  [        SU S35      e[        U 5      n[        U[        5      (       a  U4U-  n[        U[        5      (       a  U4U-  n[        U5      n[        U5      n	X:w  d  X:w  a  [	        SU	 SU SU 35      e[        XX#5      n
U
 Vs/ s H  n[        U5      PM     nnUS:X  a  S nOUS	:X  a  S
 nO[	        SU S35      e[        R                  " U6  H  n[        XXU5      n[        R                  " U6  Hq  n[        U5       H_  n[        U5       HM  n[        R                  " U" UU5      U" X5      S9n[        R                  " U" UU5      U" X5      S9nUU4v   MO     Ma     Ms     M     gs  snf 7f)a  Yields output-input tuples of indices in a CNN layer.

The generator iterates over all `(output_idx, input_idx)` tuples, where
`output_idx` is an integer index in a flattened tensor representing a single
output image of a convolutional layer that is connected (via the layer
weights) to the respective single input image at `input_idx`

Example:

  >>> input_shape = (2, 2)
  >>> kernel_shape = (2, 1)
  >>> strides = (1, 1)
  >>> padding = "valid"
  >>> filters_in = 1
  >>> filters_out = 1
  >>> data_format = "channels_last"
  >>> list(conv_kernel_idxs(input_shape, kernel_shape, strides, padding,
  ...                       filters_in, filters_out, data_format))
  [(0, 0), (0, 2), (1, 1), (1, 3)]

Args:
  input_shape: tuple of size N: `(d_in1, ..., d_inN)`, spatial shape of the
    input.
  kernel_shape: tuple of size N, spatial shape of the convolutional kernel /
    receptive field.
  strides: tuple of size N, strides along each spatial dimension.
  padding: type of padding, string `"same"` or `"valid"`.
    `"valid"` means no padding. `"same"` results in padding evenly to
    the left/right or up/down of the input such that output has the same
    height/width dimension as the input.
  filters_in: `int`, number if filters in the input to the layer.
  filters_out: `int', number if filters in the output of the layer.
  data_format: string, "channels_first" or "channels_last".

Yields:
  The next tuple `(output_idx, input_idx)`, where `output_idx` is an integer
  index in a flattened tensor representing a single output image of a
  convolutional layer that is connected (via the layer weights) to the
  respective single input image at `input_idx`.

Raises:
    ValueError: if `data_format` is neither `"channels_last"` nor
      `"channels_first"`, or if number of strides, input, and kernel number
      of dimensions do not match.

    NotImplementedError: if `padding` is neither `"same"` nor `"valid"`.
)r*   r+   rH   rI   rJ   rK   rL   r   c                     U4U -   $ Nr.   spatial_idx
filter_idxs     r   <lambda>"conv_kernel_idxs.<locals>.<lambda>  s    ZMK,Gr   r   c                     U U4-   $ rg   r.   rh   s     r   rk   rl     s    kE
 7
r   zData format `zK` not recognized.`data_format` must be "channels_first" or "channels_last".)multi_indexdimsN)rM   r   r   r   r   rN   rR   rS   rT   rU   rO   ravel_multi_index)rV   rW   rX   r1   
filters_infilters_outr   rY   rZ   r[   r\   r_   r`   concat_idxsra   rb   rc   f_inf_outout_idxin_idxs                        r   conv_kernel_idxsrx   K  s    p ''!G9 %7 7
 	

 +G,$$$0'3*w&l#Kg,K!7,,7= 9i~k]<
 	
 %7L 0<<|s|<&&G 	 
	'
 K= )I I
 	

 %,,.?@0
 (//1ABNj)";/E 22$/$G(CG  11$/$E(AF #F++ 0 * C	 A! =s   BFF2CFc                    / n[        U 5      n[        U5       He  n[        X   S-  5      nX   U-
  n	X'   X7   -  n
US:X  a  X-  n
[        SX-
  5      n[	        X   X-   5      nUR                  [        X5      5        Mg     U$ )a  Return locations of the input connected to an output position.

Assume a convolution with given parameters is applied to an input having N
spatial dimensions with `input_shape = (d_in1, ..., d_inN)`. This method
returns N ranges specifying the input region that was convolved with the
kernel to produce the output at position
`output_position = (p_out1, ..., p_outN)`.

Example:

  >>> input_shape = (4, 4)
  >>> kernel_shape = (2, 1)
  >>> output_position = (1, 1)
  >>> strides = (1, 1)
  >>> padding = "valid"
  >>> conv_connected_inputs(input_shape, kernel_shape, output_position,
  ...                       strides, padding)
  [range(1, 3), range(1, 2)]

Args:
  input_shape: tuple of size N: `(d_in1, ..., d_inN)`, spatial shape of the
    input.
  kernel_shape: tuple of size N, spatial shape of the convolutional kernel /
    receptive field.
  output_position: tuple of size N: `(p_out1, ..., p_outN)`, a single
    position in the output of the convolution.
  strides: tuple of size N, strides along each spatial dimension.
  padding: type of padding, string `"same"` or `"valid"`.
    `"valid"` means no padding. `"same"` results in padding evenly to
    the left/right or up/down of the input such that output has the same
    height/width dimension as the input.

Returns:
  N ranges `[[p_in_left1, ..., p_in_right1], ...,
            [p_in_leftN, ..., p_in_rightN]]` specifying the region in the
  input connected to output_position.
r8   r+   r   )r   rR   r   r<   minappend)rV   rW   ra   rX   r1   rangesndimsd
left_shiftright_shiftcenterstartends                r   rU   rU     s    P FE5\1,-
"o
2 #gj0g FAv*++.&"67eE'(  Mr   c           
          [        [        U5      5      nU Vs/ s H  n[        X   X   X2U   5      PM     nn[        U Vs/ s H  oPU   S:X  a  SOXe   PM     sn5      nU$ s  snf s  snf )a  Return the output shape of an N-D convolution.

Forces dimensions where input is empty (size 0) to remain empty.

Args:
  input_shape: tuple of size N: `(d_in1, ..., d_inN)`, spatial shape of the
    input.
  kernel_shape: tuple of size N, spatial shape of the convolutional kernel /
    receptive field.
  strides: tuple of size N, strides along each spatial dimension.
  padding: type of padding, string `"same"` or `"valid"`.
    `"valid"` means no padding. `"same"` results in padding evenly to
    the left/right or up/down of the input such that output has the same
    height/width dimension as the input.

Returns:
  tuple of size N: `(d_out1, ..., d_outN)`, spatial shape of the output.
r   )rR   r   r6   r   )rV   rW   rX   r1   ro   r~   r\   s          r   rN   rN     s    & \"#D A 	;><?GQZP   @DE1!n!|	6EL 
 	Fs   A#A(c           	         [         R                  " S5         U R                  nX2* S nUR                  5       (       d  [         R                  " U 5      U* S nUSU*  nUR                  5       (       d  [         R                  " U 5      SU*  n[	        U[         R
                  5      (       a*  [         R                  " U S/UR                  5       -   5      nO-[         R                  " U [         R                  " S/U4SS95      nU" U5      nUR                  U* S nUR                  5       (       d  [         R                  " U5      U* S n[         R                  " U[         R                  " XX4SS95      n	U	R                  U R                  SU*  U	R                  U* S -   5        U	sSSS5        $ ! , (       d  f       g= f)a  Returns `unsqueeze_batch(op(squeeze_batch(inp)))`.

Where `squeeze_batch` reshapes `inp` to shape
`[prod(inp.shape[:-inner_rank])] + inp.shape[-inner_rank:]`
and `unsqueeze_batch` does the reverse reshape but on the output.

Args:
  inp: A tensor with dims `batch_shape + inner_shape` where `inner_shape`
    is length `inner_rank`.
  op: A callable that takes a single input tensor and returns a single.
    output tensor.
  inner_rank: A python integer.

Returns:
  `unsqueeze_batch_op(squeeze_batch(inp))`.
squeeze_batch_dimsN)axis)
tf
name_scopeshapeis_fully_definedr   TensorShapereshapeas_listconcat	set_shape)
inpop
inner_rankr   inner_shapebatch_shapeinp_reshapedout_reshapedout_inner_shapeouts
             r   r   r     sw   " 
+	,		KL)++--((3-5KLj[)++--((3-*5Kk2>>22::cB4+2E2E2G+GHL::RYYk2<L ,'&,,j[\://11 hh|4j[\BOjj"))[$BL
 	cii*-		:+,0GGH; 
-	,	,s   FF00
F>)F)r-   )Nr   r-   )__doc__rS   numpyrO   tensorflow.compat.v2compatv2r   tf_keras.srcr   r   r'   r6   r:   r?   rC   rF   rd   rx   rU   rN   r   r.   r   r   <module>r      si    ,   ! !  
@:z24@8 1h	
Slo,d9x<.r   