U
    1eڇ                  (   @   s  d dl Z d dlZd dlZd dlmZ ejdejdZ	de	 Z
ejdejdZe  dd Ze jdd	d
d Ze jdd	dd Ze  efddZe jdd	efddZe  dd Ze  dd Ze  dd Ze  dd Ze  dddZe  dddZe  dd Ze  d d! Ze  edfd"d#Ze  edfd$d%Ze  e	fd&d'Ze  e	fd(d)Ze  d*d+ Ze  d,d- Z e  d.d/ Z!e  d0d1 Z"e  d2d3 Z#e  d4d5 Z$e  d6d7 Z%e  d8d9 Z&e  d:d; Z'e  d<d= Z(e  d>d? Z)e  d@dA Z*e  dBdC Z+e  dDdE Z,e  dFdG Z-e  dHdI Z.e  dJdK Z/e jdd	dLdM Z0e  dNdO Z1e  dPdQ Z2e  dRdS Z3e  dTdU Z4e  dVdW Z5e  dXdY Z6e  dZd[ Z7e jdd	dd]d^Z8e jdd	dd_d`Z9e  dadb Z:e jdd	e	e
dcfdddeZ;e jdd	dfdg Z<e jdd	dhdi Z=e jdd	djdk Z>e jdd	dldm Z?dndo Z@e  dpdq ZAe  i gfdrdsZBe  ddtduZCe  ddvdwZDe  ddydzZEeeeeeeeeeeeeeeeee e/e1e2e,e"e7e8ee$e&e%e'e(e)e+e*e.eAeCeBeDeEd{'ZFeeeeeeeeeeeeeeee!e0e:e3e-e#e9e<e=e>ed|ZGd}ZHdQd[d^de2e7e8efZIe jdd~de2fddZJe jdddde2dfddZKdddZLdS )    N)pairwise_distances   Zdtype      ?c                 C   s   | dk rdS dS d S )Nr       )ar   r   -lib/python3.8/site-packages/umap/distances.pysign   s    r   TZfastmathc                 C   s:   d}t | jd D ]}|| | ||  d 7 }qt|S )z]Standard euclidean distance.

    ..math::
        D(x, y) = \sqrt{\sum_i (x_i - y_i)^2}
            r   r   rangeshapenpsqrtxyresultir   r   r
   	euclidean   s    r   c                 C   sR   d}t | jd D ]}|| | ||  d 7 }qt|}| | d|  }||fS )zStandard euclidean distance and its gradient.

    ..math::
        D(x, y) = \sqrt{\sum_i (x_i - y_i)^2}
        \frac{dD(x, y)}{dx} = (x_i - y_i)/D(x,y)
    r   r   r   ư>r   )r   r   r   r   dgradr   r   r
   euclidean_grad#   s    
r   c                 C   sB   d}t | jd D ]$}|| | ||  d ||  7 }qt|S )zEuclidean distance standardised against a vector of standard
    deviations per coordinate.

    ..math::
        D(x, y) = \sqrt{\sum_i \frac{(x_i - y_i)**2}{v_i}}
    r   r   r   r   )r   r   sigmar   r   r   r   r
   standardised_euclidean3   s    "r   c                 C   s^   d}t | jd D ]$}|| | ||  d ||  7 }qt|}| | d||   }||fS )zEuclidean distance standardised against a vector of standard
    deviations per coordinate with gradient.

    ..math::
        D(x, y) = \sqrt{\sum_i \frac{(x_i - y_i)**2}{v_i}}
    r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r
   standardised_euclidean_gradB   s    "
