
    2Vh1                         d dl mZ d dlmZ d dlmZ d dlmZ ddZ ed       G d d	e             Z	 ed
      dd       Z
y)    )ops)keras_export)Merge)	normalizeNc                    | j                   }|j                   }t        |      }t        |      }|dk  s|dk  rt        d| d| d      |d   }|d   }||||k7  rt        d| d| d      t        |t              r||g}||dk(  r|dz
  |dz
  g}n
|dz
  |dz
  g}t        d	 |D              rt        d
| d      t        |      }|d   dk  r|dxx   |z  cc<   |d   dk  r|dxx   |z  cc<   d|v rt        d      |\  }	}
||	   }||
   }|.|,||k7  r't        d| d| d| d|d    d|d    d| d| d      |}|}|dk(  r t        j                  | d      } |	dz  }	|dz  }|dk(  rt        j                  |d      }|dz  }|	|dz
  k7  rNt        t        |            }t        |	|dz
        D ]  }||dz      ||<    |	|d<   t        j                  | |      } |
dk7  rLt        t        |            }t        |
dd      D ]  }||dz
     ||<    |
|d<   t        j                  ||      }|dkD  r>t        j                   |       }|dd }|d   d|d   f}t        j                  | |      } d}nd}|dkD  r>t        j                   |      }|dd }|d   |d   df}t        j                  ||      }d}nd}t        j                  | |      }t        j                   |      }d}|r|dd z   |dd z   }d}|r
|dd z   }d}|rt        j                  ||      }|dk(  rt        j                  |d      }|S |dk(  rt        j                  |d      }|S )a7  Batchwise dot product.

    `batch_dot` is used to compute dot product of `x` and `y` when
    `x` and `y` are data in batch, i.e. in a shape of `(batch_size, :)`.
    `batch_dot` results in a tensor or variable with less dimensions
    than the input. If the number of dimensions is reduced to 1,
    we use `expand_dims` to make sure that ndim is at least 2.

    Shape inference:

    Let `x`'s shape be `(100, 20)` and `y`'s shape be `(100, 30, 20)`.
    If `axes` is (1, 2), to find the output shape of resultant tensor,
    loop through each dimension in `x`'s shape and `y`'s shape:

    * `x.shape[0]` : 100 : append to output shape
    * `x.shape[1]` : 20 : do not append to output shape, dimension 1 of
        `x` has been summed over. (`dot_axes[0]` = 1)
    * `y.shape[0]` : 100 : do not append to output shape, always ignore
        first dimension of `y`
    * `y.shape[1]` : 30 : append to output shape
    * `y.shape[2]` : 20 : do not append to output shape, dimension 2 of
        `y` has been summed over.
        (`dot_axes[1]` = 2) `output_shape` = `(100, 30)`

    Example:

    >>> x_batch = np.ones(shape=(32, 20, 1))
    >>> y_batch = np.ones(shape=(32, 30, 20))
    >>> xy_batch_dot = batch_dot(x_batch, y_batch, axes=(1, 2))

    Args:
        x: Keras tensor or variable with `ndim >= 2`.
        y: Keras tensor or variable with `ndim >= 2`.
        axes: Tuple or list of integers with target dimensions, or single
            integer. The sizes of `x.shape[axes[0]]` and `y.shape[axes[1]]`
            should be equal.

    Returns:
        A tensor with shape equal to the concatenation of `x`'s shape
        (less the dimension that was summed over) and `y`'s shape (less the
        batch dimension and the dimension that was summed over). If the final
        rank is 1, we reshape it to `(batch_size, 1)`.
       zICannot do batch_dot on inputs with rank < 2. Received inputs with shapes z and .r   NzVCannot do batch_dot on inputs with different batch sizes. Received inputs with shapes    c              3   H   K   | ]  }t        |t        t        f        y wN)
