code: def run(self, eps=1e-4, kill=True, max_steps=50, verbose=False):
          r
          old_distance = np.finfo(np.float64).max
          new_distance = np.finfo(np.float64).max
  
          if verbose:
              print('Starting hierarchical clustering with %d components.' % len(self.g.components))
          converged = False
          for step in range(1, max_steps + 1):
              self._cleanup(kill, verbose)
              self._regroup()
              self._refit()
  
              new_distance = self._distance()
              assert new_distance >= 0, 'Found non-positive distance %d' % new_distance
  
              if verbose:
                  print('Distance in step %d: %g' % (step, new_distance))
              if new_distance == old_distance:
                  converged = True
                  if verbose:
                      print('Exact minimum found after %d steps' % step)
                  break
  
              rel_change = (old_distance - new_distance) / old_distance
              assert not (rel_change < -1e-13), 'distance increased'
  
              if rel_change < eps and not converged and step > 0:
                  converged = True
                  if verbose and new_distance != old_distance:
                      print('Close enough to local minimum after %d steps' % step)
                  break
  
              # save distance for comparison in next step
              old_distance = new_distance
  
          self._cleanup(kill, verbose)
          if verbose:
              print('%d components remain.' % len(self.g.components))
  
          if converged:
              return step
docs: r"""Perform the clustering on the input components updating the initial
          guess. The result is available in the member ``self.g``.
  
          Return the number of iterations at convergence, or None.
  
          :param eps:
  
              If relative change of distance between current and last step falls below ``eps``,
              declare convergence:
  
              .. math::
                  0 < \frac{d^t - d^{t-1}}{d^t} < \varepsilon
  
          :param kill:
  
               If a component is assigned zero weight (no input components), it is removed.
  
          :param max_steps:
  
               Perform a maximum number of update steps.
  
          :param verbose:
  
               Output information on progress of algorithm.