docs: protected Cluster<SubspaceModel> runDOC(Database database, Relation<V> relation, ArrayModifiableDBIDs S, final int d, int n, int m, int r, int minClusterSize) {
      // Best cluster for the current run.
      DBIDs C = null;
      // Relevant attributes for the best cluster.
      long[] D = null;
      // Quality of the best cluster.
      double quality = Double.NEGATIVE_INFINITY;
  
      // Bounds for our cluster.
      // ModifiableHyperBoundingBox bounds = new ModifiableHyperBoundingBox(new
      // double[d], new double[d]);
  
      // Inform the user about the progress in the current iteration.
      FiniteProgress iprogress = LOG.isVerbose() ? new FiniteProgress("Iteration progress for current cluster", m * n, LOG) : null;
  
      Random random = rnd.getSingleThreadedRandom();
      DBIDArrayIter iter = S.iter();
  
      for(int i = 0; i < n; ++i) {
        // Pick a random seed point.
        iter.seek(random.nextInt(S.size()));
  
        for(int j = 0; j < m; ++j) {
          // Choose a set of random points.
          DBIDs randomSet = DBIDUtil.randomSample(S, r, random);
  
          // Initialize cluster info.
          long[] nD = BitsUtil.zero(d);
  
          // Test each dimension and build bounding box.
          for(int k = 0; k < d; ++k) {
            if(dimensionIsRelevant(k, relation, randomSet)) {
              BitsUtil.setI(nD, k);
            }
          }
          if(BitsUtil.cardinality(nD) > 0) {
            DBIDs nC = findNeighbors(iter, nD, S, relation);
  
            if(LOG.isDebuggingFiner()) {
              LOG.finer("Testing a cluster candidate, |C| = " + nC.size() + ", |D| = " + BitsUtil.cardinality(nD));
            }
  
            // Is the cluster large enough?
            if(nC.size() < minClusterSize) {
              // Too small.
              if(LOG.isDebuggingFiner()) {
                LOG.finer("... but it's too small.");
              }
              continue;
            }
            // Better cluster than before?
            double nQuality = computeClusterQuality(nC.size(), BitsUtil.cardinality(nD));
            if(nQuality > quality) {
              if(LOG.isDebuggingFiner()) {
                LOG.finer("... and it's the best so far: " + nQuality + " vs. " + quality);
              }
              C = nC;
              D = nD;
              quality = nQuality;
            }
            else {
              if(LOG.isDebuggingFiner()) {
                LOG.finer("... but we already have a better one.");
              }
            }
          }
          LOG.incrementProcessed(iprogress);
        }
      }
      LOG.ensureCompleted(iprogress);
  
      return (C != null) ? makeCluster(relation, C, D) : null;
    }