
    Wiʆ              
       V   d dl Z d dlZd dlmZ d dlmZ d dlm	Z	  e j                         d        Z e j                  ddde j                  j                  e j                  j                  e j                  j                  e j                  j                  d      d	        Zd
 Zd Z e j                  edd      Z e j                  edd      ZddefdZ	 	 	 	 	 	 	 	 	 ddZd Zdddej0                  ddddfdZd Zdddej0                  ddddfdZd Z	 	 	 	 	 	 	 	 	 	 ddZy)    N)tqdm)tau_rand_intc                     | dkD  ry| dk  ry| S )zStandard clamping of a value into a fixed range (in this case -4.0 to
    4.0)

    Parameters
    ----------
    val: float
        The value to be clamped.

    Returns
    -------
    The clamped value, now fixed to be in the range -4.0 to 4.0.
    g      @g       )vals    X/home/sietch6/trending-topics-pipeline/venv/lib/python3.12/site-packages/umap/layouts.pyclipr	   	   s     Sy	t
    zf4(f4[::1],f4[::1])T)resultdiffdimi)fastmathcachelocalsc                 n    d}| j                   d   }t        |      D ]  }| |   ||   z
  }|||z  z  } |S )zReduced Euclidean distance.

    Parameters
    ----------
    x: array of shape (embedding_dim,)
    y: array of shape (embedding_dim,)

    Returns
    -------
    The squared euclidean distance between x and y
            r   )shaperange)xyr   r   r   r   s         r   rdistr      sO    . F
''!*C3Z tad{$+ Mr
   c           	      x   t        j                  |j                  d         D ]  }||   |k  s||   }||   }| |   }||   }t        ||      } |rdd|t	        | |      z  z   z  }!||z  t	        | |dz
        z  d|t	        | |      z  z   z  }"|!||   z  }#|!||   z  }$|#d|d|!z
  z  z
  t        j                  ||         z  |"z   z  }%|$d|d|!z
  z  z
  t        j                  ||         z  |"z   z  }&||z  }'||   |||   |z
  z  |'z  z
  }(||   |||   |z
  z  |'z  z
  })||z  |(|%z  |)|&z  z   z  ||   |z  z  |z  }*| dkD  r.d|z  |z  t	        | |dz
        z  }+|+|t	        | |      z  dz   z  }+nd}+t        |
      D ]\  },t        |+||,   ||,   z
  z        }-|r|-t        d*z  ||,   ||,   z
  z        z  }-||,xx   |-|z  z  cc<   |sL||,xx   |- |z  z  cc<   ^ ||xx   ||   z  cc<   t        |||   z
  ||   z        }.t        |.      D ]  }/t        ||         |z  }||   }t        ||      } | dkD  r$d|	z  |z  }+|+d| z   |t	        | |      z  dz   z  z  }+n||k(  rTd}+t        |
      D ]1  },|+dkD  rt        |+||,   ||,   z
  z        }-nd}-||,xx   |-|z  z  cc<   3  ||xx   |.||   z  z  cc<    y )	Nr         ?   r                    @MbP?)numbapranger   r   pownpexpr   r	   intr   )0head_embeddingtail_embeddingheadtail
n_verticesepochs_per_sampleabrng_state_per_samplegammar   
move_otheralphaepochs_per_negative_sampleepoch_of_next_negative_sampleepoch_of_next_samplendensmap_flagdens_phi_sumdens_re_sumdens_re_covdens_re_stddens_re_meandens_lambdadens_Rdens_mudens_mu_totr   jkcurrentotherdist_squaredphi	dphi_termq_jkq_kjdrkdrj	re_std_sqweight_kweight_jgrad_cor_coeff
grad_coeffdgrad_dn_neg_samplesps0                                                   r   '_optimize_layout_euclidean_single_epochrT   ?   s   : \\+11!45 ^"a'QAQA$Q'G"1%E %0LS1s<';#;;<ECa!e44a#lTUBV>V8VW  \!_,\!_,1C=(BFF;q>,BBYN 1C=(BFF;q>,BBYN (+5	1I![^l%BCiOP 
 1I![^l%BCiOP   !"#~368 qzK/1 !	!  c!!AX\Ca#g,FF
a#lA"66<<
 
3Z 
0jGAJq,ABC d1~#5eAh9N#OPPF
fun,
!H%/H
0 !#'8';;#21559STU9VVM =) 1 !5a!89JF&q)$We4#%!$uqJ5<#7Ca0014# J !V!$Js 1A!C'!%jGAJq4I&J!K!"AJ&5.0J1#10 *!, :1 ==,y^r
   c                    |j                  d       |j                  d       t        j                  |j                        D ]q  }||   }	||   }
