docs: public Clustering<ClusterModel> run(Relation<V> relation) {
      ArrayModifiableDBIDs ids = DBIDUtil.newArray(relation.getDBIDs());
      final int size = ids.size();
  
      // Sort by the sole dimension
      ids.sort(new VectorUtil.SortDBIDsBySingleDimension(relation, dim));
  
      // Density storage.
      WritableDoubleDataStore density = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, 0.);
  
      DBIDArrayIter iter = ids.iter(), iter2 = ids.iter();
  
      StepProgress sprog = LOG.isVerbose() ? new StepProgress("Clustering steps", 2) : null;
  
      LOG.beginStep(sprog, 1, "Kernel density estimation.");
      {
        double[] scratch = new double[2 * k];
        iter.seek(0);
        for(int i = 0; i < size; i++, iter.advance()) {
          // Current value.
          final double curv = relation.get(iter).doubleValue(dim);
  
          final int pre = Math.max(i - k, 0), prek = i - pre;
          final int pos = Math.min(i + k, size - 1), posk = pos - i;
          iter2.seek(pre);
          for(int j = 0; j < prek; j++, iter2.advance()) {
            scratch[j] = curv - relation.get(iter2).doubleValue(dim);
          }
          assert (iter2.getOffset() == i);
          iter2.advance();
          for(int j = 0; j < posk; j++, iter2.advance()) {
            scratch[prek + j] = relation.get(iter2).doubleValue(dim) - curv;
          }
  
          assert (prek + posk >= k);
          double kdist = QuickSelect.quickSelect(scratch, 0, prek + posk, k);
          switch(mode){
          case BALLOON: {
            double dens = 0.;
            if(kdist > 0.) {
              for(int j = 0; j < prek + posk; j++) {
                dens += kernel.density(scratch[j] / kdist);
              }
            }
            else {
              dens = Double.POSITIVE_INFINITY;
            }
            assert (iter.getOffset() == i);
            density.putDouble(iter, dens);
            break;
          }
          case SAMPLE: {
            if(kdist > 0.) {
              iter2.seek(pre);
              for(int j = 0; j < prek; j++, iter2.advance()) {
                double delta = curv - relation.get(iter2).doubleValue(dim);
                density.putDouble(iter2, density.doubleValue(iter2) + kernel.density(delta / kdist));
              }
              assert (iter2.getOffset() == i);
              iter2.advance();
              for(int j = 0; j < posk; j++, iter2.advance()) {
                double delta = relation.get(iter2).doubleValue(dim) - curv;
                density.putDouble(iter2, density.doubleValue(iter2) + kernel.density(delta / kdist));
              }
            }
            else {
              iter2.seek(pre);
              for(int j = 0; j < prek; j++, iter2.advance()) {
                double delta = curv - relation.get(iter2).doubleValue(dim);
                if(!(delta > 0.)) {
                  density.putDouble(iter2, Double.POSITIVE_INFINITY);
                }
              }
              assert (iter2.getOffset() == i);
              iter2.advance();
              for(int j = 0; j < posk; j++, iter2.advance()) {
                double delta = relation.get(iter2).doubleValue(dim) - curv;
                if(!(delta > 0.)) {
                  density.putDouble(iter2, Double.POSITIVE_INFINITY);
                }
              }
            }
            break;
          }
          default:
            throw new UnsupportedOperationException("Unknown mode specified.");
          }
        }
      }
  
      LOG.beginStep(sprog, 2, "Local minima detection.");
      Clustering<ClusterModel> clustering = new Clustering<>("onedimensional-kde-clustering", "One-Dimensional clustering using kernel density estimation.");
      {
        double[] scratch = new double[2 * minwindow + 1];
        int begin = 0;
        int halfw = (minwindow + 1) >> 1;
        iter.seek(0);
        // Fill initial buffer.
        for(int i = 0; i < size; i++, iter.advance()) {
          final int m = i % scratch.length, t = (i - minwindow - 1) % scratch.length;
          scratch[m] = density.doubleValue(iter);
          if(i > scratch.length) {
            double min = Double.POSITIVE_INFINITY;
            for(int j = 0; j < scratch.length; j++) {
              if(j != t && scratch[j] < min) {
                min = scratch[j];
              }
            }
            // Local minimum:
            if(scratch[t] < min) {
              int end = i - minwindow + 1;
              { // Test on which side the kNN is
                iter2.seek(end);
                double curv = relation.get(iter2).doubleValue(dim);
                iter2.seek(end - halfw);
                double left = relation.get(iter2).doubleValue(dim) - curv;
                iter2.seek(end + halfw);
                double right = curv - relation.get(iter2).doubleValue(dim);
                if(left < right) {
                  end++;
                }
              }
              iter2.seek(begin);
              ArrayModifiableDBIDs cids = DBIDUtil.newArray(end - begin);
              for(int j = 0; j < end - begin; j++, iter2.advance()) {
                cids.add(iter2);
              }
              clustering.addToplevelCluster(new Cluster<>(cids, ClusterModel.CLUSTER));
              begin = end;
            }
          }
        }
        // Extract last cluster
        int end = size;
        iter2.seek(begin);
        ArrayModifiableDBIDs cids = DBIDUtil.newArray(end - begin);
        for(int j = 0; j < end - begin; j++, iter2.advance()) {
          cids.add(iter2);
        }
        clustering.addToplevelCluster(new Cluster<>(cids, ClusterModel.CLUSTER));
      }
  
      LOG.ensureCompleted(sprog);
      return clustering;
    }