
    0hN                         d Z ddlZddlZddlmc mZ ddlm	Z	 d Z
ddZddZd Z	 	 	 ddZd	 Zd
 Zd Zd Zd Zd Zd Zy)z%Utilities used by convolution layers.    N)backendc                     | dk(  r!|dk(  ry|dk(  ry|dk(  ryt        d| d	      | d
k(  r!|dk(  ry|dk(  ry|dk(  ryt        d| d	      t        d|  d      )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/var/www/html/engine/venv/lib/python3.12/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           	         d| d| d|  }t        | t              r| f|z  }n8	 t        |       }t        |      |k7  rt	        |      |D ]  }	 t        |        |r|D ch c]
  }|dk  s	| }}d}	n|D ch c]
  }|dk  s	| }}d}	|r|d	| d
|	 dz  }t	        |      |S # t        $ r t	        |      w xY w# t        t        f$ r  |d| dt        |       z  }t	        |      w xY wc c}w c c}w )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   sj   * v3A3 7$g	' 
 %hl	(,K {q Y''' 	,L,L!	, )4>AAa>>)4?AQa??,-6wirC	
	 ##9  	(Y''	( 	* ,( 7 ./1	 !++, ? @s/   B' B?!
C1,C19
C6C6'B<?/C.c                     | y|dv sJ ||dz
  |dz
  z  z   }|dv r| }n|dk(  r	| |z
  dz   }n|dk(  r| |z   dz
  }|z   dz
  |z  S )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                 p    | y|dv sJ |dk(  r|dz  }n|dk(  rd}n
|dk(  r|dz
  }| dz
  |z  dz  z
  |z   S )	a  Determines 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                    |dv sJ | y||dz
  |dz
  z  z   }|=|dk(  r| |z  t        ||z
  d      z   }|S |dk(  r| |z  ||z   dz
  z
  }|S |dk(  r| |z  }S |dk(  r|dz  }n|dk(  rd}n
|dk(  r|dz
  }| dz
  |z  |z   dz  z
  |z   }|S )	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!F*Sv1Eq-IIF" M! !F*f{.BQ.FGF M !F*F M f"CC/C A'+5C?.P 	 Mr   c                 v    | t        j                         } | j                         }|dvrt        d|        |S )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                 z    t        | t        t        f      r| S | j                         }|dvrt	        d|       |S )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      sL    %$'kkmG11 	#
 	

 Nr   c                     |dvrt        d| d      t        |       }t        |t              r|f|z  }t        |t              r|f|z  }t        |      }t        |      }||k7  s||k7  rt	        d| d| d|       t        | |||      }| |z   }t        j                  |t              }	|D 
cg c]  }
t        |
       }}
t        j                  | D ]0  }t        | ||||      }t        j                  | D ]
  }d|	||z   <    2 |	S c c}
w )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      sd   ^ ''!G9 %7 7
 	

 +G,$$0'3*w&l#Kg,Kg!7,,7= 9i~k]<
 	
 %\7GL |+J88J%D/;<s<<$,,.?@ :0
 (//1AB 	:N59D/12	:	: K =s   0Dc              #     K   |dvrt        d| d      t        |       }t        |t              r|f|z  }t        |t              r|f|z  }t        |      }t        |      }	||k7  s|	|k7  rt	        d|	 d| d|       t        | |||      }
|
D cg c]  }t        |       }}|dk(  rd }n|d	k(  rd
 }nt	        d| d      t        j                  | D ]  }t        | ||||      }t        j                  | D ]r  }t        |      D ]b  }t        |      D ]R  }t        j                   |||       ||
|            }t        j                   |||       || |            }||f T d t  yc c}w w)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                     |f| z   S Nr.   spatial_idx
filter_idxs     r   <lambda>z"conv_kernel_idxs.<locals>.<lambda>  s    ZMK,G r   r   c                     | |fz   S rg   r.   rh   s     r   rk   z"conv_kernel_idxs.<locals>.<lambda>  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_idxsrw   K  s    p ''!G9 %7 7
 	

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

 %,,.?@ ,0
 (//1AB 	,Nj) 
,";/ 	,E 22$/$G({CG  11$/$E(jAF #F++	,
,	,	,! =s   BE;E6%CE;c                    g }t        |       }t        |      D ]l  }t        ||   dz        }||   |z
  }	||   ||   z  }
|dk(  r|
|z  }
t        d|
|z
        }t	        | |   |
|	z         }|j                  t        ||             n |S )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\ )a1,-
"1o
2 #gaj0gj FAv
*++a.&;"67eE3'() Mr   c           
          t        t        |            }|D cg c]  }t        | |   ||   |||          }}t        |D cg c]  }| |   dk(  rdn||    c}      }|S c c}w c c}w )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   rn   r}   r\   s          r   rN   rN     s    & \"#D  	;q><?GWQZPL  @DE1k!n!|A	6EL 
 	Fs   A!A&c                 N   t        j                  d      5  | j                  }|| d }|j                         st        j                  |       | d }|d|  }|j                         st        j                  |       d|  }t	        |t         j
                        r)t        j                  | dg|j                         z         }n.t        j                  | t        j                  dg|fd            } ||      }|j                  | d }|j                         st        j                  |      | d }t        j                  |t        j                  ||fd            }	|	j                  | j                  d|  |	j                  | d z          |	cddd       S # 1 sw Y   yxY w)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     sx   " 
+	, 		ZKL)++-((3-5KLj[)++-((3-*5Kk2>>2::cB4+2E2E2G+GHL::RYYk2<L ,'&,,j[\://1 hh|4j[\BOjj"))[/$BL
 	cii*-		:+,0GGH;  s   E;FF$)F)r-   )Nr   r-   )__doc__rS   numpyrO   tensorflow.compat.v2compatv2r   tf_keras.srcr   r   r'   r6   r:   r?   rC   rF   rd   rw   rU   rN   r   r.   r   r   <module>r      si    ,   ! !  
@:z24@8 1h	
Slo,d9x<.r   