| |	   }||
   }t	        ||      }dd|t        ||      z  z   z  }||	xx   ||z  z  cc<   ||
xx   ||z  z  cc<   ||	xx   |z  cc<   ||
xx   |z  cc<   s d}t        |j                        D ]&  }t        j                  |||   ||   z  z         ||<   ( y )Nr   r   g:0yE>)	fillr    r!   sizer   r"   r   r#   log)r&   r'   r(   r)   r,   r-   re_sumphi_sumr   r@   rA   rB   rC   rD   rE   epsilons                   r   -_optimize_layout_euclidean_densmap_epoch_initr\      s    KKNLLO\\$))$ GG #q!We,S1s<3334q	S<''	q	S<''	
c

c
 G6;; ?FF7fQi'!*&<=>q	?r
   Fr   parallelr^   c                     | rt         S t        S )N)3_nb_optimize_layout_euclidean_single_epoch_parallel*_nb_optimize_layout_euclidean_single_epoch)r^   s    r   ._get_optimize_layout_euclidean_single_epoch_fnrb      s    BB99r
   r         @c                 F   | j                   d   }|}||z  }|j                         }|j                         }t        |      }|i }|i }|rt        j                  t
        d|      }t        j                  |d         dz  }|d   }|d   }|d	   }t        j                  |t        j                  
      }t        j                  |t        j                  
      }|d   } nd}d}t        j                  dt        j                  
      }t        j                  dt        j                  
      }t        j                  dt        j                  
      }t        j                  dt        j                  
      }d}!g }"t        |t              r|}!t        |!      }d|vr| |d<   t        j                  | j                   d   t        |	      f|	t        j                  
      | dddf   j!                  t        j"                        j%                  t        j                        j'                  dd      z   }#t)        t+        |      fi |D ],  }$|xr$ |d   dkD  xr |$dz   t-        |      z  d|d   z
  kD  }%|%rl | |||||||       t        j.                  t        j0                  |       z         }&t        j2                  |      }'t        j4                  ||      |dz
  z  }(nd}&d}'d}( || ||||||||#|
|||||||$|%|||(|&|'||||       |dt-        |$      t-        |      z  z
  z  }|r#|$t7        |dz        z  dk(  rt9        d|$d|d       |!|$|!v s|"j;                  | j                                / |!|"j;                  | j                                |!| S |"S )a^  Improve an embedding using stochastic gradient descent to minimize the
    fuzzy set cross entropy between the 1-skeletons of the high dimensional
    and low dimensional fuzzy simplicial sets. In practice this is done by
    sampling edges based on their membership strength (with the (1-p) terms
    coming from negative sampling similar to word2vec).
    Parameters
    ----------
    head_embedding: array of shape (n_samples, n_components)
        The initial embedding to be improved by SGD.
    tail_embedding: array of shape (source_samples, n_components)
        The reference embedding of embedded points. If not embedding new
        previously unseen points with respect to an existing embedding this
        is simply the head_embedding (again); otherwise it provides the
        existing embedding to embed with respect to.
    head: array of shape (n_1_simplices)
        The indices of the heads of 1-simplices with non-zero membership.
    tail: array of shape (n_1_simplices)
        The indices of the tails of 1-simplices with non-zero membership.
    n_epochs: int, or list of int
        The number of training epochs to use in optimization, or a list of
        epochs at which to save the embedding. In case of a list, the optimization
        will use the maximum number of epochs in the list, and will return a list
        of embedding in the order of increasing epoch, regardless of the order in
        the epoch list.
    n_vertices: int
        The number of vertices (0-simplices) in the dataset.
    epochs_per_sample: array of shape (n_1_simplices)
        A float value of the number of epochs per 1-simplex. 1-simplices with
        weaker membership strength will have more epochs between being sampled.
    a: float
        Parameter of differentiable approximation of right adjoint functor
    b: float
        Parameter of differentiable approximation of right adjoint functor
    rng_state: array of int64, shape (3,)
        The internal state of the rng
    gamma: float (optional, default 1.0)
        Weight to apply to negative samples.
    initial_alpha: float (optional, default 1.0)
        Initial learning rate for the SGD.
    negative_sample_rate: int (optional, default 5)
        Number of negative samples to use per positive sample.
    parallel: bool (optional, default False)
        Whether to run the computation using numba parallel.
        Running in parallel is non-deterministic, and is not used
        if a random seed has been set, to ensure reproducibility.
    verbose: bool (optional, default False)
        Whether to report information on the current progress of the algorithm.
    densmap: bool (optional, default False)
        Whether to use the density-augmented densMAP objective
    densmap_kwds: dict (optional, default None)
        Auxiliary data for densMAP
    tqdm_kwds: dict (optional, default None)
        Keyword arguments for tqdm progress bar.
    move_other: bool (optional, default False)
        Whether to adjust tail_embedding alongside head_embedding
    Returns
    -------
    embedding: array of shape (n_samples, n_components)
        The optimized embedding.
    r   NTr]   mu_sumr   lambdaRmudtype	var_shiftr   disablefracr   
   z	completed z / epochs)r   copyrb   r    njitr\   r#   sumzerosfloat32
