public double getResultEstimate() { return registers.quantile(quantileRatio); }
/** * Calculates percentile from {@link TDigest}. * <p>Handles cases where only one value in TDigest object. */ public static double calculatePercentile(@Nonnull TDigest tDigest, int percentile) { if (tDigest.size() == 1) { // Specialize cases where only one value in TDigest (cannot use quantile method) return tDigest.centroids().iterator().next().mean(); } else { return tDigest.quantile(percentile / 100.0); } }
@Test public void testTDigest() { for (int i = 0; i < NUM_ITERATIONS; i++) { TDigest expected = TDigest.createMergingDigest(PercentileTDigestAggregationFunction.DEFAULT_TDIGEST_COMPRESSION); int size = RANDOM.nextInt(100) + 1; for (int j = 0; j < size; j++) { expected.add(RANDOM.nextDouble()); } byte[] bytes = ObjectSerDeUtils.serialize(expected); TDigest actual = ObjectSerDeUtils.deserialize(bytes, ObjectSerDeUtils.ObjectType.TDigest); for (int j = 0; j <= 100; j++) { assertEquals(actual.quantile(j / 100.0), expected.quantile(j / 100.0), 1e-5); } } } }
@Test public void testBasic() { int times = 1; int compression = 100; for (int t = 0; t < times; t++) { TDigest tDigest = TDigest.createAvlTreeDigest(compression); Random random = new Random(); int dataSize = 10000; List<Double> dataset = Lists.newArrayListWithCapacity(dataSize); for (int i = 0; i < dataSize; i++) { double d = random.nextDouble(); tDigest.add(d); dataset.add(d); } Collections.sort(dataset); double actualResult = tDigest.quantile(0.5); double expectedResult = MathUtil.findMedianInSortedList(dataset); assertEquals(expectedResult, actualResult, 0.01); } } }
} else { newQ = qCuts[i]; x = dist1.quantile(newQ);
@Test public void testTDigest() { double compression = 100; double quantile = 0.5; PercentileCounter counter = new PercentileCounter(compression, quantile); TDigest tDigest = TDigest.createAvlTreeDigest(compression); Random random = new Random(); int dataSize = 10000; List<Double> dataset = Lists.newArrayListWithCapacity(dataSize); for (int i = 0; i < dataSize; i++) { double d = random.nextDouble(); counter.add(d); tDigest.add(d); } double actualResult = counter.getResultEstimate(); Collections.sort(dataset); double expectedResult = tDigest.quantile(quantile); assertEquals(expectedResult, actualResult, 0); }
/** * This returns an approximate percentile based on a t-digest. * @param p * @return an approximate percentile based on a t-digest */ @Override public double getPercentile(double p) { return digest.quantile(p/100.0); }
@Override public double quantile(final double q) { return tdigest.quantile(q); }
@Override public double getValue(double quantile) { return snapshot.quantile(quantile); }
@Override public double getValue(double quantile) { return snapshot.quantile(quantile); }
public double quantile(double q) { return quantiles.quantile(q); }
public double getQuartile(int i) { return quantiles.quantile(0.25 * i); }
public double getResultEstimate() { return registers.quantile(quantileRatio); }
/** * Returns the quantile of the data set. * * @param quantile * must satisfy 0.0 <= quantile <= 1.0. For example to read the 99% percentile pass * quantile = 0.99 */ public double getQuantile(double quantile) { if (exactValues != null) { return getExactQuantile(quantile); } else { return tdigest.quantile(quantile); } }
@Override public void processHistogram(MetricName name, Histogram histogram, FlushProcessorContext context) throws Exception { if (histogram instanceof WavefrontHistogram && useWavefrontHistograms) { WavefrontHistogram wavefrontHistogram = (WavefrontHistogram) histogram; wavefront.report.Histogram.Builder builder = wavefront.report.Histogram.newBuilder(); builder.setBins(Lists.newLinkedList()); builder.setCounts(Lists.newLinkedList()); long minMillis = Long.MAX_VALUE; if (wavefrontHistogram.count() == 0) return; for (WavefrontHistogram.MinuteBin minuteBin : wavefrontHistogram.bins(true)) { builder.getBins().add(minuteBin.getDist().quantile(.5)); builder.getCounts().add(Math.toIntExact(minuteBin.getDist().size())); minMillis = Long.min(minMillis, minuteBin.getMinMillis()); } builder.setType(HistogramType.TDIGEST); builder.setDuration(Math.toIntExact(currentMillis.get() - minMillis)); context.report(builder.build()); } else { context.reportSubMetric(histogram.count(), "count"); for (Map.Entry<String, Double> entry : MetricsToTimeseries.explodeSummarizable(histogram, reportEmptyHistogramStats).entrySet()) { context.reportSubMetric(entry.getValue(), entry.getKey()); } for (Map.Entry<String, Double> entry : MetricsToTimeseries.explodeSampling(histogram, reportEmptyHistogramStats).entrySet()) { context.reportSubMetric(entry.getValue(), entry.getKey()); } histogram.clear(); } sentCounter.inc(); }
@Override public void processHistogram(MetricName name, Histogram histogram, FlushProcessorContext context) throws Exception { if (histogram instanceof WavefrontHistogram && useWavefrontHistograms) { WavefrontHistogram wavefrontHistogram = (WavefrontHistogram) histogram; wavefront.report.Histogram.Builder builder = wavefront.report.Histogram.newBuilder(); builder.setBins(Lists.newLinkedList()); builder.setCounts(Lists.newLinkedList()); long minMillis = Long.MAX_VALUE; if (wavefrontHistogram.count() == 0) return; for (WavefrontHistogram.MinuteBin minuteBin : wavefrontHistogram.bins(true)) { builder.getBins().add(minuteBin.getDist().quantile(.5)); builder.getCounts().add(Math.toIntExact(minuteBin.getDist().size())); minMillis = Long.min(minMillis, minuteBin.getMinMillis()); } builder.setType(HistogramType.TDIGEST); builder.setDuration(Math.toIntExact(currentMillis.get() - minMillis)); context.report(builder.build()); } else { context.reportSubMetric(histogram.count(), "count"); for (Map.Entry<String, Double> entry : MetricsToTimeseries.explodeSummarizable(histogram, reportEmptyHistogramStats).entrySet()) { context.reportSubMetric(entry.getValue(), entry.getKey()); } for (Map.Entry<String, Double> entry : MetricsToTimeseries.explodeSampling(histogram, reportEmptyHistogramStats).entrySet()) { context.reportSubMetric(entry.getValue(), entry.getKey()); } histogram.clear(); } sentCounter.inc(); }