void test_quantile(const double p, const double data[], const size_t n, const double expected, const double tol, const char *desc) { gsl_rstat_quantile_workspace *w = gsl_rstat_quantile_alloc(p); double result; size_t i; for (i = 0; i < n; ++i) gsl_rstat_quantile_add(data[i], w); result = gsl_rstat_quantile_get(w); if (fabs(expected) < 1.0e-4) gsl_test_abs(result, expected, tol, "%s p=%g", desc, p); else gsl_test_rel(result, expected, tol, "%s p=%g", desc, p); gsl_rstat_quantile_free(w); }
/* add a data point to the running totals */ int gsl_rstat_add(const double x, gsl_rstat_workspace *w) { double delta = x - w->mean; double delta_n, delta_nsq, term1, n; /* update min and max */ if (w->n == 0) { w->min = x; w->max = x; } else { if (x < w->min) w->min = x; if (x > w->max) w->max = x; } /* update mean and variance */ n = (double) ++(w->n); delta_n = delta / n; delta_nsq = delta_n * delta_n; term1 = delta * delta_n * (n - 1.0); w->mean += delta_n; w->M4 += term1 * delta_nsq * (n * n - 3.0 * n + 3.0) + 6.0 * delta_nsq * w->M2 - 4.0 * delta_n * w->M3; w->M3 += term1 * delta_n * (n - 2.0) - 3.0 * delta_n * w->M2; w->M2 += term1; /* update median */ gsl_rstat_quantile_add(x, w->median_workspace_p); return GSL_SUCCESS; } /* gsl_rstat_add() */