B
    ӻd                 @   sH   d Z ddlmZ ddlmZ dd Zdd Zdd	 Zd
d Zdd ZdS )z-Utility methods related to kernelized layers.    )	array_ops)math_opsc             C   s8   t | j}|dkr td||dkr4t| dS | S )zFIf input tensor is a vector (i.e., has rank 1), converts it to matrix.)      z8The input tensor should have rank 1 or 2. Given rank: {}r   r   )lenshape
ValueErrorformatr   expand_dims)uZu_rank r   `/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/keras/utils/kernelized_utils.py
_to_matrix   s    
r   c             C   s   t | }t |}|j}|j}|d |d krDtd|d |d tt|dd|d dg}tt|d|d ddg}||fS )zFAligns x and y tensors to allow computations over pairs of their rows.r   zLThe outermost dimensions of the input tensors should match. Given: {} vs {}.r   )r   r   r   r	   r   Ztiler
   )xyZx_matrixZy_matrixZx_shapeZy_shapeZx_tileZy_tiler   r   r   _align_matrices    s    r   c             C   s    t | } t |}tj| |ddS )NT)Ztranspose_b)r   r   matmul)r   vr   r   r   inner_product2   s    r   c             C   s:   t | |\}}tt||d}t| d| |  S )a  Computes exact Gaussian kernel value(s) for tensors x and y and stddev.

  The Gaussian kernel for vectors u, v is defined as follows:
       K(u, v) = exp(-||u-v||^2 / (2* stddev^2))
  where the norm is the l2-norm. x, y can be either vectors or matrices. If they
  are vectors, they must have the same dimension. If they are matrices, they
  must have the same number of columns. In the latter case, the method returns
  (as a matrix) K(u, v) values for all pairs (u, v) where u is a row from x and
  v is a row from y.

  Args:
    x: a tensor of rank 1 or 2. It's shape should be either [dim] or [m, dim].
    y: a tensor of rank 1 or 2. It's shape should be either [dim] or [n, dim].
    stddev: The width of the Gaussian kernel.

  Returns:
    A single value (scalar) with shape (1, 1) (if x, y are vectors) or a matrix
      of shape (m, n) with entries K(u, v) (where K is the Gaussian kernel) for
      all (u,v) pairs where u, v are rows from x and y respectively.

  Raises:
    ValueError: if the shapes of x, y are not compatible.
  r   )r   r   
reduce_sumZsquared_differenceexp)r   r   stddev	x_aligned	y_alignedZdiff_squared_l2_normr   r   r   exact_gaussian_kernel8   s    r   c             C   s8   t | |\}}ttt||d}t| | S )a  Computes exact Laplacian kernel value(s) for tensors x and y using stddev.

  The Laplacian kernel for vectors u, v is defined as follows:
       K(u, v) = exp(-||u-v|| / stddev)
  where the norm is the l1-norm. x, y can be either vectors or matrices. If they
  are vectors, they must have the same dimension. If they are matrices, they
  must have the same number of columns. In the latter case, the method returns
  (as a matrix) K(u, v) values for all pairs (u, v) where u is a row from x and
  v is a row from y.

  Args:
    x: a tensor of rank 1 or 2. It's shape should be either [dim] or [m, dim].
    y: a tensor of rank 1 or 2. It's shape should be either [dim] or [n, dim].
    stddev: The width of the Gaussian kernel.

  Returns:
    A single value (scalar) with shape (1, 1)  if x, y are vectors or a matrix
    of shape (m, n) with entries K(u, v) (where K is the Laplacian kernel) for
    all (u,v) pairs where u, v are rows from x and y respectively.

  Raises:
    ValueError: if the shapes of x, y are not compatible.
  r   )r   r   r   abssubtractr   )r   r   r   r   r   Zdiff_l1_normr   r   r   exact_laplacian_kernelV   s    r   N)	__doc__Ztensorflow.python.opsr   r   r   r   r   r   r   r   r   r   r   <module>   s   