o
    piq                     @   s\   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e j
fd	d
ZG dd de	ZdS )    N   CosineSimilarity)common_functions)loss_and_miner_utils   )BaseMetricLossFunctiontensorsc                  G   s2   t | }t j|dd\}}t j|dd}| S )Nr   dimr   )torchstacksortuniquetolist)r	   t_ r   a/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_metric_learning/losses/histogram_loss.pyfilter_pairs	   s   
r   c                       s@   e Zd Zddedef fddZdd Zdd	 Zd
d Z  Z	S )HistogramLossNn_binsdeltac                    s~   t  jdi | |d ur!|d ur!|d| ks!J d| d| |d u r+|d u r+d}|d ur1|nd| | _| jddd d S )	Nr   zUdelta and n_bins must satisfy the equation delta = 2/n_bins.
Passed values are delta=z and n_bins=d   r   F)nameis_statr   )super__init__r   add_to_recordable_attributes)selfr   r   kwargs	__class__r   r   r      s   zHistogramLoss.__init__c                 C   s   t || t |||| tj|||dd}|\}}}t|dkr&|  S | ||}	t||}
t||}|	|
 }|	| }| 	|}t
j|dd}| 	|}dt
|| d ddiS )Nall)t_per_anchorr   r
   lossalready_reduced)lossesindicesreduction_type)c_f labels_or_indices_tuple_requiredref_not_supportedlmuconvert_to_tripletslenzero_lossesdistancer   compute_densityr   cumsumsum)r   
embeddingslabelsindices_tupleref_emb
ref_labels
anchor_idxpositive_idxnegative_idxmatanchor_positive_idxanchor_negative_idxap_distsan_distsp_posphip_negr   r   r   compute_loss   s,   




zHistogramLoss.compute_lossc                 C   s   | d}t| d | j }tj||tjd}|d || j  | j }|d | j d | | j }tj||d}tj||d}t	t
dd| j  }tj|||jd}|d|d | |d|| || S )Nr   r   )tensordtype)rF   r   )sizer   floorfloatr   r*   	to_devicelongto_dtypezerosroundrG   scatter_add_)r   	distancesrH   r_stardelta_ijr_adelta_ijr_bdensityr   r   r   r2   :   s   
zHistogramLoss.compute_densityc                 C   s   t  S )Nr   )r   r   r   r   get_default_distanceO   s   z"HistogramLoss.get_default_distance)NN)
__name__
__module____qualname__intrJ   r   rE   r2   rV   __classcell__r   r   r!   r   r      s
    r   )r   rQ   r   utilsr   r*   r   r-   base_metric_loss_functionr   Tensorr   r   r   r   r   r   <module>   s    