docs: public OutlierResult run(Database database, Relation<O> relation) {
      StepProgress stepprog = LOG.isVerbose() ? new StepProgress("COF", 3) : null;
      DistanceQuery<O> dq = database.getDistanceQuery(relation, getDistanceFunction());
      LOG.beginStep(stepprog, 1, "Materializing COF neighborhoods.");
      KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, dq, k);
      DBIDs ids = relation.getDBIDs();
  
      LOG.beginStep(stepprog, 2, "Computing Average Chaining Distances.");
      WritableDoubleDataStore acds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
      computeAverageChainingDistances(knnq, dq, ids, acds);
  
      // compute COF_SCORE of each db object
      LOG.beginStep(stepprog, 3, "Computing Connectivity-based Outlier Factors.");
      WritableDoubleDataStore cofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB);
      // track the maximum value for normalization.
      DoubleMinMax cofminmax = new DoubleMinMax();
      computeCOFScores(knnq, ids, acds, cofs, cofminmax);
  
      LOG.setCompleted(stepprog);
  
      // Build result representation.
      DoubleRelation scoreResult = new MaterializedDoubleRelation("Connectivity-Based Outlier Factor", "cof-outlier", cofs, ids);
      OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(cofminmax.getMin(), cofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
      return new OutlierResult(scoreMeta, scoreResult);
    }