ex-1: generalise numeric_fwhm to take any pdf
This commit is contained in:
parent
dce8cfb8b6
commit
6ad77013b6
27
ex-1/main.c
27
ex-1/main.c
@ -72,9 +72,10 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
/* Mode comparison
|
/* Mode comparison
|
||||||
*
|
*
|
||||||
* Find the bin with the maximum number of events
|
* 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");
|
fprintf(stderr, "\n\n# Mode comparison\n");
|
||||||
|
|
||||||
/* A structure used by the optimisation
|
/* A structure used by the optimisation
|
||||||
@ -102,8 +103,28 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
/* FWHM comparison
|
/* FWHM comparison
|
||||||
*
|
*
|
||||||
* Find the bins x₋ and x₊.
|
* 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);
|
||||||
|
//uncert fwhm_o = bootstrap_fwhm(r, 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 = 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
|
/* Median comparison
|
||||||
|
113
ex-1/tests.c
113
ex-1/tests.c
@ -6,6 +6,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <gsl/gsl_randist.h>
|
#include <gsl/gsl_randist.h>
|
||||||
#include <gsl/gsl_min.h>
|
#include <gsl/gsl_min.h>
|
||||||
|
#include <gsl/gsl_roots.h>
|
||||||
#include <gsl/gsl_sum.h>
|
#include <gsl/gsl_sum.h>
|
||||||
|
|
||||||
#include "landau.h"
|
#include "landau.h"
|
||||||
@ -119,67 +120,91 @@ double numeric_mode(double min, double max,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the function to be minimized in `numeric_FWHM`.
|
/* A structure containing the half-maximum
|
||||||
|
* of a PDF and a gsl_function of the PDF
|
||||||
|
* itself, used by `numeric_fwhm` to compute
|
||||||
|
* the FWHM.
|
||||||
*/
|
*/
|
||||||
double abs_landau_pdf(double x, void* params_) {
|
struct fwhm_params {
|
||||||
double* params = ((double *) params_);
|
double halfmax;
|
||||||
return fabs(gsl_ran_landau_pdf(x) - params[0]);
|
gsl_function *pdf;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the implicit equation that is solved
|
||||||
|
* in `numeric_fwhm` by a numerical root-finding
|
||||||
|
* method. This function takes a point `x`, the
|
||||||
|
* parameters defined in `fwhm_params` and returns
|
||||||
|
* the value of:
|
||||||
|
*
|
||||||
|
* f(x) - f(max)/2
|
||||||
|
*
|
||||||
|
* where f is the PDF of interest.
|
||||||
|
*/
|
||||||
|
double fwhm_equation(double x, void* params) {
|
||||||
|
struct fwhm_params p = *((struct fwhm_params*) params);
|
||||||
|
return p.pdf->function(x, p.pdf->params) - p.halfmax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Numerically computes the FWHM of Landau
|
/* Numerically computes the FWHM of a PDF
|
||||||
* distribution by maximising the derivative.
|
* distribution using the definition.
|
||||||
* The `min,max` parameters are the initial search
|
* The `min,max` parameters are the initial search
|
||||||
* interval for the optimisation. `mode` can be
|
* interval for the root search of equation
|
||||||
* computer with `numeric_mode(min, max)`.
|
* `fwhm_equation`. Two searches are performed in
|
||||||
|
* [min, mode] and [mode, max] that will give the
|
||||||
|
* two solutions x₋, x₊. The FWHM is then x₊-x₋.
|
||||||
*/
|
*/
|
||||||
double numeric_fwhm(double min, double max, double mode) {
|
double numeric_fwhm(double min, double max,
|
||||||
// create function
|
gsl_function *pdf) {
|
||||||
gsl_function pdf;
|
/* Create the gls_function structure
|
||||||
pdf.function = &abs_landau_pdf;
|
* for the equation to be solved.
|
||||||
double params [1];
|
*/
|
||||||
params[0]= gsl_ran_landau_pdf(mode)/2;
|
double mode = numeric_mode(min, max, pdf);
|
||||||
pdf.params = params;
|
struct fwhm_params p = {
|
||||||
|
pdf->function(mode, pdf->params)/2,
|
||||||
|
pdf
|
||||||
|
};
|
||||||
|
gsl_function equation;
|
||||||
|
equation.function = &fwhm_equation;
|
||||||
|
equation.params = &p;
|
||||||
|
|
||||||
|
const gsl_root_fsolver_type * T = gsl_root_fsolver_brent;
|
||||||
|
gsl_root_fsolver * s = gsl_root_fsolver_alloc(T);
|
||||||
|
|
||||||
// initialize minimization for x₋
|
// initialize minimization for x₋
|
||||||
double guess = mode - 1;
|
double x, fmin, fmax;
|
||||||
double fmin, fmax;
|
|
||||||
int iter = 0;
|
|
||||||
int max_iter = 100;
|
int max_iter = 100;
|
||||||
double prec = 1e-7;
|
double prec = 1e-7;
|
||||||
int status;
|
int status;
|
||||||
const gsl_min_fminimizer_type * T = gsl_min_fminimizer_goldensection;
|
|
||||||
gsl_min_fminimizer * s = gsl_min_fminimizer_alloc(T);
|
|
||||||
gsl_min_fminimizer_set(s, &pdf, guess, min, mode);
|
|
||||||
|
|
||||||
// minimization
|
// minimization
|
||||||
do {
|
gsl_root_fsolver_set(s, &equation, min, mode);
|
||||||
iter++;
|
status = GSL_CONTINUE;
|
||||||
status = gsl_min_fminimizer_iterate(s);
|
for (int iter = 0; status == GSL_CONTINUE && iter < max_iter; iter++)
|
||||||
guess = gsl_min_fminimizer_x_minimum(s);
|
{ status = gsl_root_fsolver_iterate(s);
|
||||||
fmin = gsl_min_fminimizer_x_lower(s);
|
x = gsl_root_fsolver_root(s);
|
||||||
fmax = gsl_min_fminimizer_x_upper(s);
|
fmin = gsl_root_fsolver_x_lower(s);
|
||||||
status = gsl_min_test_interval(fmin, fmax, prec, prec);
|
fmax = gsl_root_fsolver_x_upper(s);
|
||||||
} while (status == GSL_CONTINUE && iter < max_iter);
|
status = gsl_min_test_interval(fmin, fmax, 0, prec);
|
||||||
double x_low = guess;
|
}
|
||||||
|
double x_low = x;
|
||||||
|
|
||||||
// initialize minimization for x₊
|
// initialize minimization for x₊
|
||||||
guess = mode + 1;
|
gsl_root_fsolver_set(s, &equation, mode, max);
|
||||||
gsl_min_fminimizer_set(s, &pdf, guess, mode, max);
|
|
||||||
|
|
||||||
// minimization
|
// minimization
|
||||||
do {
|
status = GSL_CONTINUE;
|
||||||
iter++;
|
for (int iter = 0; status == GSL_CONTINUE && iter < max_iter; iter++)
|
||||||
status = gsl_min_fminimizer_iterate(s);
|
{ status = gsl_root_fsolver_iterate(s);
|
||||||
guess = gsl_min_fminimizer_x_minimum(s);
|
x = gsl_root_fsolver_root(s);
|
||||||
fmin = gsl_min_fminimizer_x_lower(s);
|
fmin = gsl_root_fsolver_x_lower(s);
|
||||||
fmax = gsl_min_fminimizer_x_upper(s);
|
fmax = gsl_root_fsolver_x_upper(s);
|
||||||
status = gsl_min_test_interval(fmin, fmax, prec, prec);
|
status = gsl_min_test_interval(fmin, fmax, 0, prec);
|
||||||
|
}
|
||||||
|
double x_upp = x;
|
||||||
|
|
||||||
} while (status == GSL_CONTINUE && iter < max_iter);
|
// free memory
|
||||||
double x_upp = guess;
|
gsl_root_fsolver_free(s);
|
||||||
|
|
||||||
// Free memory
|
|
||||||
gsl_min_fminimizer_free(s);
|
|
||||||
return x_upp - x_low;
|
return x_upp - x_low;
|
||||||
}
|
}
|
||||||
|
13
ex-1/tests.h
13
ex-1/tests.h
@ -22,10 +22,13 @@ double numeric_mode(double min, double max,
|
|||||||
gsl_function *pdf);
|
gsl_function *pdf);
|
||||||
|
|
||||||
|
|
||||||
/* Numerically computes the FWHM of Landau
|
/* Numerically computes the FWHM of a PDF
|
||||||
* distribution by maximising the derivative.
|
* distribution using the definition.
|
||||||
* The `min,max` parameters are the initial search
|
* The `min,max` parameters are the initial search
|
||||||
* interval for the optimisation. `mode` can be
|
* interval for the root search of equation
|
||||||
* computer with `numeric_mode(min, max)`.
|
* `fwhm_equation`. Two searches are performed in
|
||||||
|
* [min, mode] and [mode, max] that will give the
|
||||||
|
* two solutions x₋, x₊. The FWHM is then x₊-x₋.
|
||||||
*/
|
*/
|
||||||
double numeric_fwhm(double min, double max, double mode);
|
double numeric_fwhm(double min, double max,
|
||||||
|
gsl_function *pdf);
|
||||||
|
Loading…
Reference in New Issue
Block a user