r   c                 C   s6   d}t | jd D ]}|t| | ||  7 }q|S )z[Manhattan, taxicab, or l1 distance.

    ..math::
        D(x, y) = \sum_i |x_i - y_i|
    r   r   r   r   r   absr   r   r   r
   	manhattanR   s    r"   c                 C   s`   d}t | j}t| jd D ]8}|t | | ||  7 }t | | ||  ||< q||fS )ziManhattan, taxicab, or l1 distance with gradient.

    ..math::
        D(x, y) = \sum_i |x_i - y_i|
    r   r   r   zerosr   r   r!   r   )r   r   r   r   r   r   r   r
   manhattan_grad`   s    r%   c                 C   s8   d}t | jd D ] }t|t| | ||  }q|S )zYChebyshev or l-infinity distance.

    ..math::
        D(x, y) = \max_i |x_i - y_i|
    r   r   )r   r   maxr   r!   r   r   r   r
   	chebyshevo   s    r'   c                 C   sp   d}d}t | jd D ]*}t| | ||  }||kr|}|}qt| j}t| | ||  ||< ||fS )zgChebyshev or l-infinity distance with gradient.

    ..math::
        D(x, y) = \max_i |x_i - y_i|
    r   r   )r   r   r   r!   r$   r   )r   r   r   Zmax_ir   vr   r   r   r
   chebyshev_grad}   s    r)   c                 C   sB   d}t | jd D ]"}|t| | ||  | 7 }q|d|  S )ag  Minkowski distance.

    ..math::
        D(x, y) = \left(\sum_i |x_i - y_i|^p\right)^{\frac{1}{p}}

    This is a general distance. For p=1 it is equivalent to
    manhattan distance, for p=2 it is Euclidean distance, and
    for p=infinity it is Chebyshev distance. In general it is better
    to use the more specialised functions for those distances.
    r   r   r   r    )r   r   pr   r   r   r   r
   	minkowski   s     r+   c                 C   s   d}t | jd D ]"}|t| | ||  | 7 }qtj| jd tjd}t | jd D ]N}tt| | ||  |d t| | ||   t|d|d   ||< qZ|d|  |fS )au  Minkowski distance with gradient.

    ..math::
        D(x, y) = \left(\sum_i |x_i - y_i|^p\right)^{\frac{1}{p}}

    This is a general distance. For p=1 it is equivalent to
    manhattan distance, for p=2 it is Euclidean distance, and
    for p=infinity it is Chebyshev distance. In general it is better
    to use the more specialised functions for those distances.
    r   r   r   r   r   r   r   r   r!   emptyfloat32powr   )r   r   r*   r   r   r   r   r   r
   minkowski_grad   s     r0   c                 C   sT   t | |  }t || }t t | | d}t dd|d| d|     S )zPoincare distance.

    ..math::
        \delta (u, v) = 2 \frac{ \lVert  u - v \rVert ^2 }{ ( 1 - \lVert  u \rVert ^2 ) ( 1 - \lVert  v \rVert ^2 ) }
        D(x, y) = \operatorname{arcosh} (1+\delta (u,v))
    r   r   )r   sumZpowerarccosh)ur(   Z	sq_u_normZ	sq_v_normZsq_distr   r   r
   poincare   s    r4   c                 C   s   t dt | d  }t dt |d  }|| }t| jd D ]}|| | ||  8 }qF|dkrld}dt |d t |d   }t | jd }t| jd D ]$}|| | | | ||   ||< qt ||fS )Nr   r   r   g1  ?r   )r   r   r1   r   r   r$   r2   )r   r   stBr   Z
grad_coeffr   r   r   r
   hyperboloid_grad   s     "r8   c                 C   sJ   d}t | jd D ]*}||| t| | ||  |  7 }q|d|  S )aP  A weighted version of Minkowski distance.

    ..math::
        D(x, y) = \left(\sum_i w_i |x_i - y_i|^p\right)^{\frac{1}{p}}

    If weights w_i are inverse standard deviations of data in each dimension
    then this represented a standardised Minkowski distance (and is
    equivalent to standardised Euclidean distance for p=1).
    r   r   r   r    )r   r   wr*   r   r   r   r   r
   weighted_minkowski   s    (r:   c                 C   s   d}t | jd D ]*}||| t| | ||  |  7 }qtj| jd tjd}t | jd D ]V}|| tt| | ||  |d  t| | ||   t|d|d   ||< qb|d|  |fS )a^  A weighted version of Minkowski distance with gradient.

    ..math::
        D(x, y) = \left(\sum_i w_i |x_i - y_i|^p\right)^{\frac{1}{p}}

    If weights w_i are inverse standard deviations of data in each dimension
    then this represented a standardised Minkowski distance (and is
    equivalent to standardised Euclidean distance for p=1).
    r   r   r   r   r   r,   )r   r   r9   r*   r   r   r   r   r   r
   weighted_minkowski_grad   s    (r;   c                 C   s   d}t j| jd t jd}t| jd D ]}| | ||  ||< q(t| jd D ]D}d}t| jd D ]}||||f ||  7 }qf||||  7 }qPt |S )Nr   r   r   )r   r-   r   r.   r   r   )r   r   vinvr   diffr   tmpjr   r   r
   mahalanobis  s    r@   c                 C   s   d}t j| jd t jd}t| jd D ]}| | ||  ||< q(t | j}t| jd D ]d}d}t| jd D ]<}||||f ||  7 }||  |||f ||  7  < qr||||  7 }q\t |}	|d|	  }
|	|
fS )Nr   r   r   r   )r   r-   r   r.   r   r$   r   )r   r   r<   r   r=   r   Zgrad_tmpr>   r?   distr   r   r   r
   mahalanobis_grad#  s    "
rB   c                 C   sB   d}t | jd D ]}| | || kr|d7 }qt|| jd  S )Nr   r   r   r   r   floatr   r   r   r
   hamming8  s
    
rE   c                 C   s^   d}t | jd D ]F}t| | t||  }|dkr|t| | ||  | 7 }q|S Nr   r   r    )r   r   r   r   denominatorr   r   r
   canberraB  s     rH   c                 C   s   d}t | j}t| jd D ]}t | | t ||  }|dkr|t | | ||  | 7 }t | | ||  | t | | ||  t | |  |d   ||< q||fS )Nr   r   r   r#   )r   r   r   r   r   rG   r   r   r
   canberra_gradM  s    *rI   c                 C   sl   d}d}t | jd D ]8}|t| | ||  7 }|t| | ||  7 }q|dkrdt|| S dS d S rF   )r   r   r   r!   rD   )r   r   	numeratorrG   r   r   r   r
   bray_curtis]  s    rK   c                 C   s   d}d}t | jd D ]8}|t| | ||  7 }|t| | ||  7 }q|dkr|t|| }t| | | | }nd}t| j}||fS rF   )r   r   r   r!   rD   r   r$   )r   r   rJ   rG   r   rA   r   r   r   r
   bray_curtis_gradk  s    rL   c                 C   sl   d}d}t | jd D ]4}| | dk}|| dk}||p:|7 }||oF|7 }q|dkrXdS t|| | S d S rF   rC   )r   r   Znum_non_zeroZ	num_equalr   x_truey_truer   r   r
   jaccard}  s    rO   c                 C   sN   d}t | jd D ](}| | dk}|| dk}|||k7 }qt|| jd  S rF   rC   r   r   num_not_equalr   rM   rN   r   r   r
   matching  s    rR   c                 C   sl   d}d}t | jd D ]4}| | dk}|| dk}||o:|7 }|||k7 }q|dkrXdS |d| |  S d S Nr   r          @r   r   r   r   num_true_truerQ   r   rM   rN   r   r   r
   dice  s    rX   c                 C   s   d}d}t | jd D ]4}| | dk}|| dk}||o:|7 }|||k7 }q|dkrXdS t|| | jd  || jd   S d S rF   rC   rV   r   r   r
   	kulsinski  s    rY   c                 C   sR   d}t | jd D ](}| | dk}|| dk}|||k7 }qd| | jd |  S rS   rU   rP   r   r   r
   rogers_tanimoto  s    rZ   c                 C   s   d}t | jd D ](}| | dk}|| dk}||o6|7 }q|t| dkkrd|t|dkkrddS t| jd | | jd  S d S rF   )r   r   r   r1   rD   )r   r   rW   r   rM   rN   r   r   r
   
russellrao  s    $r[   c                 C   sR   d}t | jd D ](}| | dk}|| dk}|||k7 }qd| | jd |  S rS   rU   rP   r   r   r
   sokal_michener  s    r\   c                 C   sl   d}d}t | jd D ]4}| | dk}|| dk}||o:|7 }|||k7 }q|dkrXdS |d| |  S d S )Nr   r         ?rU   rV   r   r   r
   sokal_sneath  s    r^   c                 C   s   | j d dkrtdtd| d |d   }td| d |d   }t|d t| d t|d  |d   }dt| S )Nr   r   0haversine is only defined for 2 dimensional datar]   r   rT   )r   
ValueErrorr   sinr   cosarcsin)r   r   sin_latsin_longr   r   r   r
   	haversine  s    2rf   c              	   C   s  | j d dkrtdtd| d |d   }td| d |d   }td| d |d   }td| d |d   }t| d tjd  t|d tjd   |d  }||d  }dtttt	t
|dd }tt
|d tt
| }	t|| t| d tjd  t|d tjd   |d   t| d tjd  t|d tjd   | | g|	d  }
||
fS )Nr   r   r_   r]   r   rT   r   )r   r`   r   ra   rb   pirc   r   minr&   r!   array)r   r   rd   Zcos_latre   Zcos_longZa_0Za_1r   Zdenomr   r   r   r
   haversine_grad  s>    8$ rj   c           	      C   s   d}d}d}t | jd D ]D}| | dk}|| dk}||o>|7 }||oL| 7 }|| oZ|7 }q| jd | | | }|dks|dkrdS d| | || ||   S d S rS   rU   )	r   r   rW   Znum_true_falseZnum_false_truer   rM   rN   Znum_false_falser   r   r
   yule   s    
