ó
    >:j 1  ã                  ó  • S SK Jr  S SKJr  S SKJr  S SKrS SKrS SKJ	r	  S SK
Jr  S SKJr  S SKJr  S	S
KJrJrJrJr  \R(                  " \5      rSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jr  " S S\5      r!g)é    )Úannotations)ÚCallable)ÚEnumN)Úndarray)Úpairwise_distances)ÚTensor)Úloggingé   )Ú_convert_to_batch_tensorÚ_convert_to_tensorÚnormalize_embeddingsÚto_scipy_cooc                ó   • [        X5      $ )úõ
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©ÚaÚbs     Úb/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sentence_transformers/util/similarity.pyÚpytorch_cos_simr      s   € ô �1‹=Ðó    c                óÂ   • [        U 5      n [        U5      n[        U 5      n[        U5      n[        R                  " X#R	                  SS5      5      R                  5       $ )r   r   r
   )r   r   ÚtorchÚmmÚ	transposeÚto_dense©r   r   Úa_normÚb_norms       r   r   r   !   sQ   € ô 	! Ó#€AÜ  Ó#€Aä! !Ó$€FÜ! !Ó$€FÜ�8Š8�F×,Ñ,¨Q°Ó2Ó3×<Ñ<Ó>Ð>r   c                ó4  • [        U 5      n [        U5      nU R                  (       d  UR                  (       a5  [        U 5      n[        U5      nX#-  R                  SS9R	                  5       $ [        [        U 5      [        U5      5      R	                  5       $ )zû
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ð 	‡{‡{�a—k—kÜ% aÓ(ˆÜ% aÓ(ˆØ‘×$Ñ$¨Ð$Ð,×5Ñ5Ó7Ð7ä!Ô"6°qÓ"9Ô;OÐPQÓ;RÓS×\Ñ\Ó^Ð^r   c                ó–   • [        U 5      n [        U5      n[        R                  " XR                  SS5      5      R	                  5       $ )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   s;   € ô 	! Ó#€AÜ  Ó#€Aä�8Š8�A—{‘{ 1 aÓ(Ó)×2Ñ2Ó4Ð4r   c                ól   • [        U 5      n [        U5      nX-  R                  SS9R                  5       $ )z÷
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&   \   s4   € ô 	˜1Ó€AÜ˜1Ó€Aà‰E�;‰;˜2ˆ;Ð×'Ñ'Ó)Ð)r   c                ó¼  • [        U 5      n [        U5      nU R                  (       d  UR                  (       a�  [        R                  S5        [	        U 5      n[	        U5      n[        X#SS9n[        R                  " U* 5      R                  5       R                  U R                  5      R                  5       $ [        R                  " XSS9R                  5       * $ )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à‡{‡{�a—k—kÜ×ÑÐVÔWä˜Q“ˆÜ˜Q“ˆÜ! %°{ÑCˆÜ×Ò  Ó&×,Ñ,Ó.×1Ñ1°!·(±(Ó;×DÑDÓFÐFô —’˜A CÑ(×1Ñ1Ó3Ð3Ð3r   c                ó¢   • [        U 5      n [        U5      n[        R                  " [        R                  " X-
  5      SS9R	                  5       * $ )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=   ˆ   s@   € ô 	˜1Ó€AÜ˜1Ó€Aä�IŠI”e—i’i ¡Ó&¨BÑ/×8Ñ8Ó:Ð:Ð:r   c                ó^  • [        U 5      n [        U5      nU R                  (       añ  [        R                  R	                  X -  SS9R                  5       R                  S5      n[        R                  R	                  X-  SS9R                  5       R                  S5      n[        R                  " XR                  5       5      R                  5       nUSU-  -
  U-   n[        R                  " USS9n[        R                  " U5      R                  5       * $ [        R                  " XSS9* $ )	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Úsqrtr6   )r   r   Ú	a_norm_sqÚ	b_norm_sqÚdot_productÚsquared_dists         r   Úeuclidean_simrK   ™   sð   € ô 	! Ó#€AÜ  Ó#€Aà‡{‡{Ü—L‘L×$Ñ$ Q¡U°Ð$Ð2×;Ñ;Ó=×GÑGÈÓJˆ	Ü—L‘L×$Ñ$ Q¡U°Ð$Ð2×;Ñ;Ó=×GÑGÈÓJˆ	Ü—l’l 1§c¡c£eÓ,×5Ñ5Ó7ˆð ! 1 {¡?Ñ2°YÑ>ˆô —{’{ <°SÑ9ˆä—
’
˜<Ó(×1Ñ1Ó3Ð3Ð3ä—’˜A CÑ(Ð(Ð(r   c                ó¨   • [        U 5      n [        U5      n[        R                  " [        R                  " X-
  S-  SS95      R	                  5       * $ )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   rF   r%   r   r   s     r   Úpairwise_euclidean_simrM   ¸   sD   € ô 	˜1Ó€AÜ˜1Ó€Aä�JŠJ”u—y’y !¡%¨A¡°2Ñ6Ó7×@Ñ@ÓBÐBÐBr   c                ó¶  • U R                   (       aQ  [        R                  S5        U R                  5       R	                  5       n UR                  5       R	                  5       n[        U 5      n [        U5      nU R                  S   S-  S:w  aT  [        R                  R                  R                  U SSSS9n [        R                  R                  R                  USSSS9n[        R                  " U SSS9u  p#[        R                  " USSS9u  pE[        R                  " US-  US-  -   SS	S
9nX$-  X5-  -   U-  nX4-  X%-  -
  U-  n[        R                  " US-  US-  -   SS	S
9S-  n	[        R                  " US-  US-  -   SS	S
9S-  n
XyU
-  -  nX‰U
-  -  n[        R                  " [        R                  " Xx4SS9SS9n[        R                  " U5      $ )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
   r?   r   )r   r
   Úconstant)ÚmodeÚvaluer"   T)r#   Úkeepdimg      à?)r$   r0   r1   Úcoalescer   r   Úshaper   ÚnnÚ
functionalÚpadÚchunkr%   Úconcatr<   )ÚxÚyr   r   ÚcÚdÚzÚreÚimÚdzÚdwÚ
norm_angles               r   Úpairwise_angle_simrd   É   s¦  € ð 	‡{‡{Ü×ÑÐmÔnØ�J‰J‹L×!Ñ!Ó#ˆØ�J‰J‹L×!Ñ!Ó#ˆä˜1Ó€AÜ˜1Ó€Að 	‡w�wˆq�z�A�~˜ÓÜ�H‰H×Ñ×#Ñ# A v°JÀaÐ#ÐHˆÜ�H‰H×Ñ×#Ñ# A v°JÀaÐ#ÐHˆô �;Š;�q˜! Ñ#�D€AÜ�;Š;�q˜! Ñ#�D€Aä�	Š	�!�Q‘$˜˜A™‘+ 1¨dÑ3€AØ
‰%�!‘%‰-˜1Ñ	€BØ
‰%�!‘%‰-˜1Ñ	€Bä	�Š�1�a‘4˜!˜Q™$‘; A¨tÑ	4¸Ñ	;€BÜ	�Š�1�a‘4˜!˜Q™$‘; A¨tÑ	4¸Ñ	;€BØˆr‰'�M€BØˆr‰'�M€Bä—’œ5Ÿ<š<¨¨°aÑ8¸aÑ@€JÜ�9Š9�ZÓ Ð r   c                  óx   • \ rS rSrSrSrSrSrSrSr	\
    SS j5       r\
    SS j5       r\
SS	 j5       rS
rg)ÚSimilarityFunctionéô   a†  
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,   c                ó0  • [        U 5      n U [         R                  :X  a  [        $ U [         R                  :X  a  [        $ U [         R
                  :X  a  [        $ U [         R                  :X  a  [        $ [        SU  S[         R                  5        S35      e)ay  
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: Ú.)rf   ÚCOSINEr   ÚDOT_PRODUCTr)   Ú	MANHATTANr:   Ú	EUCLIDEANrK   Ú
ValueErrorÚpossible_values©Úsimilarity_functions    r   Úto_similarity_fnÚ#SimilarityFunction.to_similarity_fn  s¬   € ô. 1Ð1DÓEÐàÔ"4×";Ñ";Ó;ÜˆNØÔ"4×"@Ñ"@Ó@ÜÐØÔ"4×">Ñ">Ó>Ü Ð ØÔ"4×">Ñ">Ó>Ü Ð äØ$Ð%8Ð$9Ð9mô  oA÷  oQñ  oQó  oSð  nTð  TUð  Vó
ð 	
r   c                ó0  • [        U 5      n U [         R                  :X  a  [        $ U [         R                  :X  a  [        $ U [         R
                  :X  a  [        $ U [         R                  :X  a  [        $ [        SU  S[         R                  5        S35      e)aH  
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])
rl   rm   rn   )rf   ro   r'   rp   r&   rq   r=   rr   rM   rs   rt   ru   s    r   Úto_similarity_pairwise_fnÚ,SimilarityFunction.to_similarity_pairwise_fn*  s­   € ô4 1Ð1DÓEÐàÔ"4×";Ñ";Ó;Ü#Ð#ØÔ"4×"@Ñ"@Ó@Ü%Ð%ØÔ"4×">Ñ">Ó>Ü)Ð)ØÔ"4×">Ñ">Ó>Ü)Ð)äØ$Ð%8Ð$9Ð9mô  oA÷  oQñ  oQó  oSð  nTð  TUð  Vó
ð 	
r   c                 óL   • [          V s/ s H  o R                  PM     sn $ s  sn f )a$  
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']
)rf   rQ   )Úms    r   rt   Ú"SimilarityFunction.possible_valuesS  s    € õ "4Ó4Ò!3˜A—”Ñ!3Ñ4Ð4ùÒ4s   ‰!© N)rv   zstr | SimilarityFunctionÚreturnz6Callable[[Tensor | ndarray, Tensor | ndarray], Tensor])r€   z	list[str])Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ro   rp   ÚDOTrr   rq   Ústaticmethodrw   rz   rt   Ú__static_attributes__r   r   r   rf   rf   ô   s~   † ñð €FØ€KØ
€CØ€IØ€Iàð#
Ø5ð#
à	?ó#
ó ð#
ðJ ð&
Ø5ð&
à	?ó&
ó ð&
ðP ó5ó ó5r   rf   )r   r   r   r   r€   r   )r   úlist | np.ndarray | Tensorr   r‰   r€   r   )rZ   r   r[   r   r€   r   )"Ú
__future__r   Úcollections.abcr   Úenumr   ÚnumpyÚnpr   r   Úsklearn.metricsr   r   Útransformers.utilsr	   Útensorr   r   r   r   Ú
get_loggerr�   r0   r   r   r'   r)   r&   r:   r=   rK   rM   rd   rf   r   r   r   Ú<module>r“      s{   ðÝ "å $Ý ã Û Ý Ý .Ý Ý &ç dÓ dð 
×	Ò	˜HÓ	%€ôô?ô&_ô.5ô"*ô"4ô6;ô")ô>Cô"(!ôVl5˜õ l5r   