docs: private void calculateContrast(Relation<? extends NumberVector> relation, HiCSSubspace subspace, ArrayList<ArrayDBIDs> subspaceIndex, Random random) {
      final int card = subspace.cardinality();
      final double alpha1 = FastMath.pow(alpha, (1.0 / card));
      final int windowsize = (int) (relation.size() * alpha1);
      final FiniteProgress prog = LOG.isDebugging() ? new FiniteProgress("Monte-Carlo iterations", m, LOG) : null;
  
      int retries = 0;
      double deviationSum = 0.0;
      for(int i = 0; i < m; i++) {
        // Choose a random set bit.
        int chosen = -1;
        for(int tmp = random.nextInt(card); tmp >= 0; tmp--) {
          chosen = subspace.nextSetBit(chosen + 1);
        }
        // initialize sample
        DBIDs conditionalSample = relation.getDBIDs();
  
        for(int j = subspace.nextSetBit(0); j >= 0; j = subspace.nextSetBit(j + 1)) {
          if(j == chosen) {
            continue;
          }
          ArrayDBIDs sortedIndices = subspaceIndex.get(j);
          ArrayModifiableDBIDs indexBlock = DBIDUtil.newArray(windowsize);
          // initialize index block
          DBIDArrayIter iter = sortedIndices.iter();
          iter.seek(random.nextInt(relation.size() - windowsize));
          for(int k = 0; k < windowsize; k++, iter.advance()) {
            indexBlock.add(iter); // select index block
          }
  
          conditionalSample = DBIDUtil.intersection(conditionalSample, indexBlock);
        }
        if(conditionalSample.size() < 10) {
          retries++;
          if(LOG.isDebugging()) {
            LOG.debug("Sample size very small. Retry no. " + retries);
          }
          if(retries >= MAX_RETRIES) {
            LOG.warning("Too many retries, for small samples: " + retries);
          }
          else {
            i--;
            continue;
          }
        }
        // Project conditional set
        double[] sampleValues = new double[conditionalSample.size()];
        {
          int l = 0;
          for(DBIDIter iter = conditionalSample.iter(); iter.valid(); iter.advance()) {
            sampleValues[l++] = relation.get(iter).doubleValue(chosen);
          }
        }
        // Project full set
        double[] fullValues = new double[relation.size()];
        {
          int l = 0;
          for(DBIDIter iter = subspaceIndex.get(chosen).iter(); iter.valid(); iter.advance()) {
            fullValues[l++] = relation.get(iter).doubleValue(chosen);
          }
        }
        double contrast = statTest.deviation(fullValues, sampleValues);
        if(Double.isNaN(contrast)) {
          i--;
          LOG.warning("Contrast was NaN");
          continue;
        }
        deviationSum += contrast;
        LOG.incrementProcessed(prog);
      }
      LOG.ensureCompleted(prog);
      subspace.contrast = deviationSum / m;
    }