o
    pi                     @   sL   d dl Z ddlmZ ddlmZ ddlmZ ddlm	Z	 G dd	 d	e	Z
dS )
    N   CosineSimilarity)common_functions)loss_and_miner_utils   )BaseMetricLossFunctionc                       s@   e Zd Zg dZd fdd	Zdd	 ZdddZdd Z  ZS )PNPLoss)DsDqIuIbOr   r   {Gz?r   c                    s\   t  jdi | t| t || _|| _|| _|| _| j| j	vr,t
d| d| j	 d S )Nzvariant=z but must be one of  )super__init__c_fassert_distance_typer   balphaannealvariantVARIANTS
ValueError)selfr   r   r   r   kwargs	__class__r   [/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_metric_learning/losses/pnp_loss.pyr      s   zPNPLoss.__init__c                 C   sB  t | t | t |||| |j|j}}|d}t|\}	}
}}t	j
||||d}t	j
||||d}d||	|
f< d||	|	f< d|||f< t	j|dd}|dk}t	|dkra|  S | |}|jdd|dd}|jddd|d}||ddd }| j|| jd| }t	j|dd}| jdkrt	d| }nK| jd	krdd| | j  }n<| jd
krd| t	d|  }n+| jdkr| j}d|d  || t	d||    }n| jdkrn	td| j dt	j|| dd| || d }t	|t	| }| jd	krd| }d|t	|d ddiS )Nr   )dtypedevicer   )dimr   )tempr
   r   r   r   r   z	variant <z> not available!lossalready_reduced)lossesindicesreduction_type)r   indices_tuple_not_supportedlabels_requiredref_not_supportedr    r!   sizelmuget_all_pairs_indicestorchzerossumzero_lossesdistance	unsqueezerepeatpermutesigmoidr   r   logr   r   	Exceptionreshapewhere)r   
embeddingslabelsindices_tupleref_emb
ref_labelsr    r!   Na1_idxp_idxa2_idxn_idxI_posI_negN_possafe_Nsim_allmasksim_all_repeatsim_diffsim_sg
sim_all_rkr   r%   r   r   r   compute_loss   sV   







(
$zPNPLoss.compute_loss      ?c                 C   s0   | | }t j|ddd}ddt |  }|S )ztemperature controlled sigmoid
        takes as input a torch tensor (tensor) and passes it through a sigmoid, controlled by temperature: temp
        i2   )minmaxrR   )r0   clampexp)r   tensorr#   exponentyr   r   r   r8   T   s   
zPNPLoss.sigmoidc                 C   s   t  S )Nr   )r   r   r   r   get_default_distance^   s   zPNPLoss.get_default_distance)r   r   r   r   )rR   )	__name__
__module____qualname__r   r   rQ   r8   r[   __classcell__r   r   r   r   r	   	   s    
:
r	   )r0   	distancesr   utilsr   r   r   r.   base_metric_loss_functionr   r	   r   r   r   r   <module>   s    