Hydra  4.0.1
A header-only templated C++ framework to perform data analysis on massively parallel platforms.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
vegas.inl

This example show how to use the hydra::Vegas numerical integration algorithm to calculate the integral of a five dimensional Gaussian.

/*----------------------------------------------------------------------------
*
* Copyright (C) 2016 - 2023 Antonio Augusto Alves Junior
*
* This file is part of Hydra Data Analysis Framework.
*
* Hydra is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Hydra is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Hydra. If not, see <http://www.gnu.org/licenses/>.
*
*---------------------------------------------------------------------------*/
/*
* vegas.inl
*
* Created on: 16/07/2017
* Author: Antonio Augusto Alves Junior
*/
#ifndef VEGAS_INL_
#define VEGAS_INL_
/**
* \example vegas.inl
* This example show how to use the hydra::Vegas
* numerical integration algorithm to calculate
* the integral of a five dimensional Gaussian.
*/
#include <iostream>
#include <assert.h>
#include <time.h>
#include <string>
#include <vector>
#include <array>
#include <chrono>
#include <limits>
//command line arguments
#include <tclap/CmdLine.h>
//this lib
#include <hydra/Types.h>
#include <hydra/Function.h>
#include <hydra/Vegas.h>
#include <hydra/Lambda.h>
int main(int argv, char** argc)
{
size_t calls = 0;
size_t iterations = 0;
double max_error = 0;
try {
TCLAP::CmdLine cmd("Command line arguments for vegas", '=');
TCLAP::ValueArg<size_t> NCallsArg("n", "number-of-calls", "Number of call.", true, 5000, "size_t");
cmd.add(NCallsArg);
TCLAP::ValueArg<double> MaxErrorArg("e", "max-error", "Maximum error.", false, 1.0e-3, "double");
cmd.add(MaxErrorArg);
TCLAP::ValueArg<size_t> IterationsArg("i", "max-iterations", "Maximum maximum number of iterations.",false, 10, "size_t");
cmd.add(IterationsArg);
// Parse the argv array.
cmd.parse(argv, argc);
// Get the value parsed by each arg.
calls = NCallsArg.getValue();
iterations = IterationsArg.getValue();
max_error = MaxErrorArg.getValue();
}
catch (TCLAP::ArgException &e)
{
std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
}
//number of dimensions (user can change it)
constexpr size_t N = 5;
//integration region limits
double min[N];
double max[N];
//5D Gaussian parameters
double mean = 0.0;
double sigma = 1.0;
//set Gaussian parameters and
//integration region limits
for(size_t i=0; i< N; i++){
min[i] = -6.0;
max[i] = 6.0;
}
// create functor using C++11 lambda
auto GAUSSIAN = [=] __hydra_dual__ (double x, double y, double z, double w, double v ){
double g = 1.0;
double f = 0.0;
double X[5]{x,y,z,w,v};
for(size_t i=0; i<N; i++){
double m2 = (X[i] - mean )*(X[i] - mean );
double s2 = sigma*sigma;
f = exp(-m2/(2.0 * s2 ))/( sqrt(2.0*s2*PI));
g *= f;
}
return g;
};
//wrap the lambda
auto gaussian = hydra::wrap_lambda(GAUSSIAN);
//device
{
//----------------------------------------------------------------------
//Vegas State_d hold the resources for performing the integration
State_d.SetVerbose(-2);
State_d.SetAlpha(1.5);
State_d.SetIterations( iterations );
State_d.SetUseRelativeError(1);
State_d.SetMaxError( max_error );
State_d.SetCalls( calls );
State_d.SetTrainingCalls( calls/10 );
State_d.SetTrainingIterations(2);
//vegas integrator
auto start_vegas = std::chrono::high_resolution_clock::now();
auto result = Vegas_d.Integrate(gaussian);
auto end_vegas = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed_vegas = end_vegas - start_vegas;
std::cout << std::endl;
std::cout << "----------------- Device ----------------"<< std::endl;
std::cout << ">>> [Vegas]: Gaussian<"<< N << ">" << std::endl;
std::cout << "Result: " << Vegas_d.GetState().GetResult() << " +/- " << Vegas_d.GetState().GetSigma() <<std::endl
<< "Time (ms): " << elapsed_vegas.count() <<std::endl;
std::cout << "-----------------------------------------"<< std::endl;
}
return 0;
}
#endif /* VEGAS_INL_ */