CMS 3D CMS Logo

NumericalIntegration.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_NumericalIntegration_h
2 #define PhysicsTools_Utilities_NumericalIntegration_h
3 /*
4  * Numerical integration utilities
5  *
6  * \author: Luca Lista
7  * Gauss Legendre and Gauss algorithms based on ROOT implementation
8  *
9  */
10 #include "Math/AllIntegrationTypes.h"
11 #include "Math/Functor.h"
12 #include "Math/Integrator.h"
13 #include <cmath>
14 #include <memory>
15 #include <vector>
16 
17 namespace funct {
18 
19  template <typename F>
20  double trapezoid_integral(const F& f, double min, double max, unsigned int samples) {
21  const double l = max - min, delta = l / samples;
22  double sum = 0;
23  for (unsigned int i = 0; i < samples; ++i) {
24  sum += f(min + (i + 0.5) * delta);
25  }
26  return sum * delta;
27  }
28 
30  public:
32  explicit TrapezoidIntegrator(unsigned int samples) : samples_(samples) {}
33  template <typename F>
34  double operator()(const F& f, double min, double max) const {
35  return trapezoid_integral(f, min, max, samples_);
36  }
37 
38  private:
39  unsigned int samples_;
40  };
41 
43  public:
45  GaussLegendreIntegrator(unsigned int samples, double epsilon);
46  template <typename F>
47  double operator()(const F& f, double min, double max) const {
48  a0 = 0.5 * (max + min);
49  b0 = 0.5 * (max - min);
50  result = 0.0;
51  for (i = 0; i < samples_; ++i) {
52  result += w[i] * f(a0 + b0 * x[i]);
53  }
54 
55  return result * b0;
56  }
57 
58  private:
59  unsigned int samples_;
60  std::vector<double> x, w;
61  mutable double a0, b0, result;
62  mutable unsigned int i;
63  };
64 
66  public:
69  template <typename F>
70  double operator()(const F& f, double a, double b) const {
71  h = 0;
72  if (b == a)
73  return h;
74  aconst = kCST / std::abs(b - a);
75  bb = a;
76  CASE1:
77  aa = bb;
78  bb = b;
79  CASE2:
80  c1 = kHF * (bb + aa);
81  c2 = kHF * (bb - aa);
82  s8 = 0;
83  for (i = 0; i < 4; ++i) {
84  u = c2 * x[i];
85  xx = c1 + u;
86  f1 = f(xx);
87  xx = c1 - u;
88  f2 = f(xx);
89  s8 += w[i] * (f1 + f2);
90  }
91  s16 = 0;
92  for (i = 4; i < 12; ++i) {
93  u = c2 * x[i];
94  xx = c1 + u;
95  f1 = f(xx);
96  xx = c1 - u;
97  f2 = f(xx);
98  s16 += w[i] * (f1 + f2);
99  }
100  s16 = c2 * s16;
101  if (std::abs(s16 - c2 * s8) <= epsilon_ * (1. + std::abs(s16))) {
102  h += s16;
103  if (bb != b)
104  goto CASE1;
105  } else {
106  bb = c1;
107  if (1. + aconst * std::abs(c2) != 1)
108  goto CASE2;
109  h = s8;
110  }
111 
112  error_ = std::abs(s16 - c2 * s8);
113  return h;
114  }
115  double error() const { return error_; }
116 
117  private:
118  mutable double error_;
119  double epsilon_;
120  static const double x[12], w[12];
121  static const double kHF;
122  static const double kCST;
123  mutable double h, aconst, bb, aa, c1, c2, u, s8, s16, f1, f2, xx;
124  mutable unsigned int i;
125  };
126 
127  struct RootIntegrator {
128  RootIntegrator(ROOT::Math::IntegrationOneDim::Type type = ROOT::Math::IntegrationOneDim::kADAPTIVE,
129  double absTol = 1e-9,
130  double relTol = 1e-6,
131  unsigned int size = 1000,
132  unsigned int rule = 3)
133  : type_(type),
134  absTol_(absTol),
135  relTol_(relTol),
136  size_(size),
137  rule_(rule),
138  integrator_(new ROOT::Math::Integrator(type, absTol, relTol, size, rule)) {}
140  type_ = o.type_;
141  absTol_ = o.absTol_;
142  relTol_ = o.relTol_;
143  size_ = o.size_;
144  rule_ = o.rule_;
145  integrator_ = std::make_unique<ROOT::Math::Integrator>(type_, absTol_, relTol_, size_, rule_);
146  }
148  type_ = o.type_;
149  absTol_ = o.absTol_;
150  relTol_ = o.relTol_;
151  size_ = o.size_;
152  rule_ = o.rule_;
153  integrator_ = std::make_unique<ROOT::Math::Integrator>(type_, absTol_, relTol_, size_, rule_);
154  return *this;
155  }
156  template <typename F>
157  double operator()(const F& f, double a, double b) const {
158  ROOT::Math::Functor1D wrapper(&f, &F::operator());
159  integrator_->SetFunction(wrapper);
160  return integrator_->Integral(a, b);
161  }
162 
163  private:
165  double absTol_, relTol_;
166  unsigned int size_, rule_;
167  mutable std::unique_ptr<ROOT::Math::Integrator> integrator_;
168  };
169 } // namespace funct
170 
171 #endif
RootIntegrator & operator=(const RootIntegrator &o)
double operator()(const F &f, double min, double max) const
RootIntegrator(const RootIntegrator &o)
Definition: Abs.h:5
GaussIntegrator(double epsilon)
double operator()(const F &f, double min, double max) const
TrapezoidIntegrator(unsigned int samples)
double operator()(const F &f, double a, double b) const
std::unique_ptr< ROOT::Math::Integrator > integrator_
static const double kCST
double operator()(const F &f, double a, double b) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
ROOT::Math::IntegrationOneDim::Type type_
RootIntegrator(ROOT::Math::IntegrationOneDim::Type type=ROOT::Math::IntegrationOneDim::kADAPTIVE, double absTol=1e-9, double relTol=1e-6, unsigned int size=1000, unsigned int rule=3)
double b
Definition: hdecay.h:120
arg type
Definition: Factorize.h:32
static const double w[12]
double a
Definition: hdecay.h:121
double trapezoid_integral(const F &f, double min, double max, unsigned int samples)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
static HepMC::HEPEVT_Wrapper wrapper
static const double x[12]