update_estimate(struct Quantile *quantile, double value, double p, double rand,
double min_step)
{
- if (value > quantile->est && rand > (1.0 - p)) {
+ if (value >= quantile->est) {
+ if (rand < (1.0 - p))
+ return;
quantile->step += quantile->sign > 0 ? min_step : -min_step;
- quantile->est += quantile->step > 0.0 ? fabs(quantile->step) : min_step;
+ quantile->est += quantile->step > min_step ? quantile->step : min_step;
if (quantile->est > value) {
quantile->step += value - quantile->est;
- quantile->est = value;
+ quantile->est = value + min_step / 4.0;
}
if (quantile->sign < 0 && quantile->step > min_step)
quantile->step = min_step;
quantile->sign = 1;
- } else if (value < quantile->est && rand > p) {
+ } else {
+ if (rand < p)
+ return;
quantile->step += quantile->sign < 0 ? min_step : -min_step;
- quantile->est -= quantile->step > 0.0 ? fabs(quantile->step) : min_step;
+ quantile->est -= quantile->step > min_step ? quantile->step : min_step;
if (quantile->est < value) {
quantile->step += quantile->est - value;
- quantile->est = value;
+ quantile->est = value - min_step / 4.0;
}
if (quantile->sign > 0 && quantile->step > min_step)
quantile->step = min_step;
{
int i, j, k, min_k, max_k, q, r, in_order, out_order;
QNT_Instance inst;
- double x;
+ double x, x2;
in_order = out_order = 0;
QNT_Reset(inst);
TEST_CHECK(inst->n_set == 0);
+ for (j = 0; j < 3; j++) {
+ QNT_Reset(inst);
+ x = (i + 950) / 1e9;
+ if (random() % 10)
+ x2 = (i + 951) / 1e9;
+ else
+ x2 = x;
+ for (k = 0; k < 1000; k++)
+ QNT_Accumulate(inst, random() % 2 ? x : x2);
+ for (k = 0; k < inst->n_quants; k++) {
+ TEST_CHECK(inst->quants[k].est > x - 0.4e-9);
+ TEST_CHECK(inst->quants[k].est < x2 + 0.4e-9);
+ TEST_CHECK(inst->quants[k].step < -15e-9);
+ TEST_CHECK(inst->quants[k].step > -1000e-9);
+ if (min_k * 2 == q && k < inst->repeat) {
+ if (x == x2) {
+ TEST_CHECK(inst->quants[k].step < -750e-9);
+ TEST_CHECK(inst->quants[k].step > -1000e-9);
+ } else {
+ TEST_CHECK(inst->quants[k].step < -350e-9);
+ TEST_CHECK(inst->quants[k].step > -600e-9);
+ }
+ }
+ }
+ }
+
QNT_DestroyInstance(inst);
}