isinstancelisttuple).0as     L/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/layers/merging/dot.py	<genexpr>zbatch_dot.<locals>.<genexpr>V   s     
6A:a$'
6s    "zYMultiple target dimensions are not supported. Expected: None, int, (int, int), Provided:  zCannot perform batch_dot over axis 0. If your inputs are not batched, add a dummy batch dimension to your inputs using keras.ops.expand_dims(x, 0)z*Cannot do batch_dot on inputs with shapes z with axes=z
. x.shape[z] != y.shape[z] (z != z).   TF)shapelen
ValueErrorr   intanyr   r   expand_dimsrange	transposereshapematmulsqueeze)xyaxesx_shapey_shapex_ndimy_ndimx_batch_sizey_batch_sizea0a1d1d2orig_x_ndimorig_y_ndimpatterni
x_mid_dimsx_squashed_shape
x_squashedy_trail_dimsy_squashed_shape
y_squashedresultoutput_shape
do_reshapes                             r   	batch_dotr<      sS   Z ggGggG\F\FzVaZ+ iuWIQ(
 	
 1:L1:LL$<<'/ )5	,  $d||Q;QJ
+DQJ
+D

6
66a!
 	
 :D Aw{Q6Aw{Q6 	Dy7
 	
 FB	B	B	~".R2X8iuWI[ 7Awi}T!WISDBH
 	
 KK {OOAq!
a!{OOAq!! 
VaZuV}%r6A:& 	(A QGAJ	(MM!W% 
QwuV}%r1b! 	(A QGAJ	(
MM!W% z))A,Qr]
#AJGBK8KK+,

z))A,qr{#AJ
B7KK+,

ZZ1F 99V$LJ#BQ'*4|BC7HH
#CR(<7
V\2 aVQ' M 
	VR(M    zkeras.layers.Dotc                   H     e Zd ZdZd fd	Zd Zd Zd Zd	dZ fdZ	 xZ
S )
Dota  Computes element-wise dot product of two tensors.

    It takes a list of inputs of size 2, and the axes
    corresponding to each input along with the dot product
    is to be performed.

    Let's say `x` and `y` are the two input tensors with shapes
    `(2, 3, 5)` and `(2, 10, 3)`. The batch dimension should be
    of same size for both the inputs, and `axes` should correspond
    to the dimensions that have the same size in the corresponding
    inputs. e.g. with `axes=(1, 2)`, the dot product of `x`, and `y`
    will result in a tensor with shape `(2, 5, 10)`

    Example:

    >>> x = np.arange(10).reshape(1, 5, 2)
    >>> y = np.arange(10, 20).reshape(1, 2, 5)
    >>> keras.layers.Dot(axes=(1, 2))([x, y])

    Usage in a Keras model:

    >>> x1 = keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
    >>> x2 = keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
    >>> y = keras.layers.Dot(axes=1)([x1, x2])

    Args:
        axes: Integer or tuple of integers, axis or axes along which to
            take the dot product. If a tuple, should be two integers
            corresponding to the desired axis from the first input and the
            desired axis from the second input, respectively. Note that the
            size of the two selected axes must match.
        normalize: Whether to L2-normalize samples along the dot product axis
            before taking the dot product. If set to `True`, then
            the output of the dot product is the cosine proximity
            between the two samples.
        **kwargs: Standard layer keyword arguments.

    Returns:
        A tensor, the dot product of the samples from the inputs.
    c                 d   t        |   d	i | t        |t              stt        |t        t
        f      st        d|       t        |      dk7  rt        d|       t        |d   t              rt        |d   t              st        d|       || _	        || _
        d| _        d| _        y )
NzPInvalid type for argument `axes`: it should be a list or an int. Received: axes=r   zSInvalid format for argument `axes`: it should contain two elements. Received: axes=r   r
   zUInvalid format for argument `axes`: list elements should be integers. Received: axes=TF )super__init__r   r   r   r   	TypeErrorr   r   r$   r   supports_masking_reshape_required)selfr$   r   kwargs	__class__s       r   rC   zDot.__init__   s    "6"$$dT5M288<v?  4yA~ 4486;  d1gs+:d1gs3K 337&:  	" $!&r=   c                    t        |d   t        t        f      rt        |      dk7  rt	        d|       |d   }|d   }||y t        | j
                  t              rQ| j
                  dk  r1| j
                  t        |      z  | j
                  t        |      z  g}n| j
                  gdz  }n| j
                  }||d      ||d      k7  r/t	        d||d       d|d    d||d       d|d    d| d	|       y )
