code: def kmeans_torch(
      X: torch.Tensor,
      num_clusters: int,
      threshold: float = 1e-4,
      iter_limit: int = 15,
      random_state: int = 0,
      device: torch.device = torch.device("cpu"),
  ) -> torch.Tensor:
      """
      Run k-means algorithm on the given set of spectral embeddings in X. The threshold
      and iter_limit variables are set to show the best performance on speaker diarization
      tasks. The overall implementation of k-means algorithm is inspired by the k-means
      algorithm implemented in https://github.com/scikit-learn/scikit-learn.
  
      References:
          Arthur, David, and Sergei Vassilvitskii. k-means++: The advantages of careful
          seeding. Proceedings of the eighteenth annual ACM-SIAM symposium on Discrete
          algorithms, Society for Industrial and Applied Mathematics (2007).
  
      Args:
          X (Tensor):
              Cosine similarity matrix calculated from speaker embeddings
          num_clusters (int):
              The estimated number of speakers.
          threshold (float):
              This threshold limits the change of center values. If the square of
              the center shift values are bigger than this threshold, the iteration stops.
          iter_limit (int):
              The maximum number of iterations that is allowed by the k-means algorithm.
          device (torch.device):
              Torch device variable
  
      Returns:
          selected_cluster_indices (Tensor):
              The assigned cluster labels from the k-means clustering.
      """
      # Convert tensor type to float
      X = X.float().to(device)
      input_size = X.shape[0]
  
      # Initialize the cluster centers with kmeans_plusplus algorithm.
      plusplus_init_states = kmeans_plusplus_torch(
          X,
          n_clusters=num_clusters,
          random_state=random_state,
          device=device,
      )
      centers = plusplus_init_states[0]
  
      selected_cluster_indices = torch.zeros(input_size).long()
  
      for iter_count in range(iter_limit):
          euc_dist = getEuclideanDistance(X, centers, device=device)
  
          if len(euc_dist.shape) <= 1:
              break
          else:
              selected_cluster_indices = torch.argmin(euc_dist, dim=1)
  
          center_inits = centers.clone()
  
          for index in range(num_clusters):
              selected_cluster = (
                  torch.nonzero(selected_cluster_indices == index)
                  .squeeze()
                  .to(device)
              )
              chosen_indices = torch.index_select(
                  X, 0, selected_cluster
              )
  
              if chosen_indices.shape[0] == 0:
                  chosen_indices = X[torch.randint(len(X), (1,))]
  
              centers[index] = chosen_indices.mean(dim=0)
  
          # Calculate the delta from center_inits to centers
          center_delta_pow = torch.pow((centers - center_inits), 2)
          center_shift_pow = torch.pow(
              torch.sum(torch.sqrt(torch.sum(center_delta_pow, dim=1))),
              2,
          )
  
          # If the cluster centers are not changing significantly, stop the loop.
          if center_shift_pow < threshold:
              break
  
      return selected_cluster_indices
  
imports: from typing import Dict, List, Tuple
  import torch
  from torch.linalg import eigh, eigvalsh
label_desc: Use image node_id 5 for calling a global function with example usage: kmeans_torch(X, num_clusters, threshold, iter_limit, random_state, device) and returns: selected_cluster_indices