docs: public CollectionResult<double[]> run(Database database, Relation<O> relation, Relation<?> lrelation) {
      final DistanceQuery<O> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
      final int qk = k + (includeSelf ? 0 : 1);
      final KNNQuery<O> knnQuery = database.getKNNQuery(distQuery, qk);
  
      MeanVarianceMinMax[] mvs = MeanVarianceMinMax.newArray(k);
  
      final DBIDs ids = DBIDUtil.randomSample(relation.getDBIDs(), sampling, random);
  
      FiniteProgress objloop = LOG.isVerbose() ? new FiniteProgress("Computing nearest neighbors", ids.size(), LOG) : null;
      // sort neighbors
      for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
        KNNList knn = knnQuery.getKNNForDBID(iter, qk);
        Object label = lrelation.get(iter);
  
        int positive = 0, i = 0;
        for(DBIDIter ri = knn.iter(); i < k && ri.valid(); ri.advance()) {
          if(!includeSelf && DBIDUtil.equal(iter, ri)) {
            // Do not increment i.
            continue;
          }
          positive += match(label, lrelation.get(ri)) ? 1 : 0;
          final double precision = positive / (double) (i + 1);
          mvs[i].put(precision);
          i++;
        }
        LOG.incrementProcessed(objloop);
      }
      LOG.ensureCompleted(objloop);
  
      // Transform Histogram into a Double Vector array.
      Collection<double[]> res = new ArrayList<>(k);
      for(int i = 0; i < k; i++) {
        final MeanVarianceMinMax mv = mvs[i];
        final double std = mv.getCount() > 1. ? mv.getSampleStddev() : 0.;
        res.add(new double[] { i + 1, mv.getMean(), std, mv.getMin(), mv.getMax(), mv.getCount() });
      }
      return new CollectionResult<>("Average Precision", "average-precision", res);
    }