public static DoublePopulationStatisticsAggregator combine(Collection<DoublePopulationStatisticsAggregator> aggregators) { Random random = new Random(); DoublePopulationStatisticsAggregator result = new DoublePopulationStatisticsAggregator(); for (DoublePopulationStatisticsAggregator aggregator : aggregators) { if (aggregator.maximum > result.maximum) { result.maximum = aggregator.maximum; } if (aggregator.minimum < result.minimum) { result.minimum = aggregator.minimum; } result.numValues += aggregator.numValues; result.total += aggregator.total; } // Now we can create a stream of values based on a // random sample of the aggregators reservoirs but // with the number of values in their streams a weight // and reservoir sample that. This assumes that all given reservoirs // have the same size. for (DoublePopulationStatisticsAggregator aggregator : aggregators) { double ratio = (double) aggregator.numValues / (double) result.numValues; for (double value : aggregator.reservoirSample.getReservoir()) { if ((Math.abs(random.nextDouble()) / Double.MAX_VALUE) < ratio) { result.reservoirSample.sample(value, random); } } } return result; }
public static String toString(DoublePopulationStatisticsAggregator populationStatistics) { StringBuilder result = new StringBuilder(); result.append(populationStatistics.minimum); result.append(' '); result.append(populationStatistics.maximum); result.append(' '); result.append(populationStatistics.numValues); result.append(' '); result.append(populationStatistics.total); for (int i = 0; i < populationStatistics.reservoirSample.getSize(); ++i) { result.append(' '); result.append(populationStatistics.reservoirSample.getReservoir()[i]); } return result.toString(); }
public double[] computeDeciles() { double[] result = new double[9]; Arrays.fill(result, 0.0); if (reservoirSample.getSize() > 0) { // Sort valid reservoir values first Arrays.sort(reservoirSample.getReservoir(), 0, reservoirSample.getSize()); // Compute deciles for (int i = 0; i < 9; ++i) { result[i] = getSortedPopulationDecile(reservoirSample.getReservoir(), i + 1, reservoirSample.getSize()); } } return result; }
public void aggregate(double minimum, double maximum, long numValues, double total, double[] values) { if (maximum > this.maximum) { this.maximum = maximum; } if (minimum < this.minimum) { this.minimum = minimum; } this.numValues += numValues; this.total += total; this.reservoirSample.sample(values, random); }
public ReservoirSample(int reservoirMaxSize) { reservoir = new double[reservoirMaxSize]; clear(); }
public void sample(ReservoirSample other, Random random) { for (int i = 0; i < other.getSize(); ++i) { sample(other.getReservoir()[i], random); } }
public void clear() { minimum = Double.MAX_VALUE; maximum = Double.MIN_VALUE; numValues = 0; total = 0.0; reservoirSample.clear(); }
public DoublePopulationStatisticsAggregator(double minimum, double maximum, long numValues, double total, double[] randomSample) { this.minimum = minimum; this.maximum = maximum; this.numValues = numValues; this.total = total; this.reservoirSample.sample(randomSample, random); }
public void sample(double[] values, Random random) { for (double value : values) { sample(value, random); } }