cepgen
is hosted by
Hepforge
,
IPPP Durham
CepGen
1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
AnalyticalIntegratorGSL.cpp
Go to the documentation of this file.
1
/*
2
* CepGen: a central exclusive processes event generator
3
* Copyright (C) 2022-2024 Laurent Forthomme
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <gsl/gsl_version.h>
20
21
#if defined(GSL_MAJOR_VERSION) && (GSL_MAJOR_VERSION > 2 || (GSL_MAJOR_VERSION == 2 && GSL_MINOR_VERSION >= 4))
22
23
#include <gsl/gsl_deriv.h>
24
#include <gsl/gsl_errno.h>
25
#include <gsl/gsl_integration.h>
26
27
#include "
CepGen/Core/Exception.h
"
28
#include "
CepGen/Integration/AnalyticIntegrator.h
"
29
#include "
CepGen/Modules/AnalyticIntegratorFactory.h
"
30
#include "
CepGen/Utils/GSLFunctionsWrappers.h
"
31
32
namespace
cepgen
{
33
namespace
utils {
34
class
AnalyticalIntegratorGSL final :
public
AnalyticIntegrator {
35
public
:
36
explicit
AnalyticalIntegratorGSL(
const
ParametersList& params)
37
: AnalyticIntegrator(params),
38
mode_(steerAs<int, Mode>(
"mode"
)),
39
fixed_type_(steerAs<int, FixedType>(
"fixedType"
)),
40
nodes_(steer<int>(
"nodes"
)),
41
alpha_(steer<double>(
"alpha"
)),
42
beta_(steer<double>(
"beta"
)),
43
limit_(steerAs<int, size_t>(
"limit"
)),
44
epsabs_(steer<double>(
"epsabs"
)),
45
epsrel_(steer<double>(
"epsrel"
)) {}
46
47
static
ParametersDescription description() {
48
auto
desc = AnalyticIntegrator::description();
49
desc.setDescription(
"GSL 1D integration algorithms wrapper"
);
50
desc.addAs<int, Mode>(
"mode"
, Mode::Fixed).setDescription(
"integrator algorithm to use"
);
51
desc.addAs<int, FixedType>(
"fixedType"
, FixedType::Jacobi).setDescription(
"type of quadrature"
);
52
desc.add<
int
>(
"nodes"
, 100).setDescription(
"number of quadrature nodes for the fixed type integration"
);
53
desc.add<
double
>(
"alpha"
, 0.).setDescription(
"alpha parameter for the fixed type integration"
);
54
desc.add<
double
>(
"beta"
, 0.).setDescription(
"alpha parameter for the fixed type integration"
);
55
desc.add<
int
>(
"limit"
, 1000).setDescription(
"maximum number of subintervals to build"
);
56
desc.add<
double
>(
"epsabs"
, 0.).setDescription(
"desired absolute error limit"
);
57
desc.add<
double
>(
"epsrel"
, 0.1).setDescription(
"desired relative error limit"
);
58
return
desc;
59
}
60
61
double
integrate
(
const
Function1D& func,
void
* obj =
nullptr
,
const
Limits& lim = {})
const
override
{
62
if
(obj)
63
return
eval(GSLFunctionWrapper::build(func, obj).
get
(), lim);
64
return
eval(GSLFunctionWrapper::build(func, func_params_).
get
(), lim);
65
}
66
67
private
:
68
enum struct
Mode { Fixed = 0, QNG = 1, QAG = 2, QAGS = 3, QAWC = 4 };
69
enum struct
FixedType {
70
Legendre = 0,
71
Chebyshev = 1,
72
Gegenbauer = 2,
73
Jacobi = 3,
74
Laguerre = 4,
75
Hermite = 5,
76
Exponential = 6,
77
Rational = 7,
78
Chebyshev2 = 8
79
};
80
double
eval(
const
gsl_function*,
const
Limits&)
const
;
81
const
Mode mode_;
82
const
FixedType fixed_type_;
83
const
int
nodes_;
84
const
double
alpha_, beta_;
85
const
size_t
limit_;
86
const
double
epsabs_, epsrel_;
87
};
88
89
double
AnalyticalIntegratorGSL::eval(
const
gsl_function* wrp,
const
Limits& lim)
const
{
90
double
result{0.};
91
#if defined(GSL_MAJOR_VERSION) && (GSL_MAJOR_VERSION > 2 || (GSL_MAJOR_VERSION == 2 && GSL_MINOR_VERSION >= 1))
92
const
double
xmin = (lim.hasMin() ? lim.min() : range_.min());
93
const
double
xmax = (lim.hasMax() ? lim.max() : range_.max());
94
int
res = GSL_SUCCESS;
95
if
(mode_ == Mode::Fixed) {
96
const
gsl_integration_fixed_type* type{
nullptr
};
97
switch
(fixed_type_) {
98
case
FixedType::Legendre:
99
type = gsl_integration_fixed_legendre;
100
break
;
101
case
FixedType::Chebyshev:
102
type = gsl_integration_fixed_chebyshev;
103
break
;
104
case
FixedType::Gegenbauer:
105
type = gsl_integration_fixed_gegenbauer;
106
break
;
107
case
FixedType::Jacobi:
108
type = gsl_integration_fixed_jacobi;
109
break
;
110
case
FixedType::Laguerre:
111
type = gsl_integration_fixed_laguerre;
112
break
;
113
case
FixedType::Hermite:
114
type = gsl_integration_fixed_hermite;
115
break
;
116
case
FixedType::Exponential:
117
type = gsl_integration_fixed_exponential;
118
break
;
119
case
FixedType::Rational:
120
type = gsl_integration_fixed_rational;
121
break
;
122
case
FixedType::Chebyshev2:
123
type = gsl_integration_fixed_chebyshev2;
124
break
;
125
default
:
126
throw
CG_FATAL
(
"AnalyticalIntegratorGSL"
) <<
"Invalid fixed quadrature type: "
<< (int)fixed_type_ <<
"."
;
127
}
128
std::unique_ptr<gsl_integration_fixed_workspace, void (*)(gsl_integration_fixed_workspace*)> workspace(
129
gsl_integration_fixed_alloc(type, nodes_, xmin, xmax, alpha_, beta_), gsl_integration_fixed_free);
130
res = gsl_integration_fixed(wrp, &result, workspace.get());
131
}
else
if
(mode_ == Mode::QNG) {
132
size_t
neval;
133
double
error;
134
res = gsl_integration_qng(wrp, xmin, xmax, epsabs_, epsrel_, &result, &error, &neval);
135
}
else
{
136
double
error;
137
std::unique_ptr<gsl_integration_workspace, void (*)(gsl_integration_workspace*)> workspace(
138
gsl_integration_workspace_alloc(limit_), gsl_integration_workspace_free);
139
if
(mode_ == Mode::QAG) {
140
int
key = GSL_INTEG_GAUSS41;
141
res = gsl_integration_qag(wrp, xmin, xmax, epsabs_, epsrel_, limit_, key, workspace.get(), &result, &error);
142
}
else
if
(mode_ == Mode::QAGS)
143
res = gsl_integration_qags(wrp, xmin, xmax, epsabs_, epsrel_, limit_, workspace.get(), &result, &error);
144
else
if
(mode_ == Mode::QAWC)
145
res = gsl_integration_qawc(
146
const_cast<
gsl_function*
>
(wrp), xmin, xmax, epsabs_, epsrel_, 0., limit_, workspace.get(), &result, &error);
147
}
148
if
(res != GSL_SUCCESS)
149
CG_WARNING
(
"AnalyticalIntegratorGSL"
)
150
<<
"Failed to evaluate the integral. GSL error: "
<< gsl_strerror(res) <<
"."
;
151
#else
152
(void)lim;
153
(void)wrp;
154
CG_WARNING
(
"AnalyticalIntegratorGSL"
) <<
"GSL version above 2.1 is required for integration."
;
155
#endif
156
return
result;
157
}
158
}
// namespace utils
159
}
// namespace cepgen
160
using
cepgen::utils::AnalyticalIntegratorGSL;
161
REGISTER_ANALYTIC_INTEGRATOR
(
"gsl"
, AnalyticalIntegratorGSL);
162
#endif
AnalyticIntegratorFactory.h
REGISTER_ANALYTIC_INTEGRATOR
#define REGISTER_ANALYTIC_INTEGRATOR(name, obj)
Add a generic analytical integrator object builder definition.
Definition
AnalyticIntegratorFactory.h:25
AnalyticIntegrator.h
Exception.h
CG_FATAL
#define CG_FATAL(mod)
Definition
Exception.h:61
GSLFunctionsWrappers.h
CG_WARNING
#define CG_WARNING(mod)
Definition
Message.h:228
cepgen::utils::env::get
std::string get(const std::string &var, const std::string &def)
Get an environment variable.
Definition
Environment.cpp:28
cepgen
Common namespace for this Monte Carlo generator.
Definition
CommandLineHandler.cpp:36
python.IntegrationAlgos.MCint.integrate
integrate(f, int num_dim, int num_iter, int num_warmup, int num_calls, list[tuple[float]] limits=[])
Definition
MCint.py:12
CepGen
Utils
AnalyticalIntegratorGSL.cpp
Generated on Mon Jul 29 2024 for CepGen by
1.9.7