Ë
    Têñi 1  ã                  ó
  — 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!y)é    )Úannotations)ÚCallable)ÚEnumN)Úndarray)Úpairwise_distances)ÚTensor)Úloggingé   )Ú_convert_to_batch_tensorÚ_convert_to_tensorÚnormalize_embeddingsÚto_scipy_cooc                ó   — 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©ÚaÚbs     úg/var/www/pod-logistic/pod-ai/venv/lib/python3.12/site-packages/sentence_transformers/util/similarity.pyÚpytorch_cos_simr      s   € ô �1�a‹=Ðó    c                óÂ   — t        | «      } t        |«      }t        | «      }t        |«      }t        j                  ||j	                  dd«      «      j                  «       S )r   r   r
   )r   r   ÚtorchÚmmÚ	transposeÚto_dense©r   r   Úa_normÚb_norms       r   r   r   !   sS   € ô 	! Ó#€AÜ  Ó#€Aä! !Ó$€FÜ! !Ó$€FÜ�8‰8�F˜F×,Ñ,¨Q°Ó2Ó3×<Ñ<Ó>Ð>r   c                ó(  — t        | «      } t        |«      }| j                  s|j                  r9t        | «      }t        |«      }||z  j                  d¬«      j	                  «       S t        t        | «      t        |«      «      j	                  «       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ð 	‡{‚{�a—k’kÜ% aÓ(ˆÜ% aÓ(ˆØ˜‘×$Ñ$¨Ð$Ó,×5Ñ5Ó7Ð7ä!Ô"6°qÓ"9Ô;OÐPQÓ;RÓS×\Ñ\Ó^Ð^r   c                ó–   — t        | «      } t        |«      }t        j                  | |j                  dd«      «      j	                  «       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   s=   € ô 	! Ó#€AÜ  Ó#€Aä�8‰8�A�q—{‘{ 1 aÓ(Ó)×2Ñ2Ó4Ð4r   c                ót   — t        | «      } t        |«      }| |z  j                  d¬«      j                  «       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&   \   s6   € ô 	˜1Ó€AÜ˜1Ó€Aà�‰E�;‰;˜2ˆ;Ó×'Ñ'Ó)Ð)r   c                ó´  — t        | «      } t        |«      }| j                  s|j                  r„t        j                  d«       t	        | «      }t	        |«      }t        ||d¬«      }t        j                  | «      j                  «       j                  | j                  «      j                  «       S t        j                  | |d¬«      j                  «        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à‡{‚{�a—k’kÜ×ÑÐVÔWä˜Q“ˆÜ˜Q“ˆÜ! %¨°{ÔCˆÜ×Ñ  Ó&×,Ñ,Ó.×1Ñ1°!·(±(Ó;×DÑDÓFÐFô —‘˜A˜q CÔ(×1Ñ1Ó3Ð3Ð3r   c                ó¦   — t        | «      } t        |«      }t        j                  t        j                  | |z
  «      d¬«      j	                  «        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=   ˆ   sB   € ô 	˜1Ó€AÜ˜1Ó€Aä�I‰I”e—i‘i  A¡Ó&¨BÔ/×8Ñ8Ó:Ð:Ð:r   c                ól  — t        | «      } t        |«      }| j                  rút        j                  j	                  | | z  d¬«      j                  «       j                  d«      }t        j                  j	                  ||z  d¬«      j                  «       j                  d«      }t        j                  | |j                  «       «      j                  «       }|d|z  z
  |z   }t        j                  |d¬«      }t        j                  |«      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Ú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 a§c¡c£eÓ,×5Ñ5Ó7ˆð ! 1 {¡?Ñ2°YÑ>ˆô —{‘{ <°SÔ9ˆä—
‘
˜<Ó(×1Ñ1Ó3Ð3Ð3ä—‘˜A˜q CÔ(Ð(Ð(r   c                ó¬   — t        | «      } t        |«      }t        j                  t        j                  | |z
  dz  d¬«      «      j	                  «        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   rF   r%   r   r   s     r   Úpairwise_euclidean_simrM   ¸   sF   € ô 	˜1Ó€AÜ˜1Ó€Aä�J‰J”u—y‘y ! a¡%¨A¡°2Ô6Ó7×@Ñ@ÓBÐBÐBr   c                óâ  — | j                   rQt        j                  d«       | j                  «       j	                  «       } |j                  «       j	                  «       }t        | «      } t        |«      }| j                  d   dz  dk7  rZt        j                  j                  j                  | ddd¬«      } t        j                  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
   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Ü�;‰;�q˜! Ô#�D€A€qä�	‰	�!�Q‘$˜˜A™‘+ 1¨dÔ3€AØ
ˆa‰%�!�a‘%‰-˜1Ñ	€BØ
ˆa‰%�!�a‘%‰-˜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Ÿ<™<¨¨R¨°aÔ8¸aÔ@€JÜ�9‰9�ZÓ Ð r   c                  ój   — 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y	)Ú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,   c                ó(  — 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         j                  «       › 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: ú.)rf   ÚCOSINEr   ÚDOT_PRODUCTr)   Ú	MANHATTANr:   Ú	EUCLIDEANrK   Ú
ValueErrorÚpossible_values©Úsimilarity_functions    r   Úto_similarity_fnz#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                ó(  — 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         j                  «       › 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])
        rk   rl   rm   )rf   rn   r'   ro   r&   rp   r=   rq   rM   rr   rs   rt   s    r   Úto_similarity_pairwise_fnz,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                 óH   — t         D � cg c]  } | j                  ‘Œ c} S c c} w )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']
        )rf   rQ   )Úms    r   rs   z"SimilarityFunction.possible_valuesS  s   € ô "4Ö4˜A�—“Ò4Ð4ùÒ4s   ‰N)ru   zstr | SimilarityFunctionÚreturnz6Callable[[Tensor | ndarray, Tensor | ndarray], Tensor])r{   z	list[str])Ú__name__Ú
__module__Ú__qualname__Ú__doc__rn   ro   ÚDOTrq   rp   Ústaticmethodrv   rx   rs   © 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   