docs: public double evaluateClustering(Database db, Relation<? extends NumberVector> rel, Clustering<?> c) {
      List<? extends Cluster<?>> clusters = c.getAllClusters();
      NumberVector[] centroids = new NumberVector[clusters.size()];
      int noisecount = EvaluateSimplifiedSilhouette.centroids(rel, clusters, centroids, noiseOption);
      double[] withinGroupDistance = withinGroupDistances(rel, clusters, centroids);
  
      Mean daviesBouldin = new Mean();
      for(int i = 0; i < clusters.size(); i++) {
        final NumberVector centroid = centroids[i];
        final double withinGroupDistancei = withinGroupDistance[i];
        // maximum within-to-between cluster spread
        double max = 0;
        for(int j = 0; j < clusters.size(); j++) {
          NumberVector ocentroid = centroids[j];
          if(ocentroid == centroid) {
            continue;
          }
          // Both are real clusters:
          if(centroid != null && ocentroid != null) {
            // bD = between group distance
            double bD = distanceFunction.distance(centroid, ocentroid);
            // d = within-to-between cluster spread
            double d = (withinGroupDistancei + withinGroupDistance[j]) / bD;
            max = d > max ? d : max;
          }
          else if(noiseOption != NoiseHandling.IGNORE_NOISE) {
            if(centroid != null) {
              double d = Double.POSITIVE_INFINITY;
              // Find the closest element
              for(DBIDIter it = clusters.get(j).getIDs().iter(); it.valid(); it.advance()) {
                double d2 = distanceFunction.distance(centroid, rel.get(it));
                d = d2 < d ? d2 : d;
              }
              d = withinGroupDistancei / d;
              max = d > max ? d : max;
            }
            else if(ocentroid != null) {
              double d = Double.POSITIVE_INFINITY;
              // Find the closest element
              for(DBIDIter it = clusters.get(i).getIDs().iter(); it.valid(); it.advance()) {
                double d2 = distanceFunction.distance(rel.get(it), ocentroid);
                d = d2 < d ? d2 : d;
              }
              d = withinGroupDistance[j] / d;
              max = d > max ? d : max;
            } // else: (0+0) / d = 0.
          }
        }
        daviesBouldin.put(max);
      }
  
      // For a single cluster, we return 2 (result for equidistant points)
      final double daviesBouldinMean = daviesBouldin.getCount() > 1 ? daviesBouldin.getMean() : 2.;
  
      if(LOG.isStatistics()) {
        LOG.statistics(new StringStatistic(key + ".db-index.noise-handling", noiseOption.toString()));
        if(noisecount > 0) {
          LOG.statistics(new LongStatistic(key + ".db-index.ignored", noisecount));
        }
        LOG.statistics(new DoubleStatistic(key + ".db-index", daviesBouldinMean));
      }
  
      EvaluationResult ev = EvaluationResult.findOrCreate(db.getHierarchy(), c, "Internal Clustering Evaluation", "internal evaluation");
      MeasurementGroup g = ev.findOrCreateGroup("Distance-based Evaluation");
      g.addMeasure("Davies Bouldin Index", daviesBouldinMean, 0., Double.POSITIVE_INFINITY, 0., true);
      db.getHierarchy().resultChanged(ev);
      return daviesBouldinMean;
    }