docs: public OutlierResult run(Database database, Relation<N> nrel, Relation<? extends NumberVector> relation) {
      final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(database, nrel);
      WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
  
      MeanVariance mv = new MeanVariance();
      for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
        DBIDs neighbors = npred.getNeighborDBIDs(iditer);
        final double median;
        {
          double[] fi = new double[neighbors.size()];
          // calculate and store Median of neighborhood
          int c = 0;
          for(DBIDIter iter = neighbors.iter(); iter.valid(); iter.advance()) {
            if(DBIDUtil.equal(iditer, iter)) {
              continue;
            }
            fi[c] = relation.get(iter).doubleValue(0);
            c++;
          }
  
          if(c > 0) {
            median = QuickSelect.median(fi, 0, c);
          }
          else {
            median = relation.get(iditer).doubleValue(0);
          }
        }
        double h = relation.get(iditer).doubleValue(0) - median;
        scores.putDouble(iditer, h);
        mv.put(h);
      }
  
      // Normalize scores
      final double mean = mv.getMean();
      final double stddev = mv.getNaiveStddev();
      DoubleMinMax minmax = new DoubleMinMax();
      for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
        double score = Math.abs((scores.doubleValue(iditer) - mean) / stddev);
        minmax.put(score);
        scores.putDouble(iditer, score);
      }
  
      DoubleRelation scoreResult = new MaterializedDoubleRelation("MO", "Median-outlier", scores, relation.getDBIDs());
      OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0);
      OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
      or.addChildResult(npred);
      return or;
    }