
    WiB                        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 dl	m
Z
mZmZmZ d dlmZmZmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlZd dlZd dl Z d Z!d-dZ"d Z# e#       \  Z$Z% e       jM                  e$      Z$e$jO                         Z(ejR                  dge(d <   ejR                  ejR                  ge(d<   d Z*d Z+ejX                  j[                  d      d        Z.d Z/d Z0d.dZ1d Z2d Z3d Z4d Z5d Z6d Z7d  Z8d! Z9d" Z:d# Z;d$ Z<d% Z=d& Z>d' Z?d( Z@d) ZAd* ZBejX                  j[                  d+      d,        ZCy)/    N)stats)sparse)distance)check_estimator)HDBSCANBranchDetectordetect_branches_in_clustersapproximate_predict_branch)if_matplotlibif_networkx	if_pandas)check_random_stateshuffle)
make_blobs)StandardScaler)mkdtempwrapsc                 .     t                fd       }|S )zJTest decorator that skips test if networkx or pygraphviz is not installed.c                  n    	 dd l }dd l} | i |S # t        $ r t        j                  d       Y y w xY w)Nr   z%NetworkX or pygraphviz not available.)networkx
pygraphvizImportErrorpytestskip)argskwargsr   r   funcs       g/home/sietch6/trending-topics-pipeline/venv/lib/python3.12/site-packages/hdbscan/tests/test_branches.pyrun_testzif_pygraphviz.<locals>.run_test!   s@    	) (((  	AKK?@	As    44r   )r   r    s   ` r   if_pygraphvizr!      s"     4[) ) O    c                 v   t        | t        j                        r| dz  }| |z
  }n	 | \  }}t	        |      }t        j                  t        j                  t
        j                  dz  t
        j                  |            }t        j                  t        j                  t
        j                  dz  t
        j                  |            dz
  }	t        j                  t        j                  dt
        j                  |            }
dt        j                  t        j                  dt
        j                  |            z
  }t        j                  t        j                  ||
      t        j                  |	|      g      j                  }t        j                  t        j                  |t
        j                        t        j                   |t
        j                        g      }|rt#        |||      \  }}| ||j%                  ||j&                        z  }||fS # t        $ r}t        d      |d }~ww xY w)	N   z8`n_samples` can be either an int or a two-element tuple.      r   )dtype)random_state)scalesize)
isinstancenumbersIntegral
ValueErrorr   npcoslinspacepisinvstackappendThstackzerosintponesutil_shufflenormalshape)	n_samplesr   noiser(   n_samples_outn_samples_ine	generatorouter_circ_xouter_circ_yinner_circ_xinner_circ_yXys                 r   make_branchesrJ   .   s   )W--.!Q =0	*3'M< #<0I66"++beeaiFGL66"++beeaiFG!KL66"++a=>Lrvvbkk!RUULABBL
		IIlL1IIlL1	
	
 a  			HH]"''2GGL0	
	A Aqy91	YE88a4K?  	J	s   H 	H8'H33H8c                     t        dddgdd      \  } }t        ddd	      \  }}t        j                  |j                  d
   d      }t        j
                  j                  d       t        j
                  j                  ddd      }t        j                  dd      }t        j                  | ||f      t        j                  |||f      fS )N2   )g      g      @)       @      g?r$   )r>   centerscluster_stdr(      gQ?)r>   r?   r(   r   r%                  @)rL   r%   )
r   rJ   r/   fullr=   randomseeduniformr4   concatenate)blobsyBlobsmoons_yMoonsr?   yNoises          r   generate_noisy_datara   W   s    ,	ME6 s$QGHE1WWU[[^Q'FIINN1IIdC1EWWR_F
		5%'(
/0 r"   r&   rR   c                     t        dd      j                  t              } | j                  }| j                  J |j
                  dk(  sJ |j                  j                  d   t        j                  d   k(  sJ |j                  j                  d   t        j                  d   k(  sJ |j                  j                  d   | j                  k(  s| j                  sJ |j                  J y)z=Check that the flag generates internal branch_detection_data.rR   Tmin_cluster_sizebranch_detection_dataNr   r&   )r   fitrH   branch_detection_data_minimum_spanning_tree_
all_finitecore_distancesr=   	neighborsmin_samplesrd   finite_indexcbranch_datas     r   test_branch_detection_datarq   s   s    $?CCAFA**K##///!!T)))%%++A.!''!*<<<  &&q)QWWQZ777  &&q)Q]]:a>P>PPP##+++r"   c                     t        dd      j                  t              } | j                  }| j                  J |j
                  dk(  sJ |j                  j                  d   t        j                  d   dz
  k(  sJ |j                  j                  d   t        j                  d   dz
  k(  sJ |j                  j                  d   | j                  k(  s| j                  sJ |j                  J y)	z=Check internal branch_detection_data recognizes missing data.rR   Trc   NFr   r%   r&   )r   rf   X_missing_datarg   rh   ri   rj   r=   rH   rk   rl   rd   rm   rn   s     r   'test_branch_detection_data_with_missingrt      s    $?CCNSA**K##///!!U***%%++A.!''!*q.@@@  &&q)QWWQZ!^;;;  &&q)Q]]:a>P>PPP##///r"   z)Unreachable code-branch cannot be tested.)reasonc                  d   t        j                  d      5 } t        ddd      j                  t              }dt        | d   j                        v sJ |j                  J t        j                  t              5  |j                   ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)	z$Check warning on unsupported metric.TrecordrR   cosine)rd   re   metricz1Metric cosine not supported for branch detection!rU   N)warningscatch_warningsr   rf   rH   strmessagerh   r   raisesAttributeErrorre   )wro   s     r   /test_branch_detection_data_with_non_tree_metricr      s     
	 	 	- 
$ d8

#a& 	
 Cc!B%--FXXXX''333]]>* 	$##	$
$ 
$	$ 	$
$ 
$s$   A%B&<B	B&B#	B&&B/c                     t        j                  t        j                  t                    } t	        j
                  d      5 }t        ddd      j                  |       }dt        |d   j                        v sJ 	 ddd       | t        j                  |       z  } t        j                  | j                         d	      }d
| | |k\  <   t        j                   |       } | j#                          t	        j
                  d      5 }t        ddd      j                  |       }dt        |d   j                        v sJ 	 ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)z$Check warning on unsupported inputs.Trw   rR   precomputed)rd   rz   re   zFBranch detection for non-vector space inputs is not (yet) implemented.rU   NrL           )r   
squareformpdistrH   r{   r|   r   rf   r}   r~   r/   maxr   scoreatpercentileflattenr   
csr_matrixeliminate_zeros)Dr   ro   	thresholds       r   1test_branch_detection_data_with_unsupported_inputr      sE    	HNN1-.A		 	 	- 
}D

#a& 	
 U1R5==!"	
"
 NA''		R8IAa9n!A		 	 	- 
}D

#a& 	
 U1R5==!"	
"
 

 

 
s   :E	:E	EEc                      t        d      j                  t              } | j                          | j                  J t        j                  t              5  | j                   ddd       y# 1 sw Y   yxY w)zAGenerate branch detection data function does not re-generate MST.rR   rd   N)	r   rf   rH   generate_branch_detection_datarg   r   r   r   rh   )ro   s    r   #test_generate_branch_detection_datar      s_    #''*A$$&##///	~	& !	  ! ! !s   A--A6c                    t        t        j                  | j                              t	        d| j                  v       z
  |k(  sJ t        t        j                  | j
                              t	        d| j
                  v       z
  |k(  sJ | j                  dk(  }| j                  |   dk(  j                         sJ | j                  |   dk(  j                         sJ | j                  |   dk(  j                         sJ | j                  |   dk(  j                         sJ |s4t        | j                        |k(  sJ t        | j                        |k(  sJ t        d | j                  D              ||z
  k\  sJ y)z2Checks branch_detector output for main invariants.rU   r         ?r   c              3   2   K   | ]  }t        |        y wN)len).0pss     r   	<genexpr>z(check_detected_groups.<locals>.<genexpr>   s     82s2w8s   N)r   r/   uniquelabels_intcluster_labels_branch_labels_allbranch_probabilities_probabilities_cluster_probabilities_cluster_points_branch_persistences_sum)ro   
n_clusters
n_branches
overridden
noise_masks        r   check_detected_groupsr      s[   ryy#$s2?';;zIIIBIIa''()Ca6G6G0G,HHJVVbJZ(A-22444##J/36;;===Z(C/44666$$Z0C7<<>>>1$$%3331))*j8888!7!788Z*=TUUUr"   c                     t        dd      j                  t              } t        dd      j                  |       }t	        |d       t        d	d      j                  |       }t	        |       t        dd
      j                  |       }t	        |d       t        d	d
      j                  |       }t	        |       y )NrR   Trc   coreeom)branch_detection_methodcluster_selection_method   r   rV   leaf	   r   rf   rH   r   r   ro   bs     r   test_branch_detectorr      s    $?CCAFA &		c!f  !* &		c!f  ! &		c!f  !* &		c!f  !r"   c                     t        dd      j                  t              } t        d      j                  |       }t	        j
                  |j                  d      \  }}||dk\     dk\  j                         sJ t        |       y )NrR   Trc   r   r   )return_countsr   )	r   rf   rH   r   r/   r   r   r   r   )ro   r   labelscountss       r   test_min_cluster_sizer      sn    $?CCAFA*..q1AYYqyy=NFF6Q;1$))+++!r"   c                      t        dd      j                  t              } t        d      j                  |       }t	        |d       y )NrR   Trc   label_sides_as_branches   r   r   r   s     r   test_label_sides_as_branchesr      s8    $?CCAFAt488;A!*r"   c                      t        dd      j                  t              } t        dd      j                  |       }t	        |d       y)	zSuppresses one branch.rR   Trc   rL   )r   max_cluster_sizer   r   Nr   r   s     r   test_max_cluster_sizer      s:    $?CCAFAtbIMMaPA!*r"   c                      t        j                  t        d      } d| t        dk(  <   d| t        dk(  <   t        dd      j	                  t
              }t        d      j	                  ||       }t        |ddd	       y )
NrU   r   r&   rR   Trc   r   r%   )r   r   r   )r/   	full_likerI   r   rf   rH   r   r   )split_yro   r   s      r   test_override_cluster_labelsr     sh    ll1b!GGAFOGAFO$?CCAFAt488GDA!aDIr"   c                     t         j                  j                  d       t         j                  j                  dd      } t	        dddd      j                  |       }t        ddd	      j                  |      }t        j                  |j                        }t        |      d
k(  sJ t        j                  |j                  dk(        }|dk(  |dk(  z  sJ t        dddd      j                  |      }t        j                  |j                        }t        |      dk(  sJ t        j                  |j                  dk(        dk(  sJ t        dddd      j                  |      }t        j                  |j                        }t        |      dk(  sJ t        j                  |j                  dk(        dk(  sJ y )Nr   rQ   r%   rR   T)rl   rd   allow_single_clusterre   r   r   )rd   r   r      G   H   皙?)rd   r   r   cluster_selection_persistencer&   g4H4H@)rd   r   cluster_selection_epsilonr   )r/   rW   rX   randr   rf   r   r   r   r   r   r   )no_structurero   r   unique_labels	num_noises        r   &test_allow_single_cluster_with_filtersr   
  s   IINN199>>#q)L!"		
 
c,  	 &!'	 
c!f	 
 IIaii(M}"""q..!34IO	R000 	 &!'&)		
 
c!f  IIaii(M}"""66!))Q./1444 	 &"*!		
 
c!f  IIaii(M}"""66!))Q./1444r"   c                     t        dd      j                  t              } t        dd      }t        dd      j                  t              }t        d      j                  t              }|j                          t	        j
                  t              5  t        d       d d d        t	        j
                  t              5  t        d        d d d        t	        j
                  t              5  t        d       d d d        t	        j
                  t              5  t        |       d d d        t	        j
                  t              5  t        |       d d d        t	        j
                  t              5  t        |       d d d        t	        j
                  t              5  t        | d       d d d        t	        j
                  t              5  t        | d       d d d        t	        j
                  t              5  t        | d	       d d d        t	        j
                  t              5  t        | d
       d d d        t	        j
                  t              5  t        | d       d d d        t	        j
                  t              5  t        | d       d d d        t	        j
                  t              5  t        | d       d d d        t	        j
                  t              5  t        | d       d d d        t	        j
                  t              5  t        | d       d d d        y # 1 sw Y   xY w# 1 sw Y   sxY w# 1 sw Y   SxY w# 1 sw Y   3xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   kxY w# 1 sw Y   IxY w# 1 sw Y   'xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   y xY w)NrR   Trc   )rd   gen_min_span_treer   failrU   r   r&   rM   g)r   )r   something_else)r   )r   )	r   rf   rH   r   r   r   r   r	   r.   )ro   c_nofit
c_nobranchc_nomsts       r   test_badargsr   8  s   $?CCAFAqEG!tDHHKJq)--a0G**,	~	& ,#F+,	~	& *#D)*	~	& ,#F+,	z	" -#G,-	~	& 0#J/0	z	" -#G,-	z	" <#A;<	z	" ;#A:;	z	" ;#A:;	z	" =#A<=	z	" @#A?@	z	" K#ATJK	z	" G#AFG	z	" 
#%5	


 
z	" 
#$4	

 
?, ,* *, ,- -0 0- -< <; ;; ;= =@ @K KG G
 


 
s   L3M 0MM
M'7M4$NNN1N( N5O>O-OO(3L= M
MM$'M14M>NNN%(N25N?OOO%(O1c                     t               } t        | dd      j                  t              }t	               j                  |      }t	        d      j                  |      }t        t        |j                              t        d|j                  v       z
  }t        t        |j                              t        d|j                  v       z
  }||k(  sJ y )NrR   T)memoryrl   re   )r   rU   )	r   r   rf   rH   r   r   setr   r   )cachedirro   b1b2	n_groups1	n_groups2s         r   test_cachingr   h  s    yHxQdKOOPQRA				a	 B	T	2	6	6q	9BC

O$s2+;'<<IC

O$s2+;'<<I	!!!r"   c                     t        j                  ddgddgddgddgddgg      } t        d	d
      j                  t              }t               j                  |      }t        j                  t        d	      D cg c]  }|j                  |       c}      }t        j                  t        j                  |      d      }t        j                  |d d df   |d d df   f      }t        j                  t        j                  ||d d f   | z
        dk         t        j                  t        d	      D cg c]  }|j                  |       c}      }t        j                  t        j                  |      d      }t        j                  |d d df   |d d df   f      }t        j                  t        j                  ||d d f   | z
        dk         y c c}w c c}w )NgrS   r   皙gffffff?rN   r   g333333?rR   Trc   r&   )decimalsr   )r/   asarrayr   rf   rH   r   rangeweighted_centroidaroundlexsortr   absweighted_medoid)branch_centersro   r   i	centroidsroundedcordermedoidss           r   test_centroid_medoidsr   r  s   ZZ
c{T3K$sDkJN 	$?CCAFAQA

E!HEqA//2EFIii

9-:GZZA167FFF266)FAI&783>?jjaA1!++A.ABGii

7+a8GZZA167FFF266'&!)$~56<= F
 Bs   :G9G"c                     t        dd      j                  t              } t               j                  |       }|j                  }|d   J |d   J t        |d         dk(  sJ t        |j                        dk(  sJ y )NrR   Trc   r   r&   r%   r$   )r   rf   rH   r   
exemplars_r   )ro   r   branch_exemplarss      r   test_exemplarsr     s    $?CCAFAQA||A&&&A&&&"#q(((q||!!!r"   c                  |   t        ddd      j                  t              } t               j                  |       }t	        |t        j                  ddgg            \  }}}}}}|d   dkD  sJ t        |j                  |d            dkD  sJ t	        |t        j                  dd	gg            \  }}}}}}|d   |d   k(  sJ |d   dk(  sJ |d   d
k(  sJ t	        |t        j                  ddgg            \  }}}}}}|d   dk(  sJ |d   dk(  sJ |d   dk(  sJ |d   dk(  sJ |d   dk(  sJ |d   d
k(  sJ y )NrR   T)rd   re   prediction_datar   r   r   rU   r%   rM   r   r&   rT   )	r   rf   rH   r   r
   r/   arrayr   r   )ro   r   lpclcpblbps           r   test_approximate_predictr    sx   $		c!f  	QA 6aD#;-9PQAq"b"ba52::q%%be,-111 6aD#;-9PQAq"b"bQ42a5==a5A::a5C<< 6aAs8*9MNAq"b"bQ42::a5B;;a5A::Q43;;a5C<<a5C<<r"   c                  ~   t        dd      j                  t              } t               j                  |       }|j                  j                         \  }}|j                  d   t        j                  d   k  sJ |j                  D ]  }|j                           |j                  D ]  }|j                           y )NrR   Trc   r   )	r   rf   rH   r   approximation_graph_to_numpyr=   condensed_trees_linkage_trees_)ro   r   pointsedgests        r   test_trees_numpy_output_formatsr    s    $?CCAFAQA**335MFE<<?aggaj((( 	

 	

r"   c                  j   t        dd      j                  t              } t               j                  |       } t	        |j
                  j                                |j                  D ]  } t	        |j                                 |j                  D ]  } t	        |j                                 y NrR   Trc   )	r   rf   rH   r   r   r	  	to_pandasr  r  ro   r   r  s      r    test_trees_pandas_output_formatsr    s    $?CCAFAQA/Ia$$../1 !	!++ ! !	!++ !r"   c                  j   t        dd      j                  t              } t               j                  |       } t	        |j
                  j                                |j                  D ]  } t	        |j                                 |j                  D ]  } t	        |j                                 y r  )	r   rf   rH   r   r   r	  to_networkxr  r  r  s      r   "test_trees_networkx_output_formatsr    s    $?CCAFAQA3K&&2235 %"AMM"$% %"AMM"$%r"   c                     t        dd      j                  t              } t               j                  |       }|j                  D ]!  } t        |j                        dddd       #  t        j                        ddd	       y )
NrR   Trc   )rgr   Reds)select_clusterslabel_clustersselection_palettecmapFnone)log_sizecolorbarr   )r   rf   rH   r   r  r   plotr  s      r   test_condensed_tree_plotr%    sy    $?CCAFAQA 
aff -		

 M!&&4%fEr"   c                     t        dd      j                  t              } t               j                  |       }|j                  D ]>  } t        |j                        d        t        |j                        dddd	d
       @ y )NrR   Trc   r  )r   Flastp
   r!  )vary_line_widthtruncate_moder  r   r#  )r   rf   rH   r   r  r   r$  r  s      r   test_single_linkage_tree_plotr+    sv    $?CCAFAQA 
aff6*aff!!	

r"   c                  0   t        dd      j                  t              } t               j                  |       }|j                  } t        |j                        t                t        t        |j                              dddg        t        t        |j                              t        d d df   	        t        t        |j                              d
d        t        t        |j                              |j                  d
   d       y )NrR   Trc   )	positionsxrI   )
node_colorfeature_namesr   )r/  
centrality)
edge_color
node_alpha)	r   rf   rH   r   r	  r   r$  r!   _edges)ro   r   r  s      r   test_approximation_graph_plotr5    s    $?CCAFAQA	AM!&&A&(M-'(CSzR(M-'(AadG<(M-'(LQO(M-'(88L)ar"   z(need to refactor to meet newer standardsc                  "    t        t               y r   )r   r    r"   r   )test_branch_detector_is_sklearn_estimatorr8    s
    N#r"   )d   TNN)r$   r   F)Dnumpyr/   scipyr   r   scipy.spatialr   sklearn.utils.estimator_checksr   hdbscanr   r   r	   r
   hdbscan.tests.test_hdbscanr   r   r   sklearn.utilsr   r   r;   sklearn.datasetsr   sklearn.preprocessingr   tempfiler   	functoolsr   r,   r   r{   r!   rJ   ra   rH   rI   fit_transformcopyrs   nanrq   rt   markr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r%  r+  r5  r8  r7  r"   r   <module>rI     sk      " :   F ' 0      &R$ 1""1%VVQKq VVRVV$q 
	,	0 DE$ F$
:!V".++J+5\*
`">&"<!%
F

 CD$ E$r"   