docs: public OutlierResult run(Database database, Relation<O> relation) {
      StepProgress stepprog = LOG.isVerbose() ? new StepProgress("LOF", 3) : null;
      DBIDs ids = relation.getDBIDs();
  
      LOG.beginStep(stepprog, 1, "Materializing nearest-neighbor sets.");
      KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, getDistanceFunction(), k);
  
      // Compute LRDs
      LOG.beginStep(stepprog, 2, "Computing Local Reachability Densities (LRD).");
      WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
      computeLRDs(knnq, ids, lrds);
  
      // compute LOF_SCORE of each db object
      LOG.beginStep(stepprog, 3, "Computing Local Outlier Factors (LOF).");
      WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB);
      // track the maximum value for normalization.
      DoubleMinMax lofminmax = new DoubleMinMax();
      computeLOFScores(knnq, ids, lrds, lofs, lofminmax);
  
      LOG.setCompleted(stepprog);
  
      // Build result representation.
      DoubleRelation scoreResult = new MaterializedDoubleRelation("Local Outlier Factor", "lof-outlier", lofs, ids);
      OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
      return new OutlierResult(scoreMeta, scoreResult);
    }