FullStorageAccumulator.java
package org.djutils.stats.summarizers.quantileaccumulator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.djutils.exceptions.Throw;
import org.djutils.stats.summarizers.Tally;
/**
* Quantile accumulator that stores all values and computes exact (within a few ULP) results.
* <br>
* @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
*/
public class FullStorageAccumulator implements QuantileAccumulator
{
/** Storage for the accumulated values. */
private List<Double> accumulator = new ArrayList<>();
/** Is the accumulator currently sorted? */
private boolean isSorted = true;
/**
* Construct a new FullStorageAccumulator.
*/
public FullStorageAccumulator()
{
// Nothing to do here
}
/** {@inheritDoc} */
@Override
public double ingest(final double value)
{
Throw.when(Double.isNaN(value), IllegalArgumentException.class, "accumulator can not accumlate NaN value");
this.accumulator.add(value);
this.isSorted = false;
return value;
}
/** {@inheritDoc} */
@Override
public double getQuantile(final Tally tally, final double probability)
{
Throw.whenNull(tally, "tally cannot be null");
Throw.when(probability < 0 || probability > 1, IllegalArgumentException.class,
"Probability should be between 0.0 and 1.0 (inclusive); got {}", probability);
if (!this.isSorted)
{
Collections.sort(this.accumulator);
this.isSorted = true;
}
double doubleIndex = (this.accumulator.size() - 1) * probability;
int index = Math.min((int) Math.floor(doubleIndex), this.accumulator.size() - 1);
double v0 = this.accumulator.get(index);
if (index >= this.accumulator.size() - 1)
{
return v0;
}
double v1 = this.accumulator.get(index + 1);
return v1 * (doubleIndex - index) + v0 * (1.0 - (doubleIndex - index));
}
/** {@inheritDoc} */
@Override
public void initialize()
{
this.accumulator.clear();
}
/** {@inheritDoc} */
@Override
public String toString()
{
return "FullStorageAccumulator [accumulator size=" + this.accumulator.size() + ", isSorted=" + this.isSorted + "]";
}
}