class_docstr: Density-based centroids initialisation.
  
  This initialisation means that we build a cumulative distribution
  function(CDF), then linearly space y-axis of this function then find the
  corresponding x-axis points.
  
  In order to simplify the implementation, here is
  a plan how it is achieved:
  1. Calculate CDF values at points spaced linearly between weight_min and
  weight_max(e.g. 20 points)
  2. Build an array of values linearly spaced between 0 and 1(probability)
  3. Go through the second array and find segment of CDF that contains this
  y-axis value, \hat{y}
  4. interpolate linearly between those two points, get a line equation y=ax+b
  5. solve equation \hat{y}=ax+b for x. The found x value is a new cluster
  centroid.
class_docstr_tok: ["Density-based","centroids","initialisation",".","This","initialisation","means","that","we","build","a","cumulative","distribution","function","(","CDF",")",",","then","linearly","space","y-axis","of","this","function","then","find","the","corresponding","x-axis","points",".","In","order","to","simplify","the","implementation",",","here","is","a","plan","how","it","is","achieved",":","1",".","Calculate","CDF","values","at","points","spaced","linearly","between","weight_min","and","weight_max","(","e.g",".","20","points",")","2",".","Build","an","array","of","values","linearly","spaced","between","0","and","1","(","probability",")","3",".","Go","through","the","second","array","and","find","segment","of","CDF","that","contains","this","y-axis","value",",","\\hat","{","y","}","4.","interpolate","linearly","between","those","two","points",",","get","a","line","equation","y=ax+b","5.","solve","equation","\\hat","{","y","}","=ax+b","for","x",".","The","found","x","value","is","a","new","cluster","centroid","."]
code: def _calculate_centroids_for_interval(
      self, weight_interval, number_of_clusters_for_interval
  ):
      if tf.math.less_equal(number_of_clusters_for_interval, 0):
          # Return an empty array of centroids
          return tf.constant([])
  
      # Get the limits of the weight interval
      weights_min = tf.reduce_min(weight_interval)
      weights_max = tf.reduce_max(weight_interval)
  
      # Calculate the gap to put at either side of the given interval
      weights_gap = (
          0.01
          if not self.preserve_sparsity
          else tf.minimum(
              0.01,
              tf.minimum(
                  tf.math.abs(weights_min), tf.math.abs(weights_max)
              )
              / 2,
          )
      )
  
      # Calculating the interpolation nodes for the given weights.
      # A gap is introduced on either side to guarantee that the CDF will have
      # 0 and 1 as the first and last value respectively.
      # The value 30 is a guess, we just need a sufficiently large number here
      # since we are going to interpolate values linearly anyway and the initial
      # guess will drift away. For these reasons we do not really
      # care about the granularity of the lookup
      cdf_x_grid = tf.linspace(
          weights_min - weights_gap, weights_max + weights_gap, 30
      )
  
      # Calculate the centroids within the given interval
      cdf = TFCumulativeDistributionFunction(weights=weight_interval)
      cdf_values = k.map_fn(cdf.get_cdf_value, cdf_x_grid)
      probability_space = tf.linspace(
          0 + 0.01, 1, number_of_clusters_for_interval
      )
      matching_indices = tf.searchsorted(
          sorted_sequence=cdf_values,
          values=probability_space,
          side="right",
      )
  
      centroids = self._get_centroids(
          cdf_x_grid, cdf_values, matching_indices
      )
      cluster_centroids = tf.reshape(
          centroids, (number_of_clusters_for_interval,)
      )
  
      return cluster_centroids
  
imports: import abc
  import six
  import tensorflow
  from tensorflow.python.ops import clustering_ops
  from tensorflow_model_optimization.python.core.clustering.keras import cluster_config
label_desc: Use image node_id 2 for calling the DensityBasedCentroidsInitialisation obj's underlying member method code with example usage: obj._calculate_centroids_for_interval(weight_interval, number_of_clusters_for_interval) and returns: cluster_centroids, tf