
    Ch*                        S SK Jr  S SKJrJr  S SKrS SKrS SKJ	r	  S SKJ
r
Jr  SS jrSS jrSS jrSS	 jr\SS
 j5       r\SS j5       rSS jrSS jrSS jrSS jrg)    )annotations)AnyoverloadN)
coo_matrix)Tensordevicec           	        [        U [        5      (       a|  [        S U  5       5      (       aN  [        R                  " U  Vs/ sH-  oR                  5       R                  [        R                  S9PM/     sn5      $ [        R                  " U 5      n O+[        U [        5      (       d  [        R                  " U 5      n U R                  (       a  U R                  [        R                  S9$ U $ s  snf )z
Converts the input `a` to a PyTorch tensor if it is not already a tensor.
Handles lists of sparse tensors by stacking them.

Args:
    a (Union[list, np.ndarray, Tensor]): The input array or tensor.

Returns:
    Tensor: The converted tensor.
c              3  f   #    U H(  n[        U[        5      =(       a    UR                  v   M*     g 7fN)
isinstancer   	is_sparse).0xs     Y/var/www/html/shao/venv/lib/python3.13/site-packages/sentence_transformers/util/tensor.py	<genexpr>%_convert_to_tensor.<locals>.<genexpr>   s#     @az!V$44as   /1dtype)r   listalltorchstackcoalescetofloat32tensorr   r   )ar   s     r   _convert_to_tensorr      s     !T@a@@@;;aPa

emm DaPQQQA6""LLO{{tt%--t((H  Qs   3C-c                P    U R                  5       S:X  a  U R                  S5      n U $ )z
If the tensor `a` is 1-dimensional, it is unsqueezed to add a batch dimension.

Args:
    a (Tensor): The input tensor.

Returns:
    Tensor: The tensor with a batch dimension.
   r   )dim	unsqueezer   s    r   _convert_to_batchr$   $   s#     	uuw!|KKNH    c                f    [        U 5      n U R                  5       S:X  a  U R                  S5      n U $ )a  
Converts the input data to a tensor with a batch dimension.
Handles lists of sparse tensors by stacking them.

Args:
    a (Union[list, np.ndarray, Tensor]): The input data to be converted.

Returns:
    Tensor: The converted tensor with a batch dimension.
r    r   )r   r!   r"   r#   s    r   _convert_to_batch_tensorr'   3   s-     	1Auuw!|KKNHr%   c                D   U R                   (       d)  [        R                  R                  R	                  U SSS9$ U R                  5       n U R                  5       U R                  5       p![        R                  " U R                  S5      U R                  S9nUR                  SUS   US-  5        [        R                  " U5      R                  SUS   5      nUS:  nUR                  5       nXT==   X4   -  ss'   [        R                  " XU R                  5       5      $ )z
Normalizes the embeddings matrix, so that each sentence embedding has unit length.

Args:
    embeddings (Tensor): The input embeddings matrix.

Returns:
    Tensor: The normalized embeddings matrix.
   r    )pr!   r   r   )r   r   nn
functional	normalizer   indicesvalueszerossizer   
index_add_sqrtindex_selectclonesparse_coo_tensor)
embeddingsr/   r0   	row_normsmasknormalized_valuess         r   normalize_embeddingsr<   D   s     xx"",,Z1!,DD$$&J ((*J,=,=,?V JOOA.z7H7HIIGAJ	2

9%221gajAI q=Dy.""7z?PQQr%   c                    g r    r8   truncate_dims     r   truncate_embeddingsrA   a   s    Y\r%   c                    g r   r>   r?   s     r   rA   rA   e   s    ]`r%   c                    U SSU24   $ )a\  
Truncates the embeddings matrix.

Args:
    embeddings (Union[np.ndarray, torch.Tensor]): Embeddings to truncate.
    truncate_dim (Optional[int]): The dimension to truncate sentence embeddings to. `None` does no truncation.

Example:
    >>> from sentence_transformers import SentenceTransformer
    >>> from sentence_transformers.util import truncate_embeddings
    >>> model = SentenceTransformer("tomaarsen/mpnet-base-nli-matryoshka")
    >>> embeddings = model.encode(["It's so nice outside!", "Today is a beautiful day.", "He drove to work earlier"])
    >>> embeddings.shape
    (3, 768)
    >>> model.similarity(embeddings, embeddings)
    tensor([[1.0000, 0.8100, 0.1426],
            [0.8100, 1.0000, 0.2121],
            [0.1426, 0.2121, 1.0000]])
    >>> truncated_embeddings = truncate_embeddings(embeddings, 128)
    >>> truncated_embeddings.shape
    >>> model.similarity(truncated_embeddings, truncated_embeddings)
    tensor([[1.0000, 0.8092, 0.1987],
            [0.8092, 1.0000, 0.2716],
            [0.1987, 0.2716, 1.0000]])

Returns:
    Union[np.ndarray, torch.Tensor]: Truncated embeddings.
.Nr>   r?   s     r   rA   rA   i   s    : c=L=())r%   c                $   Uc  U $ [        U [        R                  5      (       a  [        R                  " U 5      n U R
                  u  p#U R                  n[        R                  " [        R                  " U 5      [        X5      SS9u  pV[        R                  " U [        R                  S9n[        R                  " X$S9R                  S5      R                  S[        X5      5      nSXxR                  5       UR                  5       4'   SX) '   U $ )a{  
Keeps only the top-k values (in absolute terms) for each embedding and creates a sparse tensor.

Args:
    embeddings (Union[np.ndarray, torch.Tensor]): Embeddings to sparsify by keeping only top_k values.
    max_active_dims (int): Number of values to keep as non-zeros per embedding.

Returns:
    torch.Tensor: A sparse tensor containing only the top-k values per embedding.
r    )kr!   r   r+   Tr   )r   npndarrayr   r   shaper   topkabsmin
zeros_likeboolaranger"   expandflatten)	r8   max_active_dims
batch_sizer!   r   _top_indicesr:   batch_indicess	            r   select_max_active_dimsrW      s     *bjj))\\*-
 &&OJF ZZ		* 5_9RXYZNA Jejj9DLL;EEaHOOPRTWXgTmnM;?D			 +"5"5"7	78 Jur%   c                t    U  H1  n[        X   [        5      (       d  M  X   R                  U5      X'   M3     U $ )aY  
Send a PyTorch batch (i.e., a dictionary of string keys to Tensors) to a device (e.g. "cpu", "cuda", "mps").

Args:
    batch (Dict[str, Tensor]): The batch to send to the device.
    target_device (torch.device): The target device (e.g. "cpu", "cuda", "mps").

Returns:
    Dict[str, Tensor]: The batch with tensors sent to the target device.
)r   r   r   )batchtarget_devicekeys      r   batch_to_devicer\      s6     ej&))}5EJ  Lr%   c                   U R                  5       n U R                  5       R                  5       R                  5       nU R	                  5       R                  5       R                  5       n[        X!S   US   44U R                  S9$ )Nr   r    )rI   )r   r/   cpunumpyr0   r   rI   )r   r/   r0   s      r   to_scipy_coor`      sd    	

Aiikoo%%'GXXZ^^##%Fv
GAJ78HHr%   )r   zlist | np.ndarray | Tensorreturnr   )r   r   ra   r   )r8   r   ra   r   )r8   
np.ndarrayr@   
int | Nonera   rb   )r8   torch.Tensorr@   rc   ra   rd   )r8   np.ndarray | torch.Tensorr@   rc   ra   re   )r8   re   rR   rc   ra   rd   )rY   dict[str, Any]rZ   r   ra   rf   )r   r   ra   r   )
__future__r   typingr   r   r_   rG   r   scipy.sparser   r   r   r   r$   r'   r<   rA   rW   r\   r`   r>   r%   r   <module>rj      sc    "     #  2"R: 
 \ 
 \ 
 ` 
 `*@D"Ir%   