isinstancelistmaxfulllenint64astypefloat64viewreshaper   r   floatsqrtvarmeandotr%   printappend))r&   r'   r(   r)   n_epochsr*   r+   r,   r-   	rng_stater/   initial_alphanegative_sample_rater^   verbosedensmapdensmap_kwds	tqdm_kwdsr0   r   r1   r2   r3   r4   optimize_fndens_init_fnr?   r<   r=   r>   r7   r8   dens_var_shiftepochs_listembedding_listr.   r5   r6   r:   r;   r9   s)                                            r   optimize_layout_euclideanr      s   d 

q
!CE!25I!I$>$C$C$E!,113 AJK	zz9
 ff\(34q8"8,c"t$xx
"**=hhz<%k2!2::.((1BJJ/xx4hhq

3KN(D!{#	!#*{	)77			a	 #i.19BHHq!t##BJJ/44RXX>FFr1MN %//Y/ B9 Kh'!+Kq5E(O+L4H0HI 	  	 ''"&&"5"FGK77;/L&&f5aHKKLK &) 7	
< a5?(B!CDq3x"}--2.!UHh?"qK'7!!."5"5"78EB9J n1134(0>DnDr
   c                    t        | j                  d         D ]  }||   |k  s||   }||   }||   }||   } |||g| \  }} |||g| \  }}|dkD  r t        d|t        |d|z        z  z   d      }nd}d|z  |dz
  z  |dz   z  }t        |      D ]G  }t        |||   z        }||xx   ||	z  z  cc<   |
s't        |||   z        }||xx   ||	z  z  cc<   I ||xx   | |   z  cc<   t	        |||   z
  ||   z        } t        |       D ]  }!t        ||         |z  }||   } |||g| \  }}|dkD  r t        d|t        |d|z        z  z   d      }n||k(  rQd}|dz  |z  |z  |dz   z  }t        |      D ]#  }t        |||   z        }||xx   ||	z  z  cc<   %  ||xx   | ||   z  z  cc<    ||fS )Nr   r   r   r   rm   r   ư>)r   r   r"   r	   r%   r   )"r+   r4   r(   r)   r&   r'   output_metricoutput_metric_kwdsr   r1   r0   r5   r3   r2   r.   r*   r,   r-   r/   r   r@   rA   rB   rC   dist_outputgrad_dist_output_rev_grad_dist_outputw_lrO   rP   rQ   rR   rS   s"                                     r   %_optimize_layout_generic_single_epochr     s   * $**1-. 9"a'QAQA$Q'G"1%E,9-!3-)K) '4E7&XEW&X#A#S 1q3{AE#:::R@Q#'*kD.@AJ3Z /j+;A+>>?
fun,
!*/CA/F"FGF!H.H/ !#'8';;#21559STU9VVM =) 1 !5a!89JF&q)0=U1%71-- $q1s;A'>#>>DC!VC"QY]S0K$4FG
s 1A!*/?/B"BCFAJ&5.0J1%1, *!, :1 ==,o9t  !>>>r
   r   c                    | j                   d   }|}||z  }|j                         }|j                         }t        j                  t        d      }|i }d|vr| |d<   t        j                  | j                   d   t        |	      f|	t
        j                        | dddf   j                  t
        j                        j                  t
        j                        j                  dd      z   }t        t        |      fi |D ]9  } |||||| ||||||||||||||
       |d	t        |      t        |      z  z
  z  }; | S )
