analistica/ex-1/main.c

160 lines
4.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_histogram.h>
#include <gsl/gsl_statistics_double.h>
#include "landau.h"
#include "tests.h"
#include "bootstrap.h"
/* Here we generate random numbers in a uniform
* range and by using the quantile we map them
* to a Landau distribution. Then we generate an
* histogram to check the correctness.
*/
int main(int argc, char** argv) {
// initialize an RNG
gsl_rng_env_setup();
gsl_rng *r = gsl_rng_alloc(gsl_rng_default);
// prepare histogram
size_t samples = 100000;
double* sample = calloc(samples, sizeof(double));
size_t bins = 40;
double min = -10;
double max = 10;
gsl_histogram* hist = gsl_histogram_alloc(bins);
gsl_histogram_set_ranges_uniform(hist, min, max);
/* Sample generation
*
* Sample points from the Landau
* distribution and fill the histogram.
*/
fprintf(stderr, "# Sampling\n");
fprintf(stderr, "generating %ld points... ", samples);
double x;
for(size_t i=0; i<samples; i++) {
x = gsl_ran_landau(r);
sample[i] = x;
gsl_histogram_increment(hist, x);
}
fprintf(stderr, "done\n");
// sort the sample
qsort(sample, samples, sizeof(double), &cmp_double);
/* Kolmogorov-Smirnov test
*
* Compute the D statistic and its
* associated probability.
*/
double D = 0;
double d;
for(size_t i=0; i<samples; i++) {
d = fabs(landau_cdf(sample[i], NULL) - ((double)i+1)/samples);
if (d > D)
D = d;
}
fprintf(stderr, "\n\n# Kolmogorov-Smirnov test\n");
double beta = kolmogorov_cdf(D, samples);
// print the results
fprintf(stderr, "\n## Results\n");
fprintf(stderr, "D: %f\n", D);
fprintf(stderr, "α: %g\n", 1 - beta);
/* Mode comparison
*
* Compute the half-sample mode by bootstrapping
* and compare the result with the value found by
* numerical maximisation of the PDF.
*/
fprintf(stderr, "\n\n# Mode comparison\n");
/* A structure used by the optimisation
* routines in numeric_mode and others
* functions below.
*/
gsl_function pdf;
pdf.function = &landau_pdf;
pdf.params = NULL;
double mode_e = numeric_mode(min, max, &pdf, 1);
uncert mode_o = bootstrap_mode(r, sample, samples, 100);
// print the results
fprintf(stderr, "\n## Results\n");
fprintf(stderr, "expected mode: %.7f\n", mode_e);
fprintf(stderr, "observed mode: %.4f±%.4f\n", mode_o.n, mode_o.s);
// t-test
double t = fabs(mode_e - mode_o.n)/mode_o.s;
double p = 1 - erf(t/sqrt(2));
fprintf(stderr, "\n## t-test\n");
fprintf(stderr, "t=%.3f\n", t);
fprintf(stderr, "p=%.3f\n", p);
/* FWHM comparison
*
* Estimate the FWHM of the sample by constructing
* an empirical PDF via a KDE method and applying
* the definition on it (numerical solution of
* `f(x) = max/2` ⇒ x₁-x₀). This is again bootstrapped
* to estimate the standard errors and compared against
* the numerical value of FWHM from the true PDF.
*/
fprintf(stderr, "\n\n# FWHM comparison\n");
double fwhm_e = numeric_fwhm(min, max, &pdf, 1);
uncert fwhm_o = bootstrap_fwhm(r, min, max, sample, samples, 100);
// print the results
fprintf(stderr, "\n## Results\n");
fprintf(stderr, "expected fwhm: %.7f\n", fwhm_e);
fprintf(stderr, "observed fwhm: %.4f±%.4f\n", fwhm_o.n, fwhm_o.s);
// t-test
t = fabs(fwhm_e - fwhm_o.n)/fwhm_o.s;
p = 1 - erf(t/sqrt(2));
fprintf(stderr, "\n## t-test\n");
fprintf(stderr, "t=%.3f\n", t);
fprintf(stderr, "p=%.3f\n", p);
/* Median comparison
*
* Compute the median of the sample by bootstrapping
* it and comparing it with the QDF(1/2).
*/
fprintf(stderr, "\n\n# Median comparison\n");
double med_e = landau_qdf(0.5);
uncert med_o = bootstrap_median(r, sample, samples, 100);
// print the results
fprintf(stderr, "\n## Results\n");
fprintf(stderr, "expected median: %.7f\n", med_e);
fprintf(stderr, "observed median: %.4f±%.4f\n", med_o.n, med_o.s);
// t-test
t = fabs(med_e - med_o.n)/med_o.s;
p = 1 - erf(t/sqrt(2));
fprintf(stderr, "\n## t-test\n");
fprintf(stderr, "t=%.3f\n", t);
fprintf(stderr, "p=%.3f\n", p);
// clean up and exit
gsl_histogram_free(hist);
gsl_rng_free(r);
free(sample);
return EXIT_SUCCESS;
}