§
    ™ŠtjÊ5  ã                  ó  — 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 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Úreturnútuple[Tensor, Tensor]c                óš   — | j         r|j         s| |                     ¦   «         fS |j         r| j         s|                      ¦   «         |fS | |fS )aW  
    Converts the dense tensor to sparse COO if exactly one of the two inputs is sparse, so that mixed inputs can
    reuse the all-sparse computations. The lone dense operand in such a mix typically still holds mostly zeros
    (e.g. sparse embeddings encoded with ``convert_to_sparse_tensor=False``), making the conversion cheap, whereas
    densifying the sparse operand would allocate a second full-size dense tensor.

    Args:
        a (Tensor): The first tensor.
        b (Tensor): The second tensor.

    Returns:
        tuple[Tensor, Tensor]: The two tensors, using the same layout.
    )Ú	is_sparseÚ	to_sparse©r   r   s     úc/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sentence_transformers/util/similarity.pyÚ_match_layoutsr      sY   € ð 	„{ð  ˜1œ;ð  Ø�!—+’+‘-”-ÐÐØ„{ð  ˜1œ;ð  Ø�{Š{‰}Œ}˜aÐÐØˆaˆ4€Kó    c                ó"   — 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_simr   s     r   Úpytorch_cos_simr   (   s   € õ �1�a‰=Œ=Ðr   ú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   6   sf   € õ 	! Ñ#Ô#€AÝ  Ñ#Ô#€Aå! !Ñ$Ô$€FÝ! !Ñ$Ô$€FÝŒ8�F˜F×,Ò,¨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   r   r   Úsumr#   Úpairwise_dot_scorer$   s       r   Úpairwise_cos_simr-   I   s¥   € õ 	˜1ÑÔ€AÝ˜1ÑÔ€Að 	„{ð _�a”kð _Ý% aÑ(Ô(ˆÝ% aÑ(Ô(ˆØ˜‘×$Ò$¨Ð$Ñ,Ô,×5Ò5Ñ7Ô7Ð7å!Õ"6°qÑ"9Ô"9Õ;OÐPQÑ;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/   `   sJ   € õ 	! Ñ#Ô#€AÝ  Ñ#Ô#€AåŒ8�A�q—{’{ 1 aÑ(Ô(Ñ)Ô)×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,   q   sB   € õ 	˜1ÑÔ€AÝ˜1ÑÔ€Aà�‰E�;Š;˜2ˆ;ÑÔ×'Ò'Ñ)Ô)Ð)r   c                ó
  — t          | ¦  «        } t          |¦  «        }| j        s|j        r®t                               d¦  «         t	          | |¦  «        \  } }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   r    Ú
from_numpyÚfloatÚtoÚdevicer#   Úcdist)r   r   Úa_cooÚb_cooÚdists        r   Úmanhattan_simr@   ‚   sæ   € õ 	! Ñ#Ô#€AÝ  Ñ#Ô#€Aà„{ð 
4�a”kð 
4Ý×ÒÐVÑWÔWÐWå˜a Ñ#Ô#‰ˆˆ1Ý˜Q‘”ˆÝ˜Q‘”ˆÝ! %¨°{ÐCÑCÔCˆÝÔ  Ñ&Ô&×,Ò,Ñ.Ô.×1Ò1°!´(Ñ;Ô;×DÒDÑFÔFÐFõ ”˜A˜q CÐ(Ñ(Ô(×1Ò1Ñ3Ô3Ð3Ð3r   c                óà   — t          | ¦  «        } 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    r+   Úabsr#   r   s     r   Úpairwise_manhattan_simrC   ž   sc   € õ 	˜1ÑÔ€AÝ˜1ÑÔ€AÝ˜!˜QÑÔ�D€A€qåŒI•e”i  A¡Ñ&Ô&¨BÐ/Ñ/Ô/×8Ò8Ñ:Ô:Ð:Ð:r   c                óØ  — t          | ¦  «        } t          |¦  «        }| j        s|j        �r&t          | |¦  «        \  } }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       @r4   )r   r   r   r    Úsparser+   r#   Ú	unsqueezeÚmatmulÚtÚclampÚsqrtr<   )r   r   Ú	a_norm_sqÚ	b_norm_sqÚdot_productÚsquared_dists         r   Úeuclidean_simrQ   °   s=  € õ 	! Ñ#Ô#€AÝ  Ñ#Ô#€Aà„{ð )�a”kñ )Ý˜a Ñ#Ô#‰ˆˆ1Ý”L×$Ò$ Q¨¡U°Ð$Ñ2Ô2×;Ò;Ñ=Ô=×GÒGÈÑJÔJˆ	Ý”L×$Ò$ Q¨¡U°Ð$Ñ2Ô2×;Ò;Ñ=Ô=×GÒGÈÑJÔJˆ	Ý”l 1 a§c¢c¡e¤eÑ,Ô,×5Ò5Ñ7Ô7ˆð ! 1 {¡?Ñ2°YÑ>ˆõ ”{ <°SÐ9Ñ9Ô9ˆå”
˜<Ñ(Ô(×1Ò1Ñ3Ô3Ð3Ð3å”˜A˜q CÐ(Ñ(Ô(Ð(Ð(r   c                óæ   — t          | ¦  «        } 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])
    rE   r(   r)   )r   r   r    rL   r+   r#   r   s     r   Úpairwise_euclidean_simrS   Ð   sg   € õ 	˜1ÑÔ€AÝ˜1ÑÔ€AÝ˜!˜QÑÔ�D€A€qåŒJ•u”y ! a¡%¨A¡°2Ð6Ñ6Ô6Ñ7Ô7×@Ò@ÑBÔBÐBÐBr   ÚxÚyc                óÎ  — | j         s|j         rPt                               d¦  «         | j         r|                      ¦   «         } |j         r|                     ¦   «         }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
   rE   r   )r   r
   Úconstant)ÚmodeÚvaluer)   T)r*   Úkeepdimg      à?)r   r6   r7   r#   r   Úshaper    ÚnnÚ
functionalÚpadÚchunkr+   ÚconcatrB   )rT   rU   r   r   ÚcÚdÚzÚreÚimÚdzÚdwÚ
norm_angles               r   Úpairwise_angle_simri   â   sð  € ð 	„{ð �a”kð Ý×ÒÐmÑnÔnÐnØŒ;ð 	Ø—
’
‘”ˆAØŒ;ð 	Ø—
’
‘”ˆAå˜1ÑÔ€AÝ˜1ÑÔ€Að 	„wˆq„z�A�~˜ÒÐÝŒHÔ×#Ò# A v°JÀaÐ#ÑHÔHˆÝŒHÔ×#Ò# A v°JÀaÐ#ÑHÔHˆõ Œ;�q˜! Ð#Ñ#Ô#�D€A€qÝŒ;�q˜! Ð#Ñ#Ô#�D€A€qåŒ	�!�Q‘$˜˜A™‘+ 1¨dÐ3Ñ3Ô3€AØ
ˆa‰%�!�a‘%‰-˜1Ñ	€BØ
ˆa‰%�!�a‘%‰-˜1Ñ	€Bå	Œ�1�a‘4˜!˜Q™$‘; A¨tÐ	4Ñ	4Ô	4¸Ñ	;€BÝ	Œ�1�a‘4˜!˜Q™$‘; A¨tÐ	4Ñ	4Ô	4¸Ñ	;€BØˆ"ˆr‰'�M€BØˆ"ˆr‰'�M€Bå”�5œ<¨¨R¨°aÐ8Ñ8Ô8¸aÐ@Ñ@Ô@€JÝŒ9�ZÑ Ô Ð 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Ú	euclideanr2   Ú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: ú.)rk   ÚCOSINEr   ÚDOT_PRODUCTr/   Ú	MANHATTANr@   Ú	EUCLIDEANrQ   Ú
ValueErrorÚpossible_values©ro   s    r   Úto_similarity_fnz#SimilarityFunction.to_similarity_fn  sÂ   € õ. 1Ð1DÑ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])
        rs   rt   ru   )rk   rv   r-   rw   r,   rx   rC   ry   rS   rz   r{   r|   s    r   Úto_similarity_pairwise_fnz,SimilarityFunction.to_similarity_pairwise_fnE  sÃ   € õ4 1Ð1DÑ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 © )rY   )Ú.0Úms     r   ú
<listcomp>z6SimilarityFunction.possible_values.<locals>.<listcomp>{  s   € Ð4Ð4Ð4˜A�”Ð4Ð4Ð4r   )rk   rƒ   r   r   r{   z"SimilarityFunction.possible_valuesn  s   € ð 5Ð4Õ!3Ð4Ñ4Ô4Ð4r   N)ro   rp   r   rq   )r   r€   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rv   rw   ÚDOTry   rx   Ústaticmethodr}   r   r{   rƒ   r   r   rk   rk     s™   € € € € € ðð ð €FØ€KØ
€CØ€IØ€Iàð#
ð #
ð #
ñ „\ð#
ðJ ð&
ð &
ð &
ñ „\ð&
ðP ð5ð 5ð 5ñ „\ð5ð 5ð 5r   rk   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )rT   r   rU   r   r   r   )#Ú
__future__r   Úcollections.abcr   Úenumr   ÚnumpyÚnpr    r   Úsklearn.metricsr   r   Útransformers.utilsr	   Útensorr   r   r   r   Ú
get_loggerr‡   r6   r   r   r   r-   r/   r,   r@   rC   rQ   rS   ri   rk   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ð 4ð8;ð ;ð ;ð ;ð$)ð )ð )ð )ð@Cð Cð Cð Cð$*!ð *!ð *!ð *!ðZl5ð l5ð l5ð l5ð l5˜ñ l5ô l5ð l5ð l5ð l5r   