/**************************************************************************** Copyright (c) 2006, Colorado School of Mines and others. All rights reserved. This program and accompanying materials are made available under the terms of the Common Public License - v1.0, which accompanies this distribution, and is available at http://www.eclipse.org/legal/cpl-v10.html ****************************************************************************/ package edu.mines.jtk.util; /** * A quantile estimator that enables incremental updates. In other words, * the estimator processes samples sequentially in one pass, and does not * require all samples to be sorted, or even partially sorted, in fast * random-access memory. *
* The quantile estimate is probably not useful for fewer than 10 samples. *
* The estimate is most accurate for cumulative distribution functions * that are smooth in the neighborhood of the desired quantile q. For * such distributions, the accuracy of the estimate improves with * successive updates. *
* This class is an implementation of the algorithm published by Jain,
* R. and Chlamtac, I., 1985, The PP algorithm for dynamic calculation of
* quantiles and histograms without storing observations: Comm. ACM,
* v. 28, n. 10.
*
* @author Dave Hale, Colorado School of Mines
* @version 2002.03.03, 2006.07.13
*/
public class Quantiler {
/**
* Constructs a quantiler for the specified quantile fraction.
* @param q the quantile fraction; 0 <= q <= 1 is required.
*/
public Quantiler(float q) {
Check.argument(0.0f<=q,"0.0f<=q");
Check.argument(q<=1.0f,"q<=1.0f");
_q = q;
_m0 = -1.0;
_q2 = 0.0f;
_inited = (_q==0.0 || _q==1.0);
}
/**
* Constructs a quantiler for the specified quantile fraction and null value.
* @param q the quantile; 0 <= q <= 1 is required.
* @param fnull the null value to be ignored in estimating the quantile.
*/
public Quantiler(float q, float fnull) {
Check.argument(0.0f<=q,"0.0f<=q");
Check.argument(q<=1.0f,"q<=1.0f");
_q = q;
_fnull = fnull;
_ignoreNull = true;
_m0 = -1.0;
_q2 = fnull;
_inited = (_q==0.0 || _q==1.0);
}
/**
* Returns the current quantile estimate.
* @return the current quantile estimate.
*/
public float estimate() {
return (float)_q2;
}
/**
* Updates the quantile estimate with the specified sample.
* @param f the sample used to update the estimate.
* @return the updated quantile estimate.
*/
public float update(float f) {
if (!_inited) {
initOne(f);
} else {
updateOne(f);
}
return estimate();
}
/**
* Updates the quantile estimate with the specified samples.
* @param f array[] of samples used to update the estimate.
* @return the updated quantile estimate.
*/
public float update(float[] f) {
int n = f.length;
int i = 0;
for (; !_inited && i