/* Statistics code * Make only one call to reading for a particular time range and compute all our stats */ void _compute_statistics(cdb_range_t *range, uint64_t *num_recs, cdb_record_t *records) { uint64_t i = 0; uint64_t valid = 0; double sum = 0.0; double *values = calloc(*num_recs, sizeof(double)); for (i = 0; i < *num_recs; i++) { if (!isnan(records[i].value)) { sum += values[valid] = records[i].value; valid++; } } range->num_recs = valid; range->mean = gsl_stats_mean(values, 1, valid); range->max = gsl_stats_max(values, 1, valid); range->min = gsl_stats_min(values, 1, valid); range->sum = sum; range->stddev = gsl_stats_sd(values, 1, valid); range->absdev = gsl_stats_absdev(values, 1, valid); /* The rest need sorted data */ gsl_sort(values, 1, valid); range->median = gsl_stats_median_from_sorted_data(values, 1, valid); range->pct95th = gsl_stats_quantile_from_sorted_data(values, 1, valid, 0.95); range->pct75th = gsl_stats_quantile_from_sorted_data(values, 1, valid, 0.75); range->pct50th = gsl_stats_quantile_from_sorted_data(values, 1, valid, 0.50); range->pct25th = gsl_stats_quantile_from_sorted_data(values, 1, valid, 0.25); /* MAD must come last because it alters the values array * http://en.wikipedia.org/wiki/Median_absolute_deviation */ for (i = 0; i < valid; i++) { values[i] = fabs(values[i] - range->median); if (values[i] < 0.0) { values[i] *= -1.0; } } /* Final sort is required MAD */ gsl_sort(values, 1, valid); range->mad = gsl_stats_median_from_sorted_data(values, 1, valid); free(values); }
CAMLprim value ml_gsl_stats_absdev(value ow, value omean, value data) { size_t len = Double_array_length(data); double result; if(ow == Val_none) if(omean == Val_none) result = gsl_stats_absdev(Double_array_val(data), 1, len); else result = gsl_stats_absdev_m(Double_array_val(data), 1, len, Double_val(Unoption(omean))); else { value w = Unoption(ow); check_array_size(data, w); if(omean == Val_none) result = gsl_stats_wabsdev(Double_array_val(w), 1, Double_array_val(data), 1, len); else result = gsl_stats_wabsdev_m(Double_array_val(w), 1, Double_array_val(data), 1, len, Double_val(Unoption(omean))); } return copy_double(result); }