a
    h                     @  s  d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 ddl
mZmZmZmZ e	eZdddd	d
dZdddd	ddZdddd	ddZdddd	ddZdddd	ddZdddd	ddZdddddZdddd	ddZdddddZdddddd ZdS )!    )annotationsN)pairwise_distances)Tensor)logging   )_convert_to_batch_tensor_convert_to_tensornormalize_embeddingsto_scipy_coor   )abreturnc                 C  s
   t | |S )  
    Computes the cosine similarity between two tensors.

    Args:
        a (Union[list, np.ndarray, Tensor]): The first tensor.
        b (Union[list, np.ndarray, Tensor]): The second tensor.

    Returns:
        Tensor: Matrix with res[i][j] = cos_sim(a[i], b[j])
    )cos_simr   r    r   a/var/www/html/assistant/venv/lib/python3.9/site-packages/sentence_transformers/util/similarity.pypytorch_cos_sim   s    r   zlist | np.ndarray | Tensorc                 C  s8   t | } t |}t| }t|}t||dd S )r   r   r   )r   r	   torchmm	transposeto_denser   r   Za_normZb_normr   r   r   r      s
    r   c                 C  sZ   t | } t |}| js|jr@t| }t|}|| jdd S tt| t| S dS )a  
    Computes the pairwise cosine similarity cos_sim(a[i], b[i]).

    Args:
        a (Union[list, np.ndarray, Tensor]): The first tensor.
        b (Union[list, np.ndarray, Tensor]): The second tensor.

    Returns:
        Tensor: Vector with res[i] = cos_sim(a[i], b[i])
    dimN)r   	is_sparser	   sumr   pairwise_dot_scorer   r   r   r   pairwise_cos_sim0   s    r   c                 C  s(   t | } t |}t| |dd S )a  
    Computes the dot-product dot_prod(a[i], b[j]) for all i and j.

    Args:
        a (Union[list, np.ndarray, Tensor]): The first tensor.
        b (Union[list, np.ndarray, Tensor]): The second tensor.

    Returns:
        Tensor: Matrix with res[i][j] = dot_prod(a[i], b[j])
    r   r   )r   r   r   r   r   r   r   r   r   	dot_scoreG   s    r    c                 C  s$   t | } t |}| | jdd S )a  
    Computes the pairwise dot-product dot_prod(a[i], b[i]).

    Args:
        a (Union[list, np.ndarray, Tensor]): The first tensor.
        b (Union[list, np.ndarray, Tensor]): The second tensor.

    Returns:
        Tensor: Vector with res[i] = dot_prod(a[i], b[i])
    r   r   )r   r   r   r   r   r   r   r   X   s    r   c                 C  sz   t | } t |}| js|jr`td t| }t|}t||dd}t|  	| j
 S tj| |dd  S dS )a  
    Computes the manhattan similarity (i.e., negative distance) between two tensors.
    Handles sparse tensors without converting to dense when possible.

    Args:
        a (Union[list, np.ndarray, Tensor]): The first tensor.
        b (Union[list, np.ndarray, Tensor]): The second tensor.

    Returns:
        Tensor: Matrix with res[i][j] = -manhattan_distance(a[i], b[j])
    z8Using scipy for sparse Manhattan similarity computation.Z	manhattan)Zmetricg      ?pN)r   r   loggerwarning_oncer
   r   r   Z
from_numpyfloattoZdevicer   cdist)r   r   Za_cooZb_coodistr   r   r   manhattan_simi   s    
r)   r   c                 C  s.   t | } t |}tjt| | dd  S )a<  
    Computes the manhattan similarity (i.e., negative distance) between pairs of tensors.

    Args:
        a (Union[list, np.ndarray, Tensor]): The first tensor.
        b (Union[list, np.ndarray, Tensor]): The second tensor.

    Returns:
        Tensor: Vector with res[i] = -manhattan_distance(a[i], b[i])
    r   r   )r   r   r   absr   r   r   r   r   pairwise_manhattan_sim   s    r+   c                 C  s   t | } t |}| jrtjj| |  dd d}tjj|| dd d}t| |  }|d|  | }tj	|dd}t
|  S tj| |dd S d	S )
a  
    Computes the euclidean similarity (i.e., negative distance) between two tensors.
    Handles sparse tensors without converting to dense when possible.

    Args:
        a (Union[list, np.ndarray, Tensor]): The first tensor.
        b (Union[list, np.ndarray, Tensor]): The second tensor.

    Returns:
        Tensor: Matrix with res[i][j] = -euclidean_distance(a[i], b[j])
    r   r   r      g        )ming       @r!   N)r   r   r   sparser   r   Z	unsqueezematmultclampsqrtr'   )r   r   Z	a_norm_sqZ	b_norm_sqZdot_productZsquared_distr   r   r   euclidean_sim   s    r3   c                 C  s2   t | } t |}ttj| | d dd  S )a:  
    Computes the euclidean distance (i.e., negative distance) between pairs of tensors.

    Args:
        a (Union[list, np.ndarray, Tensor]): The first tensor.
        b (Union[list, np.ndarray, Tensor]): The second tensor.

    Returns:
        Tensor: Vector with res[i] = -euclidean_distance(a[i], b[i])
    r,   r   r   )r   r   r2   r   r   r   r   r   r   pairwise_euclidean_sim   s    r4   )xyr   c                 C  s"  | j r(td |   } |  }t| } t|}tj| ddd\}}tj|ddd\}}tj|d |d  ddd}|| ||  | }|| ||  | }tj|d |d  dddd }	tj|d |d  dddd }
||	|
  }||	|
  }tjtj	||fdddd}t
|S )aP  
    Computes the absolute normalized angle distance. See :class:`~sentence_transformers.losses.AnglELoss`
    or https://arxiv.org/abs/2309.12871v1 for more information.

    Args:
        x (Tensor): The first tensor.
        y (Tensor): The second tensor.

    Returns:
        Tensor: Vector with res[i] = angle_sim(a[i], b[i])
    zOPairwise angle similarity does not support sparse tensors. Converting to dense.r,   r   r   T)r   Zkeepdimg      ?)r   r#   r$   Zcoalescer   r   r   chunkr   concatr*   )r5   r6   r   r   cdzreZimZdzZdwZ
norm_angler   r   r   pairwise_angle_sim   s"    
  r=   )
__future__r   numpynpr   Zsklearn.metricsr   r   Ztransformers.utilsr   Ztensorr   r   r	   r
   Z
get_logger__name__r#   r   r   r   r    r   r)   r+   r3   r4   r=   r   r   r   r   <module>   s"   
