docs: public OutlierResult run(Database database, Relation<O> relation) {
      StepProgress stepprog = LOG.isVerbose() ? new StepProgress("VOV", 3) : null;
      DBIDs ids = relation.getDBIDs();
      int dim = RelationUtil.dimensionality(relation);
  
      LOG.beginStep(stepprog, 1, "Materializing nearest-neighbor sets.");
      KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, getDistanceFunction(), k);
  
      // Compute Volumes
      LOG.beginStep(stepprog, 2, "Computing Volumes.");
      WritableDoubleDataStore vols = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
      computeVolumes(knnq, dim, ids, vols);
  
      // compute VOV of each object
      LOG.beginStep(stepprog, 3, "Computing Variance of Volumes (VOV).");
      WritableDoubleDataStore vovs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB);
      // track the maximum value for normalization.
      DoubleMinMax vovminmax = new DoubleMinMax();
      computeVOVs(knnq, ids, vols, vovs, vovminmax);
  
      LOG.setCompleted(stepprog);
  
      // Build result representation.
      DoubleRelation scoreResult = new MaterializedDoubleRelation("Variance of Volume", "vov-outlier", vovs, ids);
      OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(vovminmax.getMin(), vovminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0.0);
      return new OutlierResult(scoreMeta, scoreResult);
    }