rk   c                 C   s   d}d}d}t | jd D ]8}|| | ||  7 }|| | d 7 }||| d 7 }q|dkrh|dkrhdS |dksx|dkr|dS d|t||   S d S Nr   r   r   r   r   )r   r   r   norm_xnorm_yr   r   r   r
   cosine6  s    ro   c                 C   s   d}d}d}t | jd D ]8}|| | ||  7 }|| | d 7 }||| d 7 }q|dkrv|dkrvd}t| j}n\|dks|dkrd}t| j}n:| | ||   t|d |  }d|t||   }||fS )Nr   r   r   r      r   r   r   r$   r   )r   r   r   rm   rn   r   rA   r   r   r   r
   cosine_gradH  s     $rr   c           
      C   s   d}d}d}d}d}t | jd D ]}|| | 7 }||| 7 }q"|| jd  }|| jd  }t | jd D ]@}| | | }|| | }	||d 7 }||	d 7 }|||	 7 }qj|dkr|dkrdS |dkrdS d|t||   S d S rl   r   )
r   r   mu_xmu_yrm   rn   dot_productr   	shifted_x	shifted_yr   r   r
   correlation_  s*    rx   c                 C   s   d}d}d}t | jd D ]6}|t| | ||  7 }|| | 7 }||| 7 }q|dkrf|dkrfdS |dksv|dkrzdS td|t||   S d S )Nr   r   r   r   r   )r   r   r   	l1_norm_x	l1_norm_yr   r   r   r
   	hellinger}  s    r{   c                 C   s
  d}d}d}t | jd }t| jd D ]B}t | | ||  ||< ||| 7 }|| | 7 }||| 7 }q*|dkr|dkrd}t | j}nr|dks|dkrd}t | j}nPt || }	t d||	  }d| }
