          logger.debug("free_ram: %sMB, linkage_required: %sMB, vector_required: %sMB",
                       int(free_ram), int(linkage_required), int(vector_required))
  
          if linkage_required < free_ram:
              logger.verbose("Using linkage method")
              retval = False
          elif vector_required < free_ram:
              logger.warning("Not enough RAM to perform linkage clustering. Using vector "
                             "clustering. This will be significantly slower. Free RAM: %sMB. "
                             "Required for linkage method: %sMB",
 
</s> remove         linkage_required = (((item_count ** 2) * np_float) / 1.8) / divider
        vector_required = ((item_count * dims) * np_float) / divider
 </s> add         linkage_required = (((self._num_predictions ** 2) * np_float) / 1.8) / divider
        vector_required = ((self._num_predictions * dims) * np_float) / divider </s> remove                                 "the size of  your dataset. Free RAM: {}MB. "
                                "Required RAM: {}MB".format(int(free_ram), int(vector_required)))
 </s> add                                 f"the size of  your dataset. Free RAM: {int(free_ram)}MB. "
                                f"Required RAM: {int(vector_required)}MB") </s> remove     def _seriation(self, tree, points, current_index):
 </s> add     def _do_linkage(self,
                    predictions: np.ndarray,
                    method: Literal["single", "centroid", "median", "ward"]) -> np.ndarray:
        """ Use FastCluster to perform vector or standard linkage

        Parameters
        ----------
        predictions: :class:`numpy.ndarray`
            A stacked matrix of vgg_face2 predictions of the shape (`N`, `D`) where `N` is the
            number of observations and `D` are the number of dimensions.
        method: ['single','centroid','median','ward']
            The clustering method to use.

        Returns
        -------
        :class:`numpy.ndarray`
            The [`num_predictions`, 4] linkage vector
        """
        dims = predictions.shape[-1]
        if self._use_vector_linkage(dims):
            retval = linkage_vector(predictions, method=method)
        else:
            retval = linkage(predictions, method=method, preserve_input=False)
        logger.debug("Linkage shape: %s", retval.shape)
        return retval

    def _process_leaf_node(self,
                           current_index: int,
                           current_bin: int) -> List[Tuple[int, int]]:
        """ Process the output when we have hit a leaf node """
        if not self._should_output_bins:
            return [(current_index, 0)]

        if current_bin not in self._bins:
            next_val = 0 if not self._bins else max(self._bins.values()) + 1
            self._bins[current_bin] = next_val
        return [(current_index, self._bins[current_bin])]

    def _get_bin(self,
                 tree: np.ndarray,
                 points: int,
                 current_index: int,
                 current_bin: int) -> int:
        """ Obtain the bin that we are currently in.

        If we are not currently below the threshold for binning, get a new bin ID from the integer
        iterator.

        Parameters
        ----------
        tree: numpy.ndarray
           A hierarchical tree (dendrogram)
        points: int
            The number of points given to the clustering process
        current_index: int
            The position in the tree for the recursive traversal
        current_bin int, optional
            The ID for the bin we are currently in. Only used when binning is enabled

        Returns
        -------
        int
            The current bin ID for the node
        """
        if tree[current_index - points, 2] >= self._threshold:
            current_bin = next(self._iterator)
            logger.debug("Creating new bin ID: %s", current_bin)
        return current_bin

    def _seriation(self,
                   tree: np.ndarray,
                   points: int,
                   current_index: int,
                   current_bin: int = 0) -> List[Tuple[int, int]]: </s> remove         result_linkage = func(predictions, **kwargs)
        result_order = self._seriation(result_linkage,
                                       num_predictions,
                                       num_predictions + num_predictions - 2)
        return result_order
 </s> add     @classmethod
    def _integer_iterator(cls) -> Generator[int, None, None]:
        """ Iterator that just yields consecutive integers """
        i = -1
        while True:
            i += 1
            yield i </s> remove         kwargs = dict(method=method)
        if self._use_vector_linkage(num_predictions, dims):
            func = linkage_vector
        else:
            kwargs["preserve_input"] = False
            func = linkage
 </s> add         self._result_linkage = self._do_linkage(predictions, method)
        logger.debug("Initialized %s", self.__class__.__name__)
            logger.verbose("Using linkage method")  # type:ignore
          logger.debug("free_ram: %sMB, linkage_required: %sMB, vector_required: %sMB",
                       int(free_ram), int(linkage_required), int(vector_required))
  
          if linkage_required < free_ram:
            logger.verbose("Using linkage method")  # type:ignore
              retval = False
          elif vector_required < free_ram:
              logger.warning("Not enough RAM to perform linkage clustering. Using vector "
                             "clustering. This will be significantly slower. Free RAM: %sMB. "
                             "Required for linkage method: %sMB",
keep keep keep keep replace keep keep keep keep keep
 Overhaul sort:
  - Standardize image data reading and writing
  - Optimize loading (just one pass required)
  - Make all sort groups binnable (to greater or lesser results)
  - Add sort by pitch
  - Deprecate multiple options
  - linting, docs + locales 
plugins/extract/recognition/vgg_face2_keras.py