
    3j                    H    S SK Jr  S SKrS SKJrJr  S SKJr   " S S5      rg)    )annotationsN)KORNIA_CHECKKORNIA_CHECK_SHAPEeuclidean_distancec                      \ rS rSrSr   S           SS jjr\SS j5       r\SS j5       rSS jr	SS jr
SS	 jrSS
 jrSrg)KMeans   a  Implements the kmeans clustering algorithm with euclidean distance as similarity measure.

Args:
    num_clusters: number of clusters the data has to be assigned to
    cluster_centers: torch.Tensor of starting cluster centres can be passed instead of num_clusters
    tolerance: float value. the algorithm terminates if the shift in centers is less than tolerance
    max_iterations: number of iterations to run the algorithm for
    seed: number to set torch manual seed for reproducibility

Example:
    >>> kmeans = kornia.contrib.KMeans(3, None, 10e-4, 100, 0)
    >>> kmeans.fit(torch.rand((1000, 5)))
    >>> predictions = kmeans.predict(torch.rand((10, 5)))

Nc                    [        US:g  S5        Ub  [        USS/5        Xl        X l        X0l        X@l        S U l        S U l        Ub  [        R                  " U5        g g )Nr   znum_clusters can't be 0CD)
r   r   num_clusters_cluster_centers	tolerancemax_iterations_final_cluster_assignments_final_cluster_centerstorchmanual_seed)selfr   cluster_centersr   r   seeds         O/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/contrib/kmeans.py__init__KMeans.__init__-   sj     	\Q&(AB &c
;( /",?C';?#d#     c                    [        U R                  [        R                  5      (       a  U R                  $ [        U R                  [        R                  5      (       a  U R                  $ [        S5      e)a  Return the current cluster centers.

Returns:
    A tensor with shape :math:`(C, D)`:
    - ``C`` is the number of clusters.
    - ``D`` is the feature dimension of each sample.

    If :meth:`fit` has already been called, this returns the learned
    final centers. Otherwise, it returns the initialization provided
    during construction.

Raises:
    TypeError: If no initial centers were provided and ``fit`` has not been run.
#Model has not been fit to a dataset)
isinstancer   r   Tensorr   	TypeErrorr   s    r   r   KMeans.cluster_centersF   sV      d115<<@@...d++U\\::(((ABBr   c                    [        U R                  [        R                  5      (       a  U R                  $ [	        S5      e)a9  Return cluster labels assigned during the most recent ``fit`` call.

Returns:
    A 1D tensor with shape :math:`(N,)`, where ``N`` is the number of
    samples given to :meth:`fit`. Each value is the cluster index
    assigned to the corresponding sample.

Raises:
    TypeError: If ``fit`` has not been run yet.
r   )r   r   r   r    r!   r"   s    r   cluster_assignmentsKMeans.cluster_assignments]   s3     d55u||DD222ABBr   c                j    [        U5      n[        R                  " X1R                  S9nUSU nX   nU$ )zChooses num_cluster points from X as the initial cluster centers.

Args:
    X: 2D input torch.Tensor to be clustered
    num_clusters: number of desired cluster centers

Returns:
    2D torch.Tensor with num_cluster rows

deviceN)lenr   randpermr)   )r   Xr   num_samplespermidxinitial_states          r   _initialise_cluster_centers"KMeans._initialise_cluster_centersn   s8     q6~~k((;=L!r   c                :    USS2SS4   nUS   n[        X45      nU$ )zCompute pairwise squared distance between 2 sets of vectors.

Args:
    data1: 2D torch.Tensor of shape N, D
    data2: 2D torch.Tensor of shape C, D

Returns:
    2D torch.Tensor of shape N, C

N.)N.r   )r   data1data2ABdistances         r   _pairwise_euclidean_distance#KMeans._pairwise_euclidean_distance   s-     !T3,)%a+r   c           	     >   [        USS/5        U R                  c!  U R                  XR                  5      U l        O][	        UR
                  S   U R                  R
                  S   :H  SUR
                  S    SU R                  R
                  S    35        U R                  nSnSn U R                  X5      nUR                  S5      nUR                  5       n[        U R                  5       H  n[        R                  " Xg:H  5      R                  5       n[        R                  " USU5      nUR
                  S   S:X  a,  U[        R                  " [        U5      S	UR                   S
9   nUR#                  SS9X''   M     [        R$                  " [        R&                  " [        R$                  " X#-
  S-  SS95      5      n	US-   nU R(                  b  U	S-  U R(                  :  a  O#U R*                  S:w  a  X@R*                  :  a  OGMg  X`l        X l        g)zFit iterative KMeans clustering till a threshold for shift in cluster centers or a maximum no of iterations
have reached.

Args:
    X: 2D input torch.Tensor to be clustered

Nr   N   zPDimensions at position 1 of X and cluster_centers do not match.                  != r   )r=   r(   )dim   )r   r   r1   r   r   shaper9   argmincloneranger   nonzerosqueezeindex_selectrandintr*   r)   meansumsqrtr   r   r   r   )
r   r,   current_centersprevious_centers	iterationr8   cluster_assignmentindexselectedcenter_shifts
             r   fit
KMeans.fit   s    	1sCj)  ($($D$DQHYHY$ZD! 
d3399!<<D!6!6!<!<Q!? @B //04	%)%F%Fq%ZH!)!4.446t001 ==);)DEMMO --aH= >>!$) s1vtAHH!MNH)11)=& 2 !99UZZ		?;]bc:cij0k%lmL!AI~~)lAo.N""a'I9L9L,L5 8 +='&5#r   c                   [        UR                  S   U R                  R                  S   :H  SUR                  S    SU R                  R                  S    35        U R                  XR                  5      nUR	                  S5      nU$ )zFind the cluster center closest to each point in x.

Args:
    x: 2D torch.Tensor

Returns:
    1D torch.Tensor containing cluster id assigned to each data point in x

r=   zPDimensions at position 1 of x and cluster_centers do not match.                 r>   r?   )r   rB   r   r9   rC   )r   xr8   rP   s       r   predictKMeans.predict   s     	GGAJ$..44Q77D!5!5!;!;A!> ?A	
 44Q8L8LM%__R0!!r   )r   r   r   r   r   r   )gMbP?r   N)r   intr   ztorch.Tensor | Noner   floatr   rZ   r   z
int | NonereturnNone)r\   torch.Tensor)r,   r^   r   rZ   r\   r^   )r4   r^   r5   r^   r\   r^   )r,   r^   r\   r]   )rW   r^   r\   r^   )__name__
__module____qualname____firstlineno____doc__r   propertyr   r%   r1   r9   rT   rX   __static_attributes__ r   r   r	   r	      s    ( !$$ -$ 	$
 $ $ 
$2 C C, C C "$86t"r   r	   )	
__future__r   r   kornia.core.checkr   r   kornia.geometry.linalgr   r	   rf   r   r   <module>rj      s   ( #  > 5B" B"r   