|| d|	d   }||| |	  |
 }||fS )Nr   r   r   r   r   rp   )r   r-   r   r   r   r$   )r   r   r   ry   rz   Z	grad_termr   rA   r   Z
dist_denomZ
grad_denomZgrad_numer_constr   r   r
   hellinger_grad  s*    r|   c                 C   sB   | dkrdS | t |  |  dt dt j |    d| d   S )Nr   r   r]   rT   r   g      (@r   logrg   r   r   r   r
   approx_log_Gamma  s    r   c                 C   s|   t | |}t| |}|dk r\t| }tdt|D ] }|t|t||  7 }q6|S t| t| t| |  S d S )N   r   )rh   r&   r   r~   r   intr   )r   r   r	   bvaluer   r   r   r
   log_beta  s    

r   c                 C   s6   t dd|  d  dt dt j |    d|   S )NrT   g       r]   g      ?r}   r   r   r   r
   log_single_beta  s    r   c                 C   s  t | }t |}d}d}d}t| jd D ]}| | ||  dkr~|t| | || 7 }|t| | 7 }|t|| 7 }q.| | dkr|t| | 7 }|| dkr.|t|| 7 }q.t d| |t|| |t|   d| |t|| |t|    S )zThe symmetric relative log likelihood of rolling data2 vs data1
    in n trials on a die that rolled data1 in sum(data1) trials.

    ..math::
        D(data1, data2) = DirichletMultinomail(data2 | data1)
    r   r   g?r   )r   r1   r   r   r   r   r   )Zdata1Zdata2Zn1Zn2Zlog_bZself_denom1Zself_denom2r   r   r   r
   ll_dirichlet  s&    	

  r   dy=c           	      C   s   | j d }d}d}d}d}t|D ]<}| |  |7  < || | 7 }||  |7  < ||| 7 }q"t|D ]$}| |  |  < ||  |  < qht|D ]H}|| | t| | ||   7 }||| t|| | |   7 }q|| d S )z
    symmetrized KL divergence between two probability distributions

    ..math::
        D(x, y) = \frac{D_{KL}\left(x \Vert y\right) + D_{KL}\left(y \Vert x\right)}{2}
    r   r   r   r   r   r   r~   )	r   r   znx_sumy_sumkl1kl2r   r   r   r
   symmetric_kl  s"    
