docs: public PointerHierarchyRepresentationResult run(Database db, Relation<O> relation) {
      if(SingleLinkage.class.isInstance(linkage)) {
        LOG.verbose("Notice: SLINK is a much faster algorithm for single-linkage clustering!");
      }
      final DBIDs ids = relation.getDBIDs();
      final int size = ids.size();
      DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction());
  
      // Compute the initial (lower triangular) distance matrix.
      MatrixParadigm mat = new MatrixParadigm(ids);
      initializeDistanceMatrix(mat, dq, linkage);
  
      // Initialize space for result:
      PointerHierarchyRepresentationBuilder builder = new PointerHierarchyRepresentationBuilder(ids, dq.getDistanceFunction().isSquared());
  
      // Repeat until everything merged into 1 cluster
      FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Agglomerative clustering", size - 1, LOG) : null;
      // Use end to shrink the matrix virtually as the tailing objects disappear
      DBIDArrayIter ix = mat.ix;
      for(int i = 1, end = size; i < size; i++) {
        end = shrinkActiveSet(ix, builder, end, //
            findMerge(end, mat, builder));
        LOG.incrementProcessed(prog);
      }
      LOG.ensureCompleted(prog);
  
      return builder.complete();
    }