CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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/Functor.h"
11 #include "Math/Integrator.h"
12 #include "Math/AllIntegrationTypes.h"
13 #include <vector>
14 #include <cmath>
15 #include <memory>
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  private:
38  unsigned int samples_;
39  };
40 
42  public:
44  GaussLegendreIntegrator(unsigned int samples, double epsilon);
45  template<typename F>
46  double operator()(const F& f, double min, double max) const {
47  a0 = 0.5*(max + min);
48  b0 = 0.5*(max - min);
49  result = 0.0;
50  for (i = 0; i < samples_; ++i) {
51  result += w[i] * f(a0 + b0*x[i]);
52  }
53 
54  return result * b0;
55  }
56  private:
57  unsigned int samples_;
58  std::vector<double> x, w;
59  mutable double a0, b0, result;
60  mutable unsigned int i;
61  };
62 
64  public:
66  GaussIntegrator(double epsilon) : epsilon_(epsilon) { }
67  template<typename F>
68  double operator()(const F& f, double a, double b) const {
69  h = 0;
70  if (b == a) return h;
71  aconst = kCST/std::abs(b - a);
72  bb = a;
73  CASE1:
74  aa = bb;
75  bb = b;
76  CASE2:
77  c1 = kHF*(bb + aa);
78  c2 = kHF*(bb - aa);
79  s8 = 0;
80  for(i = 0; i < 4; ++i) {
81  u = c2*x[i];
82  xx = c1 + u;
83  f1 = f(xx);
84  xx = c1-u;
85  f2 = f(xx);
86  s8 += w[i]*(f1 + f2);
87  }
88  s16 = 0;
89  for(i = 4; i < 12; ++i) {
90  u = c2*x[i];
91  xx = c1+u;
92  f1 = f(xx);
93  xx = c1-u;
94  f2 = f(xx);
95  s16 += w[i]*(f1 + f2);
96  }
97  s16 = c2*s16;
98  if (std::abs(s16 - c2*s8) <= epsilon_*(1. + std::abs(s16))) {
99  h += s16;
100  if(bb != b) goto CASE1;
101  } else {
102  bb = c1;
103  if(1. + aconst*std::abs(c2) != 1) goto CASE2;
104  h = s8;
105  }
106 
107  error_ = std::abs(s16 - c2*s8);
108  return h;
109  }
110  double error() const { return error_; }
111  private:
112  mutable double error_;
113  double epsilon_;
114  static const double x[12], w[12];
115  static const double kHF;
116  static const double kCST;
117  mutable double h, aconst, bb, aa, c1, c2, u, s8, s16, f1, f2, xx;
118  mutable unsigned int i;
119  };
120 
121  struct RootIntegrator {
122  RootIntegrator(ROOT::Math::IntegrationOneDim::Type type = ROOT::Math::IntegrationOneDim::kADAPTIVE,
123  double absTol = 1e-9, double relTol = 1e-6, unsigned int size = 1000, unsigned int rule = 3) :
124  type_(type), absTol_(absTol), relTol_(relTol), size_(size), rule_(rule),
125  integrator_(new ROOT::Math::Integrator(type, absTol, relTol, size, rule)) { }
127  type_ = o.type_;
128  absTol_ = o.absTol_; relTol_ = o.relTol_;
129  size_ = o.size_; rule_ = o.rule_;
130  integrator_.reset(new ROOT::Math::Integrator(type_, absTol_, relTol_, size_, rule_));
131  }
133  type_ = o.type_;
134  absTol_ = o.absTol_; relTol_ = o.relTol_;
135  size_ = o.size_; rule_ = o.rule_;
136  integrator_.reset(new ROOT::Math::Integrator(type_, absTol_, relTol_, size_, rule_));
137  return * this;
138  }
139  template<typename F>
140  double operator()(const F& f, double a, double b) const {
141  ROOT::Math::Functor1D wrapper(&f, &F::operator());
142  integrator_->SetFunction(wrapper);
143  return integrator_->Integral(a, b);
144  }
145  private:
147  double absTol_, relTol_;
148  unsigned int size_, rule_;
149  mutable std::auto_ptr<ROOT::Math::Integrator> integrator_;
150  };
151 }
152 
153 #endif
dbl * delta
Definition: mlp_gen.cc:36
int i
Definition: DBlmapReader.cc:9
RootIntegrator & operator=(const RootIntegrator &o)
RootIntegrator(const RootIntegrator &o)
double operator()(const F &f, double min, double max) const
GaussIntegrator(double epsilon)
#define abs(x)
Definition: mlp_lapack.h:159
#define min(a, b)
Definition: mlp_lapack.h:161
TrapezoidIntegrator(unsigned int samples)
double operator()(const F &f, double a, double b) const
static const double kCST
const T & max(const T &a, const T &b)
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
double operator()(const F &f, double a, double b) const
arg type
Definition: Factorize.h:37
static const double w[12]
double operator()(const F &f, double min, double max) const
double a
Definition: hdecay.h:121
double trapezoid_integral(const F &f, double min, double max, unsigned int samples)
const double epsilon
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
tuple size
Write out results.
std::auto_ptr< ROOT::Math::Integrator > integrator_
static HepMC::HEPEVT_Wrapper wrapper
static const double x[12]