"$r   c                 C   s  | j d }d}d}d}d}t|D ]<}| |  |7  < || | 7 }||  |7  < ||| 7 }q"t|D ]$}| |  |  < ||  |  < qht|D ]H}|| | t| | ||   7 }||| t|| | |   7 }q|| d }	t||  | |  d d }
|	|
fS )z5
    symmetrized KL divergence and its gradient

    r   r   r   r   r   )r   r   r   r   r   r   r   r   r   rA   r   r   r   r
   symmetric_kl_grad  s&    
"$r   c                 C   s"  d}d}d}d}d}t | jd D ]}|| | 7 }||| 7 }q"|| jd  }|| jd  }t | jd D ]@}| | | }|| | }	||d 7 }||	d 7 }|||	 7 }qj|dkr|dkrd}
t| j}nL|dkrd}
t| j}n2d|t||   }
| | | || |  |
 }|
|fS rl   rq   )r   r   rs   rt   rm   rn   ru   r   rv   rw   rA   r   r   r   r
   correlation_grad7  s2    r   @   c                 C   s   | |    tj}||   tj}tj|jtjd}tj|jtjd}t|D ]V}	|| }
||
dk |
|
dk  ||
dk< |j| }
||
dk |
|
dk  ||
dk< qTt|| t| }d}t|jd D ]D}t|jd D ]0}|||f dkr||||f |||f  7 }qq|S )Nr   r   r   r   )	r1   astyper   r.   onesr   r   TZdiag)r   r   MZcostmaxiterr*   qr3   r(   r   r6   rg   r   r   r?   r   r   r
   sinkhorn_distanceZ  s      
" r   c                 C   s   | d |d  }| d |d  }t | d t |d  }t | d }|d |d  d|  t | t dt j  }t dt j}|| |d< || |d< |d| |d |d  d|d     |d< ||fS )Nr   r   r   rp   r   )r   r!   r   r~   rg   r-   r.   )r   r   mu_1mu_2r   Z
sign_sigmarA   r   r   r   r
   spherical_gaussian_energy_gradt  s    2,r   c                 C   s  | d |d  }| d |d  }t | d t |d  }d}t | d t |d  }|| }t | d }t | d }	|dkr|d |d  t jddddgt jdfS d| }
