
    6bi!                         S r SSKJs  Jr  SSKJr  SSKJr  SSK	J
r
  SSKJr  \" S5       " S S	\5      5       r\" S
5      SS j5       rg)z'Layer that concatenates several inputs.    N)backend)_Merge)tf_utils)keras_exportzkeras.layers.Concatenatec                      ^  \ rS rSrSrS
U 4S jjr\R                  S 5       rS r	\R                  S 5       r
SS jrU 4S jrS	rU =r$ )Concatenate   a  Layer that concatenates a list of inputs.

It takes as input a list of tensors, all of the same shape except
for the concatenation axis, and returns a single tensor that is the
concatenation of all inputs.

>>> x = np.arange(20).reshape(2, 2, 5)
>>> print(x)
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]
 [[10 11 12 13 14]
  [15 16 17 18 19]]]
>>> y = np.arange(20, 30).reshape(2, 1, 5)
>>> print(y)
[[[20 21 22 23 24]]
 [[25 26 27 28 29]]]
>>> tf.keras.layers.Concatenate(axis=1)([x, y])
<tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [20, 21, 22, 23, 24]],
       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [25, 26, 27, 28, 29]]])>

>>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
>>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
>>> concatted = tf.keras.layers.Concatenate()([x1, x2])
>>> concatted.shape
TensorShape([5, 16])

c                 N   > [         TU ]  " S0 UD6  Xl        SU l        SU l        g)a~  Instantiates a Concatenate layer.

>>> x = np.arange(20).reshape(2, 2, 5)
>>> print(x)
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]
 [[10 11 12 13 14]
  [15 16 17 18 19]]]
>>> y = np.arange(20, 30).reshape(2, 1, 5)
>>> print(y)
[[[20 21 22 23 24]]
 [[25 26 27 28 29]]]
>>> tf.keras.layers.Concatenate(axis=1)([x, y])
<tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [20, 21, 22, 23, 24]],
       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [25, 26, 27, 28, 29]]])>

Args:
  axis: Axis along which to concatenate.
  **kwargs: standard layer keyword arguments.
