docs: public OutlierResult run(Database database, Relation<N> spatial, Relation<O> attributes) {
      if(LOG.isDebugging()) {
        LOG.debug("Dimensionality: " + RelationUtil.dimensionality(attributes));
      }
      final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(database, spatial);
  
      CovarianceMatrix covmaker = new CovarianceMatrix(RelationUtil.dimensionality(attributes));
      WritableDataStore<double[]> deltas = DataStoreUtil.makeStorage(attributes.getDBIDs(), DataStoreFactory.HINT_TEMP, double[].class);
      for(DBIDIter iditer = attributes.iterDBIDs(); iditer.valid(); iditer.advance()) {
        final O obj = attributes.get(iditer);
        final DBIDs neighbors = npred.getNeighborDBIDs(iditer);
        // TODO: remove object itself from neighbors?
  
        // Mean vector "g"
        double[] mean = Centroid.make(attributes, neighbors).getArrayRef();
        // Delta vector "h"
        double[] delta = minusEquals(obj.toArray(), mean);
        deltas.put(iditer, delta);
        covmaker.put(delta);
      }
      // Finalize covariance matrix:
      double[] mean = covmaker.getMeanVector();
      double[][] cmati = inverse(covmaker.destroyToSampleMatrix());
  
      DoubleMinMax minmax = new DoubleMinMax();
      WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(attributes.getDBIDs(), DataStoreFactory.HINT_STATIC);
      for(DBIDIter iditer = attributes.iterDBIDs(); iditer.valid(); iditer.advance()) {
        // Note: we modify deltas here
        double[] v = minusEquals(deltas.get(iditer), mean);
        final double score = transposeTimesTimes(v, cmati, v);
        minmax.put(score);
        scores.putDouble(iditer, score);
      }
  
      DoubleRelation scoreResult = new MaterializedDoubleRelation("mean multiple attributes spatial outlier", "mean-multipleattributes-outlier", scores, attributes.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;
    }