
    $j1                       d dl mZ d dlmZ 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 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  G d de          Z!dS )!    )annotations)Callable)EnumN)ndarray)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     m/home/rurouni/.hermes/hermes-agent/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)   4   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+   K   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(   \   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_simr<   m   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       @r0   )r   r&   r   sparser'   r   	unsqueezematmultclampsqrtr8   )r   r   	a_norm_sq	b_norm_sqdot_productsquared_dists         r   euclidean_simrM      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])
    rA   r#   r$   )r   r   rH   r'   r   r   s     r   pairwise_euclidean_simrO      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          |          }| j        d         dz  dk    rPt          j        j	        
                    | ddd          } t          j        j	        
                    |ddd          }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 )ak  
    Computes the absolute normalized angle distance. See :class:`~sentence_transformers.sentence_transformer.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
   rA   r   )r   r
   constant)modevaluer$   T)r%   keepdimg      ?)r&   r2   r3   coalescer   r   shaper   nn
functionalpadchunkr'   concatr>   )rP   rQ   r   r   cdzreimdzdw
norm_angles               r   pairwise_angle_simrf      s    	{ $mnnnJJLL!!##JJLL!!##1A1A 	wqzA~H##AvJa#HHH##AvJa#HH ;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   c                  n    e Zd ZdZdZdZdZdZdZe	dd
            Z
e	dd            Ze	dd            ZdS )SimilarityFunctiona  
    Enum class for supported similarity functions. The following functions are supported:

    - ``SimilarityFunction.COSINE`` (``"cosine"``): Cosine similarity
    - ``SimilarityFunction.DOT_PRODUCT`` (``"dot"``, ``dot_product``): Dot product similarity
    - ``SimilarityFunction.EUCLIDEAN`` (``"euclidean"``): Euclidean distance
    - ``SimilarityFunction.MANHATTAN`` (``"manhattan"``): Manhattan distance
    cosinedot	euclideanr.   similarity_functionstr | SimilarityFunctionr   6Callable[[Tensor | ndarray, Tensor | ndarray], Tensor]c                2   t          |           } | t           j        k    rt          S | t           j        k    rt          S | t           j        k    rt          S | t           j        k    rt          S t          d|  dt           
                                 d          )a  
        Converts a similarity function name or enum value to the corresponding similarity function.

        Args:
            similarity_function (Union[str, SimilarityFunction]): The name or enum value of the similarity function.

        Returns:
            Callable[[Union[Tensor, ndarray], Union[Tensor, ndarray]], Tensor]: The corresponding similarity function.

        Raises:
            ValueError: If the provided function is not supported.

        Example:
            >>> similarity_fn = SimilarityFunction.to_similarity_fn("cosine")
            >>> similarity_scores = similarity_fn(embeddings1, embeddings2)
            >>> similarity_scores
            tensor([[0.3952, 0.0554],
                    [0.0992, 0.1570]])
        The provided function 4 is not supported. Use one of the supported values: .)rh   COSINEr   DOT_PRODUCTr+   	MANHATTANr<   	EUCLIDEANrM   
ValueErrorpossible_valuesrl   s    r   to_similarity_fnz#SimilarityFunction.to_similarity_fn  s    . 11DEE"4";;;N"4"@@@"4">>>  "4">>>   V%8  V  V  oA  oQ  oQ  oS  oS  V  V  V
 
 	
r   c                2   t          |           } | t           j        k    rt          S | t           j        k    rt          S | t           j        k    rt          S | t           j        k    rt          S t          d|  dt           
                                 d          )a  
        Converts a similarity function into a pairwise similarity function.

        The pairwise similarity function returns the diagonal vector from the similarity matrix, i.e. it only
        computes the similarity(a[i], b[i]) for each i in the range of the input tensors, rather than
        computing the similarity between all pairs of a and b.

        Args:
            similarity_function (Union[str, SimilarityFunction]): The name or enum value of the similarity function.

        Returns:
            Callable[[Union[Tensor, ndarray], Union[Tensor, ndarray]], Tensor]: The pairwise similarity function.

        Raises:
            ValueError: If the provided similarity function is not supported.

        Example:
            >>> pairwise_fn = SimilarityFunction.to_similarity_pairwise_fn("cosine")
            >>> similarity_scores = pairwise_fn(embeddings1, embeddings2)
            >>> similarity_scores
            tensor([0.3952, 0.1570])
        rp   rq   rr   )rh   rs   r)   rt   r(   ru   r?   rv   rO   rw   rx   ry   s    r   to_similarity_pairwise_fnz,SimilarityFunction.to_similarity_pairwise_fn*  s    4 11DEE"4";;;##"4"@@@%%"4">>>))"4">>>)) V%8  V  V  oA  oQ  oQ  oS  oS  V  V  V
 
 	
r   	list[str]c                 $    d t           D             S )ad  
        Returns a list of possible values for the SimilarityFunction enum.

        Returns:
            list: A list of possible values for the SimilarityFunction enum.

        Example:
            >>> possible_values = SimilarityFunction.possible_values()
            >>> possible_values
            ['cosine', 'dot', 'euclidean', 'manhattan']
        c                    g | ]	}|j         
S  )rU   ).0ms     r   
<listcomp>z6SimilarityFunction.possible_values.<locals>.<listcomp>`  s    444A444r   )rh   r   r   r   rx   z"SimilarityFunction.possible_valuesS  s     54!34444r   N)rl   rm   r   rn   )r   r}   )__name__
__module____qualname____doc__rs   rt   DOTrv   ru   staticmethodrz   r|   rx   r   r   r   rh   rh      s          FK
CII#
 #
 #
 \#
J &
 &
 &
 \&
P 5 5 5 \5 5 5r   rh   )r   r   r   r   r   r   )r   r   r   r   r   r   )rP   r   rQ   r   r   r   )"
__future__r   collections.abcr   enumr   numpynpr   r   sklearn.metricsr   r   transformers.utilsr	   tensorr   r   r   r   
get_loggerr   r2   r   r   r)   r+   r(   r<   r?   rM   rO   rf   rh   r   r   r   <module>r      s   " " " " " " $ $ $ $ $ $                  . . . . . .       & & & & & & 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"(! (! (! (!Vl5 l5 l5 l5 l5 l5 l5 l5 l5 l5r   