TFN )super__init__axissupports_masking_reshape_required)selfr   kwargs	__class__s      a/home/james-whalen/.local/lib/python3.13/site-packages/tf_keras/src/layers/merging/concatenate.pyr   Concatenate.__init__?   s*    4 	"6"	 $!&    c                   ^
 [        U5      S:  d  [        US   [        5      (       d  [        SU 35      e[	        S U 5       5      (       a  g U Vs/ s H  n[        U5      PM     nn[        5       n[        [        U5      5       H.  nX5   U R                  	 UR                  [        X5   5      5        M0     [        U5      S:w  aw  SU 3n[        S U 5       5      n[        U5      S:w  a  [        U5      eUu  n[        U5       H2  m
[        U
4S jU 5       5      n	[        U	5      S:  d  M)  [        U5      e   g g s  snf )N   r   z\A `Concatenate` layer should be called on a list of at least 1 input. Received: input_shape=c              3   (   #    U  H  oS L v   M
     g 7fNr   .0shapes     r   	<genexpr>$Concatenate.build.<locals>.<genexpr>f   s     6+}+   ztA `Concatenate` layer requires inputs with matching shapes except for the concatenation axis. Received: input_shape=c              3   8   #    U  H  n[        U5      v   M     g 7fr   )lenr   s     r   r   r   u   s     :	uE

	s   c              3   >   >#    U  H  nUT   c  M  UT   v   M     g 7fr   r   )r   r   r   s     r   r   r   }   s%      "!*T{  E$K!*s   
)
r"   
isinstancetuple
ValueErroralllistsetranger   add)r   input_shaper   reduced_inputs_shapes	shape_setierr_msgranksrankunique_dimsr   s             @r   buildConcatenate.build^   sK    {az+a.%'H'H;;F-I  6+666:E F+e+ FE	s012A%(3MM% 5 89: 3 y>Q))47  :	::E5zQ ))GTd " "!*" 
 {#a'$W-- $  !Gs   Ec                 >    [         R                  " XR                  S9$ )Nr   )r   concatenater   )r   inputss     r   _merge_functionConcatenate._merge_function   s    ""6		::r   c                 ~   [        U[        [        45      (       a  [        US   [        [        45      (       d  [        SU 35      eUn[        US   5      nUSS   HS  nX0R                     b  X@R                     c  S X0R                  '     O&X0R                  ==   X@R                     -  ss'   MU     [        U5      $ )Nr   zRA `Concatenate` layer should be called on a list of inputs. Received: input_shape=r   )r$   r%   r(   r&   r   )r   r,   input_shapesoutput_shaper   s        r   compute_output_shape Concatenate.compute_output_shape   s    ;66;q>E4=99 ))47  #LO,!!"%EII&.%		2B2J*.YY'#uYY'77#	 &
 \""r   c                    Uc  g [        U[        [        45      (       d  [        SU 35      e[        U[        [        45      (       d  [        SU 35      e[	        U5      [	        U5      :w  a)  [        SU S[	        U5       SU S[	        U5       35      e[        S U 5       5      (       a  g / n[        X5       H  u  pEUc&  UR                  [        R                  " USS95        M.  [        R                  " U5      [        R                  " U5      :  a&  UR                  [        R                  " US	S
95        M  UR                  U5        M     [        R                  " X0R                  S
9n[        R
                  " US	SS9$ )Nz'`mask` should be a list. Received mask=z,`inputs` should be a list. Received: inputs=zLThe lists `inputs` and `mask` should have the same length. Received: inputs=z of length z, and mask=c              3   (   #    U  H  oS L v   M
     g 7fr   r   )r   ms     r   r   +Concatenate.compute_mask.<locals>.<genexpr>   s     '$QDy$r    bool)dtyper7   F)r   keepdims)r$   r%   r(   r&   r"   r'   zipappendtf	ones_liker   ndimexpand_dimsr8   r   )r   r9   maskmasksinput_imask_iconcatenateds          r   compute_maskConcatenate.compute_mask   sS   <$..FtfMNN&5$-00>vhG  t9F#$$*8;s6{m Dv[T5 
 '$''' "60OG~R\\'@Af%W(==R^^F<=V$  1 **5yyA{{<b5AAr   c                    > SU R                   0n[        TU ]	  5       n[        [	        UR                  5       5      [	        UR                  5       5      -   5      $ )Nr   )r   r   
get_configdictr(   items)r   configbase_configr   s      r   rW   Concatenate.get_config   sK    DII
 g(*D**,-V\\^0DDEEr   )r   r   r   rG   r   )__name__
__module____qualname____firstlineno____doc__r   r   shape_type_conversionr4   r:   r?   rT   rW   __static_attributes____classcell__)r   s   @r   r   r      s[    B'> ##$. $$.L; ### $#*BBF Fr   r   zkeras.layers.concatenatec                 (    [        SSU0UD6" U 5      $ )a  Functional interface to the `Concatenate` layer.

>>> x = np.arange(20).reshape(2, 2, 5)
>>> print(x)
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]
 [[10 11 12 13 14]
  [15 16 17 18 19]]]
>>> y = np.arange(20, 30).reshape(2, 1, 5)
>>> print(y)
[[[20 21 22 23 24]]
 [[25 26 27 28 29]]]
>>> tf.keras.layers.concatenate([x, y],
...                             axis=1)
<tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
array([[[ 0,  1,  2,  3,  4],
      [ 5,  6,  7,  8,  9],
      [20, 21, 22, 23, 24]],
     [[10, 11, 12, 13, 14],
      [15, 16, 17, 18, 19],
      [25, 26, 27, 28, 29]]])>

Args:
    inputs: A list of input tensors.
    axis: Concatenation axis.
    **kwargs: Standard layer keyword arguments.

Returns:
    A tensor, the concatenation of the inputs alongside axis `axis`.
r   r   )r   )r9   r   r   s      r   r8   r8      s    @ +D+F+F33r   r]   )rb   tensorflow.compat.v2compatv2rK   tf_keras.srcr   &tf_keras.src.layers.merging.base_merger   tf_keras.src.utilsr    tensorflow.python.util.tf_exportr   r   r8   r   r   r   <module>rn      sb    . " !   9 ' : ()gF& gF *gFT ()4 *4r   