a	  Improve an embedding using stochastic gradient descent to minimize the
    fuzzy set cross entropy between the 1-skeletons of the high dimensional
    and low dimensional fuzzy simplicial sets. In practice this is done by
    sampling edges based on their membership strength (with the (1-p) terms
    coming from negative sampling similar to word2vec).

    Parameters
    ----------
    head_embedding: array of shape (n_samples, n_components)
        The initial embedding to be improved by SGD.

    tail_embedding: array of shape (source_samples, n_components)
        The reference embedding of embedded points. If not embedding new
        previously unseen points with respect to an existing embedding this
        is simply the head_embedding (again); otherwise it provides the
        existing embedding to embed with respect to.

    head: array of shape (n_1_simplices)
        The indices of the heads of 1-simplices with non-zero membership.

    tail: array of shape (n_1_simplices)
        The indices of the tails of 1-simplices with non-zero membership.

    n_epochs: int
        The number of training epochs to use in optimization.

    n_vertices: int
        The number of vertices (0-simplices) in the dataset.

    epochs_per_sample: array of shape (n_1_simplices)
        A float value of the number of epochs per 1-simplex. 1-simplices with
        weaker membership strength will have more epochs between being sampled.

    a: float
        Parameter of differentiable approximation of right adjoint functor

    b: float
        Parameter of differentiable approximation of right adjoint functor

    rng_state: array of int64, shape (3,)
        The internal state of the rng

    gamma: float (optional, default 1.0)
        Weight to apply to negative samples.

    initial_alpha: float (optional, default 1.0)
        Initial learning rate for the SGD.

    negative_sample_rate: int (optional, default 5)
        Number of negative samples to use per positive sample.

    verbose: bool (optional, default False)
        Whether to report information on the current progress of the algorithm.

    tqdm_kwds: dict (optional, default None)
        Keyword arguments for tqdm progress bar.

    move_other: bool (optional, default False)
        Whether to adjust tail_embedding alongside head_embedding

    Returns
    -------
    embedding: array of shape (n_samples, n_components)
        The optimized embedding.
    r   Tr   Nrl   r   ri   rm   r   )r   rq   r    rr   r   r#   ry   rz   r{   r|   r}   r~   r   r   r   r   )r&   r'   r(   r)   r   r*   r+   r,   r-   r   r/   r   r   r   r   r   r   r0   r   r1   r2   r3   r4   r   r.   r5   s                             r   optimize_layout_genericr     sl   l 

q
!CE!25I!I$>$C$C$E!,113**-K
 		!#*{	)77			a	 #i.19BHHq!t##BJJ/44RXX>FFr1MN %//Y/ E )& '	
* a5?(B!CD-E0 r
   c           	         t        | j                  d         D ]h  }||   |k  s||   }||   }||   }||   } |||g| \  }}||   }d||	|   z  dz   z   }t        |
      D ]7  }t        |||   z        }||xx   ||z  z  cc<   |s'||xx   | |z  z  cc<   9 ||xx   | |   z  cc<   t        |||   z
  ||   z        }t        |      D ]  } t	        |      |z  }||   } |||g| \  }}t        j                  t        |||   z
  d       |	|   dz   z        }!| d|!z
  d|!z
  |	|   z  dz   z  z  }t        |
      D ]#  }t        |||   z        }||xx   ||z  z  cc<   %  ||xx   |||   z  z  cc<   k y )Nr   r   r   )r   r   r	   r%   r   r#   r$   rx   )"r+   r4   r(   r)   r&   r'   r   r   weightsigmasr   r1   r0   r5   r3   r2   r   r*   rhosr/   r   r@   rA   rB   rC   r   r   r   rO   rP   rQ   rR   rS   w_hs"                                     r   %_optimize_layout_inverse_single_epochr     s%   , $**1-. /"a'QAQA$Q'G"1%E,9-!3-)K) )CfQi$ 678J3Z 0j+;A+>>?
fun,
!H%/H0 !#'8';;#21559STU9VVM =) 1 +j8&q)0=U1%71--
 ffc+Q"7>>&)dBRST#VCQWq	4ID4P'QR
