#define DELAY_QUANT_MAX_K 2
#define DELAY_QUANT_Q 10
#define DELAY_QUANT_REPEAT 7
+#define DELAY_QUANT_LARGE_STEP_DELAY 1000
#define DELAY_QUANT_MIN_STEP 1.0e-9
struct HCL_Instance_Record {
clock->precision = precision;
clock->delay_quants = QNT_CreateInstance(DELAY_QUANT_MIN_K, DELAY_QUANT_MAX_K,
DELAY_QUANT_Q, DELAY_QUANT_REPEAT,
+ DELAY_QUANT_LARGE_STEP_DELAY,
DELAY_QUANT_MIN_STEP);
LCL_AddParameterChangeHandler(handle_slew, clock);
/* Parameters for the peer delay quantile */
#define DELAY_QUANT_Q 100
+#define DELAY_QUANT_LARGE_STEP_DELAY 100
#define DELAY_QUANT_REPEAT 7
/* Minimum and maximum allowed poll interval */
if (params->max_delay_quant > 0.0) {
int k = round(CLAMP(0.05, params->max_delay_quant, 0.95) * DELAY_QUANT_Q);
result->delay_quant = QNT_CreateInstance(k, k, DELAY_QUANT_Q, DELAY_QUANT_REPEAT,
+ DELAY_QUANT_LARGE_STEP_DELAY,
LCL_GetSysPrecisionAsQuantum() / 2.0);
} else {
result->delay_quant = NULL;
int q;
int min_k;
double min_step;
+ double neg_step_limit;
int n_set;
};
/* ================================================== */
QNT_Instance
-QNT_CreateInstance(int min_k, int max_k, int q, int repeat, double min_step)
+QNT_CreateInstance(int min_k, int max_k, int q, int repeat,
+ int large_step_delay, double min_step)
{
QNT_Instance inst;
long seed;
if (q < 2 || min_k > max_k || min_k < 1 || max_k >= q ||
- repeat < 1 || repeat > MAX_REPEAT || min_step <= 0.0)
+ repeat < 1 || repeat > MAX_REPEAT || min_step <= 0.0 || large_step_delay < 0)
assert(0);
inst = MallocNew(struct QNT_Instance_Record);
inst->q = q;
inst->min_k = min_k;
inst->min_step = min_step;
+ inst->neg_step_limit = -large_step_delay * min_step;
QNT_Reset(inst);
static void
update_estimate(struct Quantile *quantile, double value, double p, double rand,
- double min_step)
+ double min_step, double neg_step_limit)
{
if (value >= quantile->est) {
if (rand < (1.0 - p))
quantile->step = min_step;
quantile->sign = -1;
}
+
+ if (quantile->step < neg_step_limit)
+ quantile->step = neg_step_limit;
}
/* ================================================== */
p = (double)(i / inst->repeat + inst->min_k) / inst->q;
rand = (double)random() / ((1U << 31) - 1);
- update_estimate(&inst->quants[i], value, p, rand, inst->min_step);
+ update_estimate(&inst->quants[i], value, p, rand, inst->min_step, inst->neg_step_limit);
}
}
typedef struct QNT_Instance_Record *QNT_Instance;
-extern QNT_Instance QNT_CreateInstance(int min_k, int max_k, int q, int repeat, double min_step);
+extern QNT_Instance QNT_CreateInstance(int min_k, int max_k, int q, int repeat,
+ int large_step_delay, double min_step);
extern void QNT_DestroyInstance(QNT_Instance inst);
extern void QNT_Reset(QNT_Instance inst);
max_k = random() % (q - 1) + 1;
} while (min_k > max_k);
- inst = QNT_CreateInstance(min_k, max_k, q, r, 1e-9);
+ inst = QNT_CreateInstance(min_k, max_k, q, r, 900, 1e-9);
TEST_CHECK(min_k == QNT_GetMinK(inst));
TEST_CHECK(max_k == QNT_GetMaxK(inst));
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);
+ TEST_CHECK(inst->quants[k].step > -901e-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);
+ TEST_CHECK(inst->quants[k].step > -901e-9);
} else {
TEST_CHECK(inst->quants[k].step < -350e-9);
TEST_CHECK(inst->quants[k].step > -600e-9);