o
    pi                     @   sj   d dl Zd dlZd dlZdejfddZdddZd	d
 ZdddZ	dd Z
dddZdd Zdd ZdS )    NXc                 C   s0   t t j| d dd}d||dk< | j| jS )zL2 normalize vectors

    Parameters
    ----------
    X : `np.ndarray`
        (n_samples, n_dimensions) vectors.

    Returns
    -------
    normalized : `np.ndarray`
        (n_samples, n_dimensions) L2-normalized vectors

          )axis      ?r   )npsqrtsumT)r   norm r   P/home/ubuntu/.local/lib/python3.10/site-packages/pyannote/core/utils/distance.pyl2_normalize"   s   r   	euclideanFc                 C   sf   | dkr|rdS dt jfS | dkr|rdS dt jfS | dkr dS | dkr)dt jfS d|  d	}t|)
ab  Return range of possible distance between two vectors

    Parameters
    ----------
    metric : `str`, optional
        Metric. Defaults to 'euclidean'
    normalize : `bool`, optional
        Set to True if vectors are L2-normalized. Defaults to False.

    Returns
    -------
    min_dist, max_dist : `float`
        Range of possible distance.
    r   )        g       @r   sqeuclidean)r   g      @cosineangularzdist_range does not support z metric.)r   infpiNotImplementedError)metric	normalizemsgr   r   r   
dist_range6   s   


r   c                 C   s^   | j \}|dk rtg S g }t|d D ]}|| | | |d d }|| qt|S )zHelper function for pdistr   r   N)shaper   arrayrangeappendhstack)r   funcn_items	distancesidistancer   r   r   _pdist_func_1DZ   s   

r%   c                 K   s  |dkrt jjj| fddi|}ttd| ddS |dkr5| jdks.J d| d	t| d
d S |dkrL| jdksFJ d| d	t| tj	S |dkrc| jdks]J d| d	t| tj
S |dkr{| jdkstJ d| d	t| dd S t jjj| fd|i|S )ar  Same as scipy.spatial.distance with support for additional metrics

    * 'angular': pairwise angular distance
    * 'equal':   pairwise equality check (only for 1-dimensional fX)
    * 'minimum': pairwise minimum (only for 1-dimensional fX)
    * 'maximum': pairwise maximum (only for 1-dimensional fX)
    * 'average': pairwise average (only for 1-dimensional fX)
    r   r   r   r         equalr   'z(' metric only supports 1-dimensional fX.c                 S      | |kS Nr   xr   r   r   r   <lambda>{       zpdist.<locals>.<lambda>minimummaximumaveragec                 S      d| |  S N      ?r   r+   r   r   r   r-          )scipyspatialr$   pdistr   arccosclipndimr%   r/   r0   )fXr   kwargsr   r   r   r   r8   k   s    
r8   c                    s   t  fddt| D S )zHelper function for cdistc                 3   s    | ]}| V  qd S r*   r   ).0x_trnX_tstr    r   r   	<genexpr>   s    z!_cdist_func_1D.<locals>.<genexpr>)r   vstackiter)X_trnrA   r    r   r@   r   _cdist_func_1D   s   rF   c                 K   sD  |dkrt jjj| |fddi|}ttd| ddS |dkr<| jdkr,|jdks4J d| d	t| |d
d S |dkrY| jdkrJ|jdksRJ d| d	t| |tj	S |dkrv| jdkrg|jdksoJ d| d	t| |tj
S |dkr| jdkr|jdksJ d| d	t| |dd S t jjj| |fd|i|S )ax  Same as scipy.spatial.distance.cdist with support for additional metrics

    * 'angular': pairwise angular distance
    * 'equal':   pairwise equality check (only for 1-dimensional fX)
    * 'minimum': pairwise minimum (only for 1-dimensional fX)
    * 'maximum': pairwise maximum (only for 1-dimensional fX)
    * 'average': pairwise average (only for 1-dimensional fX)
    r   r   r   r   r&   r'   r   r(   z7' metric only supports 1-dimensional fX_trn and fX_tst.c                 S   r)   r*   r   r?   rA   r   r   r   r-      r.   zcdist.<locals>.<lambda>r/   r0   r1   c                 S   r2   r3   r   rG   r   r   r   r-      r5   )r6   r7   r$   cdistr   r9   r:   r;   rF   r/   r0   )fX_trnfX_tstr   r=   r   r   r   r   rH      s4   





rH   c                 C   st   t |t |}}t ||krtdt ||t ||}}t ||  || d  d| d  | d S )a  Compute index in condensed pdist matrix

                V
        0 | . 0 1 2 3
     -> 1 | . . 4 5 6 <-   ==>   0 1 2 3 4 5 6 7 8 9
        2 | . . . 7 8                    ^
        3 | . . . . 9
        4 | . . . . .
           ----------
            0 1 2 3 4

    Parameters
    ----------
    n : int
        Number of inputs in squared pdist matrix
    i, j : `int` or `numpy.ndarray`
        Indices in squared pdist matrix

    Returns
    -------
    k : `int` or `numpy.ndarray`
        Index in condensed pdist matrix
    zi and j should be different.r      r   )r   r   any
ValueErrorr/   r0   int64)nr#   jr   r   r   to_condensed   s
   .rQ   c              	   C   sx   t |}t | t d| d| d   d|   d d  d }t |d d ||   d| d  | d }||fS )a1  Compute indices in squared matrix

    Parameters
    ----------
    n : int
        Number of inputs in squared pdist matrix
    k : `int` or `numpy.ndarray`
        Index in condensed pdist matrix

    Returns
    -------
    i, j : `int` or `numpy.ndarray`
        Indices in squared pdist matrix

    i   r   r   r4   rK   )r   r   rN   r   )rO   kr#   rP   r   r   r   
to_squared   s   
8.rT   )r   F)r   )numpyr   scipy.spatial.distancer6   scipy.cluster.hierarchyndarrayr   r   r%   r8   rF   rH   rQ   rT   r   r   r   r   <module>   s   
$
"
,