NumericalFeaturesStatistics { Double2DoubleMap buildHistogram(Binning binning, double min, double max) { double step = (max - min) / 100; Double2DoubleMap histogram = new Double2DoubleArrayMap(); for (double bucketLower = min - step; bucketLower < max + step; bucketLower += step) { int v = binning.getNumberOfValuesBetween(bucketLower, bucketLower + step); histogram.put(bucketLower, v * percentsBinningStep); } return histogram; } NumericalFeaturesStatistics(); synchronized void finishCalculateDigests(StatisticsWorkHandler handler); Long2ObjectMap<Binning> binnings(); synchronized Long2ObjectMap<Double2DoubleMap> buildHistograms(); Long2ObjectMap<Double2DoubleMap> histograms(); void logFeaturesStatistics(); @Inject NumericalFeaturesStatistics percentsHistogramStep(
            @Named("percentsBinningStep") double percentsHistogramStep);  }
@Test public void testBuildHistogram() { Binning binning = new Binning(); for (int i = 0; i < 99; i++) { binning.addPercentile(ThreadLocalRandom.current().nextDouble()); } binning.addPercentile(0.).finishBuild(); NumericalFeaturesStatistics st = new NumericalFeaturesStatistics() .percentsHistogramStep(0.01); Double2DoubleMap histogram = st.buildHistogram(binning, 0, 1); assertEquals(102, histogram.size()); double sum = histogram.values() .stream().mapToDouble(Double::doubleValue).sum(); assertEquals(1., sum, Util.EPSILON); }