docs: public OutlierResult run(Database database, Relation<N> nrel, Relation<? extends NumberVector> relation) {
      final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(database, nrel);
  
      // Compute the global mean and variance
      MeanVariance globalmv = new MeanVariance();
      for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
        globalmv.put(relation.get(iditer).doubleValue(0));
      }
  
      DoubleMinMax minmax = new DoubleMinMax();
      WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
  
      // calculate normalized attribute values
      // calculate neighborhood average of normalized attribute values.
      for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
        // Compute global z score
        final double globalZ = (relation.get(iditer).doubleValue(0) - globalmv.getMean()) / globalmv.getNaiveStddev();
        // Compute local average z score
        Mean localm = new Mean();
        for(DBIDIter iter = npred.getNeighborDBIDs(iditer).iter(); iter.valid(); iter.advance()) {
          if(DBIDUtil.equal(iditer, iter)) {
            continue;
          }
          localm.put((relation.get(iter).doubleValue(0) - globalmv.getMean()) / globalmv.getNaiveStddev());
        }
        // if neighors.size == 0
        final double localZ;
        if(localm.getCount() > 0) {
          localZ = localm.getMean();
        }
        else {
          // if s has no neighbors => Wzi = zi
          localZ = globalZ;
        }
  
        // compute score
        // Note: in the original moran scatterplot, any object with a score < 0
        // would be an outlier.
        final double score = Math.max(-globalZ * localZ, 0);
        minmax.put(score);
        scores.putDouble(iditer, score);
      }
  
      DoubleRelation scoreResult = new MaterializedDoubleRelation("MoranOutlier", "Moran Scatterplot Outlier", scores, relation.getDBIDs());
      OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0);
      OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
      or.addChildResult(npred);
      return or;
    }