
    #i1                    
   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     v/var/www/vps2.regionflexible.com/Desarrollo/venv/lib/python3.12/site-packages/sentence_transformers/util/similarity.pypytorch_cos_simr      s     1a=    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88FF,,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 	{{akk%a(%a($$$,5577!"6q"9;OPQ;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88Aq{{1a()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                  rt        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{{akkVWQQ!%{C&,,.11!((;DDFF AqC(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IIeiiA&B/88:::r   c                l   t        |       } t        |      }| j                  rt        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{{LL$$QU$2;;=GGJ	LL$$QU$2;;=GGJ	ll1acce,557 !1{?2Y> {{<S9

<(11333AqC(((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JJuyy!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JJL!!#JJL!!#1A1A 	wwqzA~HH##AvJa#HHH##AvJa#H ;;q!#DAq;;q!#DAq		!Q$A+1d3A
a%!a%-1	B
a%!a%-1	B	1a4!Q$;At	4	;B	1a4!Q$;At	4	;B"r'MB"r'MB5<<Ra8a@J99Z  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    . 11DE"4";";;N"4"@"@@"4">">>  "4">">>  $%8$99m  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 11DE"4";";;##"4"@"@@%%"4">">>))"4">">>))$%8$99m  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4A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"*"46;")>C"(!Vl5 l5r   