s 1A!*/?/B"BCFAJ&5.0J11" *!, :1 ==,[/r
   c                 h   | j                   d   }|}|	|z  }|j                         }|	j                         }t        j                  t        d      }|i }d|vr| |d<   t        t        |      fi |D ]:  } ||	|||| |||||||||||||||       |dt        |      t        |      z  z
  z  }< | S )a
  Improve an embedding using stochastic gradient descent to minimize the
    fuzzy set cross entropy between the 1-skeletons of the high dimensional
    and low dimensional fuzzy simplicial sets. In practice this is done by
    sampling edges based on their membership strength (with the (1-p) terms
    coming from negative sampling similar to word2vec).

    Parameters
    ----------
    head_embedding: array of shape (n_samples, n_components)
        The initial embedding to be improved by SGD.

    tail_embedding: array of shape (source_samples, n_components)
        The reference embedding of embedded points. If not embedding new
        previously unseen points with respect to an existing embedding this
        is simply the head_embedding (again); otherwise it provides the
        existing embedding to embed with respect to.

    head: array of shape (n_1_simplices)
        The indices of the heads of 1-simplices with non-zero membership.

    tail: array of shape (n_1_simplices)
        The indices of the tails of 1-simplices with non-zero membership.

    weight: array of shape (n_1_simplices)
        The membership weights of the 1-simplices.

    sigmas:

    rhos:

    n_epochs: int
        The number of training epochs to use in optimization.

    n_vertices: int
        The number of vertices (0-simplices) in the dataset.

    epochs_per_sample: array of shape (n_1_simplices)
        A float value of the number of epochs per 1-simplex. 1-simplices with
        weaker membership strength will have more epochs between being sampled.

    a: float
        Parameter of differentiable approximation of right adjoint functor

    b: float
        Parameter of differentiable approximation of right adjoint functor

    rng_state: array of int64, shape (3,)
        The internal state of the rng

    gamma: float (optional, default 1.0)
        Weight to apply to negative samples.

    initial_alpha: float (optional, default 1.0)
        Initial learning rate for the SGD.

    negative_sample_rate: int (optional, default 5)
        Number of negative samples to use per positive sample.

    verbose: bool (optional, default False)
        Whether to report information on the current progress of the algorithm.

    tqdm_kwds: dict (optional, default None)
        Keyword arguments for tqdm progress bar.

    move_other: bool (optional, default False)
        Whether to adjust tail_embedding alongside head_embedding

    Returns
    -------
    embedding: array of shape (n_samples, n_components)
        The optimized embedding.
    r   Tr   rl   r   )r   rq   r    rr   r   r   r   r   )r&   r'   r(   r)   r   r   r   r   r*   r+   r,   r-   r   r/   r   r   r   r   r   r   r0   r   r1   r2   r3   r4   r   r5   s                               r   optimize_layout_inverser     s   @ 

q
!CE!25I!I$>$C$C$E!,113**-K
 		!#*{	)%//Y/ E )&)	
, a5?(B!CD/E2 r
   c                 d	   t        |      }|j                  d   dz
  dz  }d}|D ]$  }|j                  d   |k\  s|j                  d   }& t        j                  |      j	                  t        j
                        }t        j                  j                  t        |	d                t        j                  j                  |       t        |      D ]  }|D ]  }|||   j                  d   k  s||   |   |k  s&||   |   }||   |   }| |   |   }||   |   }t        ||      }|dkD  r.d|z  |z  t        ||dz
        z  }||t        ||      z  dz   z  }nd}t        |      D ]  } t        |||    ||    z
  z        }!t        | |      D ]  }"||"z   }#||#cxkD  rdcxk\  r|"k7  sn |||"|z   |f   }$|$dk\  s.|!t        |t        j                  t        j                  |"      dz
         z  |||"|z   |f   z  ||    | |#   |$| f   z
  z        z  }! || xx   t        |!      |z  z  cc<   |st        |||    ||    z
  z        }%t        | |      D ]  }"||"z   }#||#cxkD  rdcxk\  r|"k7  sn |||"|z   |f   }$|$dk\  s.|%t        |t        j                  t        j                  |"      dz
         z  |||"|z   |f   z  ||    | |#   |$| f   z
  z        z  }% || xx   t        |%      |z  z  cc<    ||   |xx   ||   |   z  cc<   ||   |   dkD  rt        |||   |   z
  ||   |   z        }&nd}&t        |&      D ]C  }'t!        |	      ||   j                  d   z  }||   |   }t        ||      }|dkD  r$d|