t ||d  |
| |  t ||d   }|| t t | d t dt j  }t jd	t jd}d| | |
|  d|  |d< d| | |
|  d|  |d< ||||  ||d    d|d   |d< |	|||  ||d    d|d   |d< ||fS )
Nr   r   r   r   rp   r   r   rT      )r   r!   r   ri   r.   r~   rg   r-   )r   r   r   r   sigma_11sigma_12sigma_22ZdetZsign_s1Zsign_s2Z
cross_termZm_distrA   r   r   r   r
   diagonal_gaussian_energy_grad  s0    (
,  ,,r   c              
   C   s0  | d |d  }| d |d  }t | d | d< t |d |d< t | d | d< t |d |d< t t | d | d< t t |d |d< |d t |d d  |d t |d d   }|d |d  t |d  t |d  }|d t |d d  |d t |d d   }| d t | d d  | d t | d d   | }| d | d  t | d  t | d  | }| d t | d d  | d t | d d   | }	t ||	 |d  }
|	|d  d| | |  ||d   }|
dk r>|d |d  t jdddddgt jd	fS ||
 t |
 t dt j  }t 	d
t j}d|	 | d| |  |
 |d< d| | d| |  |
 |d< ||t | d d  |t | d  t | d    |d< |d  ||t | d d  |t | d  t | d    7  < |d  |
9  < |d  |t | d d  |	 8  < |d  |t | d d  | 8  < |d  |d | t | d  t | d  7  < |d  |
d d   < ||t | d d  |t | d  t | d    |d< |d  ||t | d d  |t | d  t | d    7  < |d  |
9  < |d  |t | d d  |	 8  < |d  |t | d d  | 8  < |d  |d | t | d  t | d  8  < |d  |
d d   < | d | d  d| | t d| d   |d |d  t d| d     |d< |d  |
9  < |d  || d | d   t d| d   |	 8  < |d  || d | d   t d| d   | 8  < |d  |d | | d | d   t d| d   8  < |d  |
d d   < ||fS )Nr   r   r   rp      g3#I9r   r   r   r   g:0yE>)
r   r!   rc   ra   rb   ri   r.   r~   rg   r$   )r   r   r   r   r	   r   cr   r   r   Z	det_sigmaZx_inv_sigma_y_numeratorrA   r   r   r   r
   gaussian_energy_grad  s`    4,4808&
"  >F&&4>F&&4>66:r   c                 C   s  | d |d  }| d |d  }| d |d  }t |}|dkr\dt jdddgt jdfS |d |d  t | dt t |  t dt j  }t jdt jd}d| t | |d< d| t | |d< ||d |d   |d  dt |   |d< ||fS )	Nr   r   r   g      $@r   g      r   rp   )r   r   ri   r.   r!   r~   rg   r-   )r   r   r   r   r   Z
sigma_signrA   r   r   r   r
   spherical_gaussian_grad  s&    
&r   c           	      C   s   |dkr$dt |  |   d iS |dkrltj| }tj| }tj| }t|||d}||d dS |dkrt	
dd	 | D }tj|}|d
 }|d }||d dS i S d S )Nordinalsupport_sizerT   count)poisson_lambda)r   normalisationstringc                 S   s   g | ]}t |qS r   )len).0r   r   r   r
   
<listcomp>  s     z'get_discrete_params.<locals>.<listcomp>g      ?)r   max_dist)rD   r&   rh   scipyZstatsZtminZtmaxZtmeancount_distancer   ri   )	datametricZ	min_countZ	max_countZlambda_r   ZlengthsZ
max_lengthr   r   r   r
   get_discrete_params  s"    r   c                 C   s   | |krdS dS d S )Nr   r   r   )r   r   r   r   r
   categorical_distance'  s    r   c                 C   sB   t t|}t|D ](\}}||  || krt ||   S qdS )Nr   )rD   r   	enumerate)r   r   Zcat_hierarchyZn_levelslevelZcatsr   r   r
   !hierarchical_categorical_distance/  s
    r   c                 C   s   t | | | S N)r!   )r   r   r   r   r   r
   ordinal_distance9  s    r   c           
      C   s   t t| |}t t| |}t|}|dk r4d}n8|dk r`d}td|D ]}|t|7 }qJnt|d }d}	t||D ]&}|	|| | | 7 }	|t|7 }qz|	| S )Nr   r   
   r   )r   rh   r&   r   r~   r   r   )