Nr   r   LA `Dot` layer should be called on a list of 2 inputs. Received: input_shape=r
   z'Incompatible input shapes: axis values z
 (at axis z) != z). Full input shapes: z, )r   r   r   r   r   r$   r   )rG   input_shapeshape1shape2r$   s        r   buildz	Dot.build  s*    ;q>E4=9;1$))47  QQ>V^dii%yy1}		CK/S[1HI		{Q99D$q'?fT!Wo-%d1g/z$q'%$q'?#:d1gY 7&&,XRx9  .r=   c                    t        |      dk7  rt        d|       |d   }|d   }t        | j                  t              re| j                  dk  rE| j                  t        |j
                        z  | j                  t        |j
                        z  g}n| j                  gdz  }ng }t        t        | j                              D ]j  }| j                  |   dk  r8|j                  | j                  |   t        ||   j
                        z         M|j                  | j                  |          l | j                  r t        ||d         }t        ||d         }t        |||      }|S )Nr   zEA `Dot` layer should be called on exactly 2 inputs. Received: inputs=r   r
   )axis)
r   r   r   r$   r   r   r   appendr   r<   )rG   inputsx1x2r$   r2   outputs          r   _merge_functionzDot._merge_function$  s>   v;!$$*8-  AYAYdii%yy1}IIBHH-IIBHH-
 		{QD3tyy>* .99Q<!#KK		!s6!9??/C CDKK		!-	. >>2DG,B2DG,B2r4(r=   c                 F   t        |t        t        f      rt        |      dk7  rt	        d|       t        |d         }t        |d         }t        | j
                  t              rQ| j
                  dk  r1| j
                  t        |      z  | j
                  t        |      z  g}n| j
                  gdz  }n| j
                  }|j                  |d          |j                  |d          |j                  d       ||z   }t        |      dk(  r|dgz  }t        |      S )Nr   rK   r   r
   )r   r   r   r   r   r$   r   pop)rG   rL   rM   rN   r$   r:   s         r   compute_output_shapezDot.compute_output_shapeC  s   +t}5[9IQ9N))47  k!n%k!n%dii%yy1}		CK/S[1HI		{Q99D

47

47

1|!QCL\""r=   c                      y r   rA   )rG   rS   masks      r   compute_maskzDot.compute_maskZ  s    r=   c                     | j                   | j                  d}t        |          }t	        t        |j                               t        |j                               z         S )N)r$   r   )r$   r   rB   
get_configdictr   items)rG   configbase_configrI   s      r   r_   zDot.get_config]  sP    II
 g(*D**,-V\\^0DDEEr=   )Fr   )__name__
__module____qualname____doc__rC   rO   rW   rZ   r]   r_   __classcell__)rI   s   @r   r?   r?      s.    'R'.:>#.F Fr=   r?   zkeras.layers.dotc                 (     t        dd|i||       S )aS  Functional interface to the `Dot` layer.

    Args:
        inputs: A list of input tensors (at least 2).
        axes: Integer or tuple of integers,
            axis or axes along which to take the dot product.
        normalize: Whether to L2-normalize samples along the
            dot product axis before taking the dot product.
            If set to `True`, then the output of the dot product
            is the cosine proximity between the two samples.
        **kwargs: Standard layer keyword arguments.

    Returns:
        A tensor, the dot product of the samples from the inputs.
    r$   rA   )r?   )rS   r$   rH   s      r   dotrj   f  s    " $3#D#F#F++r=   r   )r   )	keras.srcr   keras.src.api_exportr   #keras.src.layers.merging.base_merger   keras.src.utils.numerical_utilsr   r<   r?   rj   rA   r=   r   <module>ro      sZ     - 5 5{|  !]F% ]F "]F@  !, ",r=   