#include <gsl/gsl_rng.h>

#pragma once

/* A pair structure that represent
 * a value with an uncertainty
 */
typedef struct {
  double n;  // nominal value
  double s;  // uncertainty
} uncert;


/* Function that compare doubles for sorting:
 * x > y  ⇒ 1
 * x == y ⇒ 0
 * x < y  ⇒ -1
 */
int cmp_double (const void *xp, const void *yp);


/* Computes an approximation to the asymptotic median
 * and its standard deviation by bootstrapping (ie
 * repeated resampling) the original `sample`, `boots`
 * times.
 *
 * The functions returns an `uncert` pair of mean and
 * sdtdev of the medians computed on each sample.
 */
uncert bootstrap_median(
    const gsl_rng *r,
    double *sample, size_t n,
    int boots);


/* Computes an approximation to the asymptotic mode
 * and its standard deviation by bootstrapping (ie
 * repeated resampling) the original `sample`, `boots`
 * times.
 *
 * The functions returns an `uncert` pair of mean and
 * stddev of the modes computed on each sample.
 */
uncert bootstrap_mode(
    const gsl_rng *r,
    double *sample, size_t n,
    int boots);


/* Computes an approximation to the asymptotic fwhm
 * and its standard deviation by bootstrapping (ie
 * repeated resampling) the original `sample`, `boots`
 * times.
 *
 * `min,max` are the bounds of interval that is
 * expected to contain the mode of the sample.
 *
 * The functions returns an `uncert` pair of mean and
 * stddev of the fwhms computed on each sample.
 */
uncert bootstrap_fwhm(
    const gsl_rng *r,
    double min, double max,
    double *sample, size_t n,
    int boots);