z  |z  }|d|z   |t        ||      z  dz   z  z  }n||k(  red}t        |      D ]  } |dkD  rt        |||    ||    z
  z        }!nd}!t        | |      D ]  }"||"z   }#||#cxkD  rdcxk\  r|"k7  sn |||"|z   |f   }$|$dk\  s.|!t        |t        j                  t        j                  |"      dz
         z  |||"|z   |f   z  ||    | |#   |$| f   z
  z        z  }! || xx   t        |!      |z  z  cc<    F ||   |xx   |&||   |   z  z  cc<     y )	Nr   r   r   r   r   r   r   r   )rz   r   r#   aranger|   int32randomseedabsshuffler   r   r"   r	   r$   r%   r   )(head_embeddingstail_embeddingsheadstailsr+   r,   r-   regularisation_weights	relationsr   r/   lambda_r   r0   r1   r2   r3   r4   r5   n_embeddingswindow_sizemax_n_edgese_p_sembedding_orderr   mr@   rA   rB   rC   rD   rO   rP   rQ   offset
neighbor_midentified_indexother_grad_drR   rS   s(                                           r   /_optimize_layout_aligned_euclidean_single_epochr   m  s   * u:L??1%)a/KK" );;q>[(++a.K) ii-44RXX>OIINN3y|$%IIo&; s  r	A'*00338LQ8OPQ8RVW8W!HQK!HQK)!,Q/'*1-$We4#%!%AL!c'0J!JJ!c,&:":S"@@J!$Js )?A!*
U1X0E"FGF"'k"B "%&Z
'*CCVC/8F[<PRS9S/T,/14 &$%,rvvv8J6K/L%L&<Q@TVW=W&X%Y )0
*9**E,<a,?+*)*%&	+" 	!""  AJ$v,"66J!'+J%(WQZ:O,P'Q&+[L+&F &F)*VJ+jGAGG3<Q@TVW=W3X 0#3q#8$0D)0266BFF6NQ<N:O3P)P*@,-v/CQ,F+*)*
 -2!H.=j.I0@!0C/.-.	)*5& %&L&$ aD$6$>>S)?V %Q'*.?.B1.EE*-a03a7$':1=a@@4Q7:;%M
 %&M}- );A$Y//!2D2J2J12MMA+A.q1E#(%#8L#c)%(5[1_
"u|';L! 44q8' 
 a %(
"3Z ;%+%)*
U1X8M*N%OF%(F&+[L+&F &F)*VJ+jGAGG3<Q@TVW=W3X 0#3q#8$*d)0266BFF6NQ<N:O3P)P*@,-v/CQ,F+*)*
 -4AJ.=j.I0@!0C/.-.	)*/& %&F&$  
d6lU&::
1;#);V .a03!$>q$A!$DD3ar	sr
   c                 ,   | d   j                   d   }|}t        j                  j                  j	                  t        j
                  j                  d d d         }t        j                  j                  j	                  t        j
                  j                  d d d         }t        j                  j                  j	                  t        j
                  j                  d d d         }t        t        |            D ]  }|j                  ||   j                  t        j                        |z         |j                  ||   j                  t        j                               |j                  ||   j                  t        j                                t        j                  t        d|      }|i }d|vr| |d<   t        t        |      fi |D ]9  } || |||||	|
||||||||||||       |dt        |      t        |      z  z
  z  }; | S )Nr   r   Tr]   rl   r   )r   r    typedList
empty_listtypesru   r   rz   r   r|   r#   rr   r   r   r   )r   r   r   r   r   r+   r   r   r   r,   r-   r/   r   r   r   r^   r   r   r0   r   r1   r2   r3   r4   r   r   r5   s                              r   !optimize_layout_aligned_euclideanr     s   * !

"
"1
%CE!&!1!1!<!<U[[=P=PQTSTQT=U!V$)KK$4$4$?$?CaC %! !;;++66u{{7J7J3Q37OP3u: M"))a ''

36JJ	
 	&,,&q)00<	
 	##$5a$8$?$?

$KLM **7K 		!#*{	)%//Y/ E"&) '	
, a5?(B!CD/E2 r
   )F)	r   r   rc   FFFNNF)
gP);?gV?r   g{Gzt?r   rc   TFNF)r    numpyr#   	tqdm.autor   umap.distances	distancesdist
umap.utilsr   rr   r	   r   ru   intpr   rT   r\   ra   r`   boolrb   r   r   	euclideanr   r   r   r   r   r   r
   r   <module>r      s       #  * 
++%%##{{[[		

*{|?B .8UZZ+dU. * 7Aejj+dT7 3
:T :$ 'ME`O?z ..%DNEl ..+K\TB 
'Lr
   