
    bi#                        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	j        e          ZddZddZddZddZddZddZddZddZddZddZdS )    )annotationsN)pairwise_distances)Tensor)logging   )_convert_to_batch_tensor_convert_to_tensornormalize_embeddingsto_scipy_cooar   breturnc                "    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   s     `/root/projects/butler/venv/lib/python3.11/site-packages/sentence_transformers/util/similarity.pypytorch_cos_simr      s     1a==    list | np.ndarray | Tensorc                    t          |           } t          |          }t          |           }t          |          }t          j        ||                    dd                                                    S )r   r   r   )r   r
   torchmm	transposeto_denser   r   a_normb_norms       r   r   r      sf     	!##A ##A!!$$F!!$$F8FF,,Q2233<<>>>r   c                d   t          |           } t          |          }| j        s|j        rIt          |           }t          |          }||z                      d                                          S t          t          |           t          |                                                    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])
    dim)r	   	is_sparser
   sumr   pairwise_dot_scorer   s       r   pairwise_cos_simr&   0   s     	1A1A 	{ _ak _%a((%a(($$$,,55777!"6q"9"9;OPQ;R;RSS\\^^^r   c                    t          |           } t          |          }t          j        | |                    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   s     r   	dot_scorer(   G   sJ     	!##A ##A8Aq{{1a(())22444r   c                    t          |           } t          |          }| |z                      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   s     r   r%   r%   X   sB     	1A1AE;;2;'')))r   c                   t          |           } t          |          }| j        s|j        rt                              d           t	          |           }t	          |          }t          ||d          }t          j        |                                           	                    | j
                                                  S t          j        | |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.	manhattan)metricg      ?p)r   r#   loggerwarning_oncer   r   r   
from_numpyfloattodevicer   cdist)r   r   a_coob_coodists        r   manhattan_simr9   i   s     	!##A ##A{ 	4ak 	4VWWWQQ!%{CCC&&,,..11!(;;DDFFF AqC(((113333r   c                    t          |           } t          |          }t          j        t          j        | |z
            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   s     r   pairwise_manhattan_simr<      sP     	1A1AIeiA&&B///88::::r   c                   t          |           } t          |          }| j        rt          j                            | | z  d                                                              d          }t          j                            ||z  d                                                              d          }t          j        | |                                                                          }|d|z  z
  |z   }t          j	        |d          }t          j
        |                                           S t          j        | |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-   )r   r#   r   sparser$   r   	unsqueezematmultclampsqrtr5   )r   r   	a_norm_sq	b_norm_sqdot_productsquared_dists         r   euclidean_simrJ      s!    	!##A ##A{ )L$$QU$22;;==GGJJ	L$$QU$22;;==GGJJ	l1accee,,5577 !1{?2Y> {<S999
<((113333AqC(((((r   c                    t          |           } t          |          }t          j        t          j        | |z
  dz  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   rE   r$   r   r   s     r   pairwise_euclidean_simrL      sT     	1A1AJuy!a%A266677@@BBBBr   xyc                $   | j         rft                              d           |                                                                 } |                                                                }t          |           } t          |          }t          j        | dd          \  }}t          j        |dd          \  }}t          j        |dz  |dz  z   dd          }||z  ||z  z   |z  }||z  ||z  z
  |z  }t          j        |dz  |dz  z   dd          dz  }	t          j        |dz  |dz  z   dd          dz  }
||	|
z  z  }||	|
z  z  }t          j        t          j	        ||fd          d          }t          j
        |          S )aV  
    Computes the absolute normalized angle distance. See :class:`~sentence_transformers.losses.AnglELoss`
    or https://huggingface.co/papers/2309.12871 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"   keepdimg      ?)r#   r/   r0   coalescer   r	   r   chunkr$   concatr;   )rM   rN   r   r   cdzreimdzdw
norm_angles               r   pairwise_angle_simr\      s    	{ $mnnnJJLL!!##JJLL!!##1A1A ;q!###DAq;q!###DAq	!Q$A+1d333A
a%!a%-1	B
a%!a%-1	B	1a4!Q$;At	4	4	4	;B	1a4!Q$;At	4	4	4	;B"r'MB"r'MB5<Ra888a@@@J9Z   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   )rM   r   rN   r   r   r   )
__future__r   numpynpr   sklearn.metricsr   r   transformers.utilsr   tensorr   r	   r
   r   
get_logger__name__r/   r   r   r&   r(   r%   r9   r<   rJ   rL   r\    r   r   <module>rf      st   " " " " " "      . . . . . .       & & & & & & d d d d d d d d d d d d 
	H	%	%   ? ? ? ?&_ _ _ _.5 5 5 5"* * * *"4 4 4 46; ; ; ;") ) ) )>C C C C"#! #! #! #! #! #!r   