2020-03-06 02:24:32 +01:00
|
|
|
#include <gsl/gsl_monte_plain.h>
|
|
|
|
#include <gsl/gsl_monte_miser.h>
|
|
|
|
#include <gsl/gsl_monte_vegas.h>
|
|
|
|
#include <gsl/gsl_monte.h>
|
2020-06-01 15:46:25 +02:00
|
|
|
#include <stdio.h>
|
2020-03-06 02:24:32 +01:00
|
|
|
#include <math.h>
|
2020-06-01 15:46:25 +02:00
|
|
|
#include "lib.h"
|
2020-05-15 00:07:04 +02:00
|
|
|
|
2020-04-30 22:25:44 +02:00
|
|
|
|
2020-05-15 00:07:04 +02:00
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
2020-03-06 02:24:32 +01:00
|
|
|
// Some useful variables.
|
2020-05-15 00:07:04 +02:00
|
|
|
//
|
2020-06-01 15:46:25 +02:00
|
|
|
size_t dims = 1; // Integral dimension
|
|
|
|
double lower[1] = {0}; // Integration range lower limit
|
|
|
|
double upper[1] = {1}; // Integration range upper limit
|
|
|
|
double integral, error; // Result and error
|
|
|
|
|
|
|
|
// An integral is estimated with a number c_i of function calls.
|
|
|
|
// Different number of function calls are tested.
|
|
|
|
//
|
|
|
|
size_t c_0 = 50; // Initial number of function calls
|
|
|
|
size_t c_f = 50000000; // Final number of function calls
|
|
|
|
size_t factor = 10; // c_(i+1) = c_i * factor
|
|
|
|
size_t size = round(1 + log(c_f/c_0)/log(factor)); // Number of integrations
|
|
|
|
|
|
|
|
// A fit will be performed. This struct is needed to accomplish it.
|
|
|
|
//
|
|
|
|
struct bag full_bag;
|
|
|
|
full_bag.pokets.x = calloc(size, sizeof(double));
|
|
|
|
full_bag.pokets.y = calloc(size, sizeof(double));
|
|
|
|
full_bag.size = size;
|
2020-03-06 02:24:32 +01:00
|
|
|
|
|
|
|
// Initialize an RNG.
|
2020-05-15 00:07:04 +02:00
|
|
|
//
|
2020-03-06 02:24:32 +01:00
|
|
|
gsl_rng_env_setup();
|
|
|
|
gsl_rng *r = gsl_rng_alloc(gsl_rng_default);
|
|
|
|
|
|
|
|
// Define GSL function.
|
2020-05-15 00:07:04 +02:00
|
|
|
//
|
2020-03-06 02:24:32 +01:00
|
|
|
gsl_monte_function expo = {&function, dims, NULL};
|
|
|
|
expo.f = &function;
|
|
|
|
expo.dim = 1;
|
|
|
|
expo.params = NULL;
|
|
|
|
|
2020-06-01 15:46:25 +02:00
|
|
|
// Print the results table header.
|
|
|
|
//
|
2020-05-24 22:04:31 +02:00
|
|
|
printf(" Calls | Plain | Error | MISER |"
|
|
|
|
" Error | VEGAS | Error | χ²\n");
|
|
|
|
printf(" ------|----------|----------|----------|"
|
|
|
|
"----------|----------|----------|---------\n");
|
|
|
|
|
2020-06-01 15:46:25 +02:00
|
|
|
// Compute the integral with the three MC methods: plain MC, MISER and VEGAS.
|
2020-05-15 00:07:04 +02:00
|
|
|
//
|
2020-06-01 15:46:25 +02:00
|
|
|
size_t calls = c_0;
|
|
|
|
size_t i = 0;
|
|
|
|
while (calls <= c_f)
|
2020-05-15 00:07:04 +02:00
|
|
|
{
|
|
|
|
// Plain MC
|
|
|
|
gsl_monte_plain_state *sMC = gsl_monte_plain_alloc (dims);
|
|
|
|
gsl_monte_plain_integrate (&expo, lower, upper, dims, calls,
|
|
|
|
r, sMC, &integral, &error);
|
|
|
|
gsl_monte_plain_free(sMC);
|
2020-05-19 16:01:52 +02:00
|
|
|
results(calls, integral, error, 0);
|
2020-03-06 02:24:32 +01:00
|
|
|
|
2020-06-01 15:46:25 +02:00
|
|
|
// Update the struct for the fit.
|
|
|
|
//
|
|
|
|
full_bag.pokets.x[i] = calls;
|
|
|
|
full_bag.pokets.y[i++] = error;
|
|
|
|
|
2020-05-15 00:07:04 +02:00
|
|
|
// MISER
|
|
|
|
gsl_monte_miser_state *sMI = gsl_monte_miser_alloc (dims);
|
2020-03-06 02:24:32 +01:00
|
|
|
gsl_monte_miser_integrate (&expo, lower, upper, dims, calls,
|
2020-05-15 00:07:04 +02:00
|
|
|
r, sMI, &integral, &error);
|
|
|
|
gsl_monte_miser_free(sMI);
|
2020-05-19 16:01:52 +02:00
|
|
|
results(0, integral, error, 0);
|
2020-03-06 02:24:32 +01:00
|
|
|
|
2020-05-15 00:07:04 +02:00
|
|
|
// VEGAS
|
|
|
|
gsl_monte_vegas_state *sVE = gsl_monte_vegas_alloc (dims);
|
|
|
|
gsl_monte_vegas_integrate (&expo, lower, upper, dims, calls,
|
|
|
|
r, sVE, &integral, &error);
|
2020-05-24 22:04:31 +02:00
|
|
|
|
2020-05-19 16:01:52 +02:00
|
|
|
// In order to see the parameters of the VEGAS integration, decomment this
|
|
|
|
// paragraph:
|
|
|
|
//
|
|
|
|
// gsl_monte_vegas_params params;
|
|
|
|
// gsl_monte_vegas_params_get(sVE, ¶ms);
|
|
|
|
// params.verbose = 1;
|
|
|
|
// params.ostream = stderr;
|
|
|
|
// gsl_monte_vegas_params_set(sVE, ¶ms);
|
2020-05-15 00:07:04 +02:00
|
|
|
do
|
|
|
|
{
|
|
|
|
gsl_monte_vegas_integrate (&expo, lower, upper, dims,
|
2020-05-19 16:01:52 +02:00
|
|
|
calls, r, sVE, &integral, &error);
|
2020-05-15 00:07:04 +02:00
|
|
|
} while (fabs (gsl_monte_vegas_chisq (sVE) - 1.0) > 0.5);
|
|
|
|
gsl_monte_vegas_free(sVE);
|
2020-05-19 16:01:52 +02:00
|
|
|
double chi = sVE->chisq;
|
|
|
|
results(0, integral, error, chi);
|
|
|
|
|
2020-05-15 00:07:04 +02:00
|
|
|
// Update function calls
|
2020-06-01 15:46:25 +02:00
|
|
|
//
|
2020-05-15 00:07:04 +02:00
|
|
|
printf ("\n");
|
2020-06-01 15:46:25 +02:00
|
|
|
calls = calls*factor;
|
2020-05-15 00:07:04 +02:00
|
|
|
}
|
2020-03-06 02:24:32 +01:00
|
|
|
|
2020-06-01 15:46:25 +02:00
|
|
|
// Do a fit of the Plain MC errors.
|
|
|
|
//
|
|
|
|
double p, a, a_err, b, b_err;
|
|
|
|
fit(full_bag, &p, &a, &a_err, &b, &b_err);
|
|
|
|
|
|
|
|
// Print the fit results.
|
|
|
|
//
|
|
|
|
fprintf (stderr, "\n## Fit results:\n\n");
|
|
|
|
fprintf (stderr, "a = %.5f\t", a);
|
|
|
|
fprintf (stderr, "δa = %.5f\n", a_err);
|
|
|
|
fprintf (stderr, "b = %.5f\t", b);
|
|
|
|
fprintf (stderr, "δb = %.5f\n", b_err);
|
|
|
|
fprintf (stderr, "p-value = %.5f\n", p);
|
|
|
|
|
2020-03-06 02:24:32 +01:00
|
|
|
// Free memory.
|
2020-06-01 15:46:25 +02:00
|
|
|
//
|
2020-03-06 02:24:32 +01:00
|
|
|
gsl_rng_free(r);
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|