cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
VegasIntegrator.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2013-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_monte_vegas.h>
20
26#include "CepGen/Utils/String.h"
27
28namespace cepgen {
30 class VegasIntegrator final : public GSLIntegrator {
31 public:
32 explicit VegasIntegrator(const ParametersList& params)
33 : GSLIntegrator(params),
34 ncvg_(steer<int>("numFunctionCalls")),
35 chisq_cut_(steer<double>("chiSqCut")),
36 treat_(steer<bool>("treat")) {
37 verbosity_ = steer<int>("verbose"); // supersede the parent default verbosity level
38 }
39
41 auto desc = GSLIntegrator::description();
42 desc.setDescription("Vegas stratified sampling integrator");
43 desc.add<int>("numFunctionCalls", 100'000);
44 desc.add<double>("chiSqCut", 1.5);
45 desc.add<bool>("treat", true).setDescription("Phase space treatment");
46 desc.add<int>("iterations", 10);
47 desc.add<double>("alpha", 1.25);
48 desc.addAs<int, Mode>("mode", Mode::stratified);
49 desc.add<std::string>("loggingOutput", "cerr");
50 desc.add<int>("verbose", -1);
51 return desc;
52 }
53
54 Value integrate(Integrand&) override;
55
56 enum class Mode { importance = 1, importanceOnly = 0, stratified = -1 };
57 friend std::ostream& operator<<(std::ostream& os, const Mode& mode) {
58 switch (mode) {
60 return os << "importance";
62 return os << "importance-only";
64 return os << "stratified";
65 }
66 return os;
67 }
68
69 private:
70 void warmup(size_t);
71
72 double COORD(size_t i, size_t j) const { return vegas_state_->xi[i * vegas_state_->dim + j]; }
73
74 double eval(Integrand& integrand, const std::vector<double>& x) const override {
75 //--- by default, no grid treatment
76 if (!treat_)
77 return integrand.eval(x);
78 //--- treatment of the integration grid
79 if (r_boxes_ == 0) {
80 r_boxes_ = (size_t)std::pow(vegas_state_->bins, integrand.size());
81 x_new_.resize(integrand.size());
82 }
83 double w = r_boxes_;
84 for (size_t j = 0; j < integrand.size(); ++j) {
85 //--- find surrounding coordinates and interpolate
86 const double z = x.at(j) * vegas_state_->bins;
87 const auto id = (size_t)z; // coordinate of point before
88 const double rel_pos = z - id; // position between coordinates (norm.)
89 const double bin_width = (id == 0) ? COORD(1, j) : COORD(id + 1, j) - COORD(id, j);
90 //--- build new coordinate from linear interpolation
91 x_new_[j] = COORD(id + 1, j) - bin_width * (1. - rel_pos);
92 w *= bin_width;
93 }
94 return w * integrand.eval(x_new_);
95 }
96
97 const int ncvg_;
98 const double chisq_cut_;
99 const bool treat_;
100 gsl_monte_vegas_params vegas_params_;
101
103 struct gsl_monte_vegas_deleter {
104 inline void operator()(gsl_monte_vegas_state* state) { gsl_monte_vegas_free(state); }
105 };
106
109 std::unique_ptr<gsl_monte_vegas_state, gsl_monte_vegas_deleter> vegas_state_;
110 mutable unsigned long long r_boxes_{0ull};
111 mutable std::vector<double> x_new_;
112 };
113
115 setIntegrand(integrand);
116
117 //--- start by preparing the grid/state
118 vegas_state_.reset(gsl_monte_vegas_alloc(function_->dim));
119 gsl_monte_vegas_params_get(vegas_state_.get(), &vegas_params_);
120 vegas_params_.iterations = steer<int>("iterations");
121 vegas_params_.alpha = steer<double>("alpha");
122 vegas_params_.verbose = verbosity_;
123 vegas_params_.mode = steer<int>("mode");
124 //--- output logging
125 const auto& log = steer<std::string>("loggingOutput");
126 if (log == "cerr") // redirect all debugging information to the error stream
127 vegas_params_.ostream = stderr;
128 else if (log == "cout") // redirect all debugging information to the standard stream
129 vegas_params_.ostream = stdout;
130 else
131 vegas_params_.ostream = fopen(log.c_str(), "w");
132 gsl_monte_vegas_params_set(vegas_state_.get(), &vegas_params_);
133
134 //--- a bit of printout for debugging
135 CG_DEBUG("Integrator:build") << "Vegas parameters:\n\t"
136 << "Number of iterations in Vegas: " << vegas_params_.iterations << ",\n\t"
137 << "α-value: " << vegas_params_.alpha << ",\n\t"
138 << "Verbosity: " << vegas_params_.verbose << ",\n\t"
139 << "Grid interpolation mode: " << (VegasIntegrator::Mode)vegas_params_.mode << ".";
140 if (!vegas_state_)
141 throw CG_FATAL("Integrator:integrate") << "Vegas state not initialised!";
142
143 //--- launch integration
144
145 // warmup (prepare the grid)
146 warmup(25'000);
147
148 // integration phase
149 unsigned short it_chisq = 0;
150 double result, abserr;
151 do {
152 if (int res = gsl_monte_vegas_integrate(function_.get(),
153 &xlow_[0],
154 &xhigh_[0],
155 function_->dim,
156 0.2 * ncvg_,
157 rnd_gen_->engine<gsl_rng>(),
158 vegas_state_.get(),
159 &result,
160 &abserr);
161 res != GSL_SUCCESS)
162 throw CG_FATAL("Integrator:integrate")
163 << "Error at iteration #" << it_chisq << " while performing the integration!\n\t"
164 << "GSL error: " << gsl_strerror(res) << ".";
165 CG_LOG << "\t>> at call " << (++it_chisq) << ": "
166 << utils::format(
167 "average = %10.6f "
168 "sigma = %10.6f chi2 = %4.3f.",
169 result,
170 abserr,
171 gsl_monte_vegas_chisq(vegas_state_.get()));
172 } while (std::fabs(gsl_monte_vegas_chisq(vegas_state_.get()) - 1.) > chisq_cut_ - 1.);
173 CG_DEBUG("Integrator:integrate") << "Vegas grid information:\n\t"
174 << "ran for " << vegas_state_->dim << " dimensions, "
175 << "and generated " << vegas_state_->bins_max << " bins.\n\t"
176 << "Integration volume: " << vegas_state_->vol << ".";
177
178 return Value{result, abserr};
179 }
180
181 void VegasIntegrator::warmup(size_t ncall) {
182 if (!vegas_state_)
183 throw CG_FATAL("Integrator:warmup") << "Vegas state not initialised!";
184 // perform a first integration to warm up the grid
185 double result = 0., abserr = 0.;
186 // ensure the operation was successful
187 if (int res = gsl_monte_vegas_integrate(function_.get(),
188 &xlow_[0],
189 &xhigh_[0],
190 function_->dim,
191 ncall,
192 rnd_gen_->engine<gsl_rng>(),
193 vegas_state_.get(),
194 &result,
195 &abserr);
196
197 res != GSL_SUCCESS)
198 throw CG_ERROR("VegasIntegrator:warmup") << "Failed to warm-up the Vegas grid.\n\t"
199 << "GSL error: " << gsl_strerror(res) << ".";
200
201 CG_INFO("VegasIntegrator:warmup") << "Finished the Vegas warm-up.";
202 }
203} // namespace cepgen
204
205REGISTER_INTEGRATOR("Vegas", VegasIntegrator);
#define CG_FATAL(mod)
Definition Exception.h:61
#define CG_ERROR(mod)
Definition Exception.h:60
#define REGISTER_INTEGRATOR(name, obj)
Add a generic process definition to the list of handled processes.
#define CG_LOG
Definition Message.h:212
#define CG_DEBUG(mod)
Definition Message.h:220
#define CG_INFO(mod)
Definition Message.h:216
std::vector< double > xhigh_
std::vector< double > xlow_
void setIntegrand(Integrand &)
std::unique_ptr< gsl_monte_function > function_
GSL structure storing the function to be integrated by this integrator instance (along with its param...
static ParametersDescription description()
An integrand wrapper placeholder.
Definition Integrand.h:27
int verbosity_
Integrator verbosity.
Definition Integrator.h:57
const std::unique_ptr< utils::RandomGenerator > rnd_gen_
Definition Integrator.h:56
A description object for parameters collection.
T steer(const std::string &key) const
Retrieve a parameters as previously steered.
Definition Steerable.h:39
A scalar value with its uncertainty.
Definition Value.h:26
Vegas integration algorithm developed by P. Lepage, as documented in .
VegasIntegrator(const ParametersList &params)
static ParametersDescription description()
Value integrate(Integrand &) override
Perform the multidimensional Monte Carlo integration.
friend std::ostream & operator<<(std::ostream &os, const Mode &mode)
std::string format(const std::string &fmt, Args... args)
Format a string using a printf style format descriptor.
Definition String.h:61
Common namespace for this Monte Carlo generator.