r   r   r   r   lohiZ
log_lambdaZlog_k_factorialkr   r   r   r
   r   >  s    
r      c                 C   s   t | t | }}t|| |kr2t|| | S t|d tj}t|d }t|D ]}|d ||< t|D ]H}	||	d  d }
||	 d }t| | ||	 k}t	|
||||	d < qv|}t	||kr^||   S q^|| | S )Nr   )
r   r!   r   Zaranger   float64r$   r   r   rh   )r   r   r   Zmax_distanceZx_lenZy_lenZv0Zv1r   r?   Zdeletion_costZinsertion_costZsubstitution_costr   r   r
   levenshteinW  s     r   )'r   l2r"   taxicabl1r'   	linfinitylinftylinfr+   r4   
seuclideanr   
wminkowskir:   r@   rH   ro   rx   r{   rf   
braycurtisr   r   rE   rO   rX   rR   rY   Zrogerstanimotor[   ZsokalsneathZsokalmichenerrk   categoricalr   hierarchical_categoricalr   r   )r   r   r"   r   r   r'   r   r   r   r+   r   r   r   r:   r@   rH   ro   rx   r{   rf   r   r   Zspherical_gaussian_energyZdiagonal_gaussian_energyZgaussian_energyZhyperboloid)r   r   r   r   r   )parallelc                 C   s   |d krt | jd | jd f}t| jd D ]L}t|d | jd D ]2}|| | | | |||f< |||f |||f< qHq0n\t | jd |jd f}t| jd D ]2}t|jd D ]}|| | || |||f< qq|S )Nr   r   )r   r$   r   r   )XYr   r   r   r?   r   r   r
   parallel_special_metric  s    r   )r   Znogil   c                 C   s   |d kr"| d }}| j d  }}n |d }}| j d |j d  }}tj||ftjd}|| d }	t|	D ]}
|
| }t|| |}|r|nd}t|||D ]L}t|| |}t||D ].}t||D ]}|| | || |||f< qqqql|S )NTr   Fr   r   )r   r   r$   r.   numbaZprangerh   r   )r   r   r   Z
chunk_sizeZXXZsymmetricalZrow_sizeZcol_sizer   Zn_row_chunksZ	chunk_idxr   Zchunk_end_nZm_startmZchunk_end_mr   r?   r   r   r
   chunked_parallel_special_metric  s"    

"r   c                    sd   t rN|d k	rt|  nd tjddd fdd	}t| |||dS t }t| ||dS )	Nr   Tr   c                    s   | |f  S r   r   )Z_XZ_YZkwd_valsr   r   r
   _partial_metric  s    z0pairwise_special_metric.<locals>._partial_metric)r   force_all_finite)r   )N)callabletuplevaluesr   njitr   named_distancesr   )r   r   r   kwdsr   r   Zspecial_metric_funcr   r   r
   pairwise_special_metric  s    
r   )r   )r   )r   )r   )r   )r   r   )r   r   )Nr{   NT)Mr   Znumpyr   Zscipy.statsr   Zsklearn.metricsr   Zeyer   Z_mock_identityZ
_mock_costr   Z
_mock_onesr   r   r   r   r   r   r"   r%   r'   r)   r+   r0   r4   r8   r:   r;   r@   rB   rE   rH   rI   rK   rL   rO   rR   rX   rY   rZ   r[   r\   r^   rf   rj   rk   ro   rr   rx   r{   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Znamed_distances_with_gradientsZDISCRETE_METRICSZSPECIAL_METRICSr   r   r   r   r   r   r
   <module>   s  












	
















	
'










"


"
  



"

H


	 1!	
