cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
Integrator.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2023-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
23#include "CepGen/Utils/String.h"
27
28namespace cepgen {
29 namespace python {
30 class Integrator final : public cepgen::Integrator {
31 public:
32 explicit Integrator(const ParametersList& params)
33 : cepgen::Integrator(params), env_(ParametersList().setName("python_integrator")) {
34 auto cfg = ObjectPtr::importModule(steer<std::string>("module"));
35 if (!cfg)
36 throw PY_ERROR << "Failed to import the Python module '" << steer<std::string>("module") << "'.";
37 if (func_ = cfg.attribute("integrate"); !func_ || !PyCallable_Check(func_.get()))
38 throw PY_ERROR << "Failed to retrieve/cast the object to a Python functional.";
39 }
40
41 void setLimits(const std::vector<Limits>& lims) override { lims_ = ObjectPtr::make(lims); }
42
43 Value integrate(Integrand& integrand) override {
44 gIntegrand = &integrand;
45 const auto iterations = steer<int>("iterations");
46 const auto evals = steer<int>("evals");
47 PyMethodDef py_integr = {"integrand", py_integrand, METH_VARARGS, "A python-wrapped integrand"};
48 ObjectPtr function(PyCFunction_NewEx(&py_integr, nullptr, ObjectPtr::make<std::string>("integrand").get()));
49 const auto value = lims_ ? func_(function.get(), (int)integrand.size(), iterations, 1000, evals, lims_.get())
50 : func_(function.get(), (int)integrand.size(), iterations, 1000, evals);
51 if (!value)
52 throw PY_ERROR;
53 const auto vals = value.vector<double>();
54 if (vals.size() < 2)
55 throw CG_FATAL("python:Integrator")
56 << "Wrong multiplicity of result returned from Python's integration algorithm: " << vals << ".";
57
58 return Value{vals[0], vals[1]};
59 }
60
63 desc.setDescription("Python integration algorithm");
64 desc.add<std::string>("module", "IntegrationAlgos.Vegas")
65 .setDescription("name of the Python module embedding the integrate() function");
66 desc.add<int>("iterations", 10);
67 desc.add<int>("evals", 1000);
68 return desc;
69 }
71
72 private:
73 Environment env_;
74 ObjectPtr func_{nullptr}, lims_{nullptr};
75 static PyObject* py_integrand(PyObject* /*self*/, PyObject* args) {
76 if (!gIntegrand)
77 throw CG_FATAL("python:Integrator") << "Integrand was not initialised.";
78 const auto c_args = ObjectPtr::wrap(PyTuple_GetItem(args, 0)).vector<double>();
79 return ObjectPtr::make<double>(gIntegrand->eval(c_args)).release();
80 }
81 };
82 Integrand* Integrator::gIntegrand = nullptr;
83 } // namespace python
84} // namespace cepgen
#define PY_ERROR
Definition Error.h:25
#define CG_FATAL(mod)
Definition Exception.h:61
#define REGISTER_INTEGRATOR(name, obj)
Add a generic process definition to the list of handled processes.
An integrand wrapper placeholder.
Definition Integrand.h:27
virtual double eval(const std::vector< double > &)=0
Compute the integrand for a given coordinates set.
virtual size_t size() const =0
Phase space dimension.
Monte-Carlo integration algorithm.
Definition Integrator.h:28
static ParametersDescription description()
A description object for parameters collection.
A scalar value with its uncertainty.
Definition Value.h:26
Integrator(const ParametersList &params)
Value integrate(Integrand &integrand) override
Perform the multidimensional Monte Carlo integration.
static ParametersDescription description()
void setLimits(const std::vector< Limits > &lims) override
Specify the variables limits on integration.
static Integrand * gIntegrand
Smart pointer to a Python object and its dereferencing operator.
Definition ObjectPtr.h:36
ObjectPtr attribute(const std::string &) const
Retrieve the attribute from a python object.
std::vector< T > vector() const
Retrieve a vector of objects, either from a Python list or tuple.
static ObjectPtr importModule(const std::string &)
Import a Python module in a new reference-counted Python object.
static ObjectPtr wrap(PyObject *)
Wrap a PyObject without cleaning at the destructor.
Definition ObjectPtr.cpp:45
static ObjectPtr make(const T &)
Build a new Python object from a C++ one.
Common namespace for this Monte Carlo generator.