docstr: Compute best cost change for all the possible swaps.
  
  Parameters
  ----------
  D : {array-like, sparse matrix}, shape=(n_samples, n_samples)
      Distance matrix.
  
  medoid_idxs : {array-like}, shape = (n_clusters)
                Indices of medoid points
  
  not_medoid_idxs : {array-like}, shape = (n_samples - n_clusters)
                    Indices of non-medoid points
  
  Djs : {array-like}, shape = (n_samples)
        Distances of each point to closest medoid
  
  Ejs : {array-like}, shape = (n_samples)
        Distances of each point to next-closest medoid
  
  n_clusters : integer
               Number of clusters/medoids
  
  
  Returns
  -------
  Sum of sample distances to closest cluster centers.
docstr_tok: ["Compute","best","cost","change","for","all","the","possible","swaps",".","Parameters","--","--","--","--","--","D",":","{","array-like",",","sparse","matrix","}",",","shape=","(","n_samples",",","n_samples",")","Distance","matrix",".","medoid_idxs",":","{","array-like","}",",","shape","=","(","n_clusters",")","Indices","of","medoid","points","not_medoid_idxs",":","{","array-like","}",",","shape","=","(","n_samples","-","n_clusters",")","Indices","of","non-medoid","points","Djs",":","{","array-like","}",",","shape","=","(","n_samples",")","Distances","of","each","point","to","closest","medoid","Ejs",":","{","array-like","}",",","shape","=","(","n_samples",")","Distances","of","each","point","to","next-closest","medoid","n_clusters",":","integer","Number","of","clusters\/medoids","Returns","--","--","--","-","Sum","of","sample","distances","to","closest","cluster","centers","."]
code: def _compute_optimal_swap(
      self, D, medoid_idxs, not_medoid_idxs, Djs, Ejs, n_clusters
  ):
      """Compute best cost change for all the possible swaps.
  
      Parameters
      ----------
      D : {array-like, sparse matrix}, shape=(n_samples, n_samples)
          Distance matrix.
  
      medoid_idxs : {array-like}, shape = (n_clusters)
                    Indices of medoid points
  
      not_medoid_idxs : {array-like}, shape = (n_samples - n_clusters)
                        Indices of non-medoid points
  
      Djs : {array-like}, shape = (n_samples)
            Distances of each point to closest medoid
  
      Ejs : {array-like}, shape = (n_samples)
            Distances of each point to next-closest medoid
  
      n_clusters : integer
                   Number of clusters/medoids
  
  
      Returns
      -------
      Sum of sample distances to closest cluster centers."""
  
      # Initialize best cost change and the associated swap couple.
      best_swap = (1, 1, 0.0)
      # print("Number of samples:", len(D))
      cur_cost_change = 0.0
      not_medoid_shape = len(not_medoid_idxs)
      cluster_i_bool, not_cluster_i_bool, second_best_medoid = (
          None,
          None,
          None,
      )
      not_second_best_medoid = None
  
      i, j, h = 0, 0, 0
      id_i, id_j, id_h = 0, 0, 0
      # Compute the change in cost for each swap.
      for h in range(not_medoid_shape):
          # id of the potential new medoid.
          id_h = not_medoid_idxs[h]
          # print("\n-------------------------\nConsidering the potential data point ", id_h)
          for i in range(n_clusters):
              # id of the medoid we want to replace.
              id_i = medoid_idxs[i]
              # print("\nConsidering the medoid numbered ",id_i)
              cur_cost_change = 0.0
              # compute for all not-selected points the change in cost
              for j in range(not_medoid_shape):
                  id_j = not_medoid_idxs[j]
                  # print("\nFor the not selected point ", id_j)
                  cluster_i_bool = D[id_i, id_j] == Djs[id_j]
                  # print("\nIs the current point ",id_j," in same cluster as ", id_i,"? : ", cluster_i_bool)
  
                  second_best_medoid = D[id_h, id_j] < Ejs[id_j]
                  # print("\nIs the current point ",id_j," 's distance from the potential medoid swap point'", id_h,"less than the second closest medoid? :", second_best_medoid)
  
                  if cluster_i_bool & second_best_medoid:
                      cur_cost_change += D[id_j, id_h] - Djs[id_j]
                  elif cluster_i_bool & (not second_best_medoid):
                      cur_cost_change += Ejs[id_j] - Djs[id_j]
                  elif (not cluster_i_bool) & (
                      D[id_j, id_h] < Djs[id_j]
                  ):
                      cur_cost_change += D[id_j, id_h] - Djs[id_j]
                  # print("\nCost change:", cur_cost_change)
  
              # same for i
              second_best_medoid = D[id_h, id_i] < Ejs[id_i]
              if second_best_medoid:
                  # print("\nCost change increases by distance to swap")
                  cur_cost_change += D[id_i, id_h]
              else:
                  # print("\nCost changes increases by distance to next medoid")
                  cur_cost_change += Ejs[id_i]
  
              if cur_cost_change < best_swap[2]:
                  best_swap = (id_i, id_h, cur_cost_change)
                  # print("Swap current medoid ", id_i, " with potential medoid ", id_h, " at the cost change of ",cur_cost_change)
  
      # If one of the swap decrease the objective, return that swap.
      if best_swap[2] < 0:
          return best_swap
      else:
          # print("No good swap")
          return None
  
imports: import warnings
  import numpy
  from sklearn.base import BaseEstimator, ClusterMixin
  from sklearn.exceptions import ConvergenceWarning
  from sklearn.metrics.pairwise import pairwise_distances, pairwise_distances_argmin
  from sklearn.utils import check_array
  from sklearn.utils.validation import check_is_fitted
label_desc: Use image node_id 7 for calling the KMedoids obj's underlying member method code with example usage: obj._compute_optimal_swap(D, medoid_idxs, not_medoid_idxs, Djs, Ejs, n_clusters) and returns: best_swap, None