ROOT  6.06/09
Reference Guide
GaussIntegrator.cxx
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Authors: David Gonzalez Maline 01/2008
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 , LCG ROOT MathLib Team *
7  * *
8  * *
9  **********************************************************************/
10 
11 #include "Math/GaussIntegrator.h"
12 #include "Math/IntegratorOptions.h"
13 #include <cmath>
14 
15 namespace ROOT {
16 namespace Math {
17 
18 
19 bool GaussIntegrator::fgAbsValue = false;
20 
21  GaussIntegrator::GaussIntegrator(double epsabs, double epsrel)
22 {
23 // Default Constructor. If tolerances are not given use default values from ROOT::Math::IntegratorOneDimOptions
24 
25  fEpsAbs = epsabs;
26  fEpsRel = epsrel;
28  if (epsrel < 0 || (epsabs == 0 && epsrel == 0)) fEpsRel = ROOT::Math::IntegratorOneDimOptions::DefaultRelTolerance();
29  if (std::max(fEpsRel,fEpsAbs) <= 0.0 ) {
30  fEpsRel = 1.E-9;
31  fEpsAbs = 1.E-9;
32  MATH_WARN_MSG("ROOT::Math::GausIntegrator", "Invalid tolerance given, use values of 1.E-9");
33  }
34 
35  fLastResult = fLastError = 0;
36  fUsedOnce = false;
37  fFunction = 0;
38 }
39 
41 {
42  // Destructor. (no - operations)
43 }
44 
46 { fgAbsValue = flag; }
47 
48 double GaussIntegrator::Integral(double a, double b) {
49  return DoIntegral(a, b, fFunction);
50 }
51 
53  IntegrandTransform it(this->fFunction);
54  return DoIntegral(0., 1., it.Clone());
55 }
56 
57 double GaussIntegrator::IntegralUp (double a) {
59  return DoIntegral(0., 1., it.Clone());
60 }
61 
62 double GaussIntegrator::IntegralLow (double b) {
64  return DoIntegral(0., 1., it.Clone());
65 }
66 
67 double GaussIntegrator::DoIntegral(double a, double b, const IGenFunction* function)
68 {
69  // Return Integral of function between a and b.
70 
71  if (fEpsRel <=0 || fEpsAbs <= 0) {
72  if (fEpsRel > 0) fEpsAbs = fEpsRel;
73  else if (fEpsAbs > 0) fEpsRel = fEpsAbs;
74  else {
75  MATH_INFO_MSG("ROOT::Math::GausIntegratorOneDim", "Invalid tolerance given - use default values");
78  }
79  }
80 
81  const double kHF = 0.5;
82  const double kCST = 5./1000;
83 
84  double x[12] = { 0.96028985649753623, 0.79666647741362674,
85  0.52553240991632899, 0.18343464249564980,
86  0.98940093499164993, 0.94457502307323258,
87  0.86563120238783174, 0.75540440835500303,
88  0.61787624440264375, 0.45801677765722739,
89  0.28160355077925891, 0.09501250983763744};
90 
91  double w[12] = { 0.10122853629037626, 0.22238103445337447,
92  0.31370664587788729, 0.36268378337836198,
93  0.02715245941175409, 0.06225352393864789,
94  0.09515851168249278, 0.12462897125553387,
95  0.14959598881657673, 0.16915651939500254,
96  0.18260341504492359, 0.18945061045506850};
97 
98  double h, aconst, bb, aa, c1, c2, u, s8, s16, f1, f2;
99  double xx[1];
100  int i;
101 
102  if ( fFunction == 0 )
103  {
104  MATH_ERROR_MSG("ROOT::Math::GausIntegratorOneDim", "A function must be set first!");
105  return 0.0;
106  }
107 
108  h = 0;
109  fUsedOnce = true;
110  if (b == a) return h;
111  aconst = kCST/std::abs(b-a);
112  bb = a;
113 CASE1:
114  aa = bb;
115  bb = b;
116 CASE2:
117  c1 = kHF*(bb+aa);
118  c2 = kHF*(bb-aa);
119  s8 = 0;
120  for (i=0;i<4;i++) {
121  u = c2*x[i];
122  xx[0] = c1+u;
123  f1 = (*function)(xx);
124  if (fgAbsValue) f1 = std::abs(f1);
125  xx[0] = c1-u;
126  f2 = (*function) (xx);
127  if (fgAbsValue) f2 = std::abs(f2);
128  s8 += w[i]*(f1 + f2);
129  }
130  s16 = 0;
131  for (i=4;i<12;i++) {
132  u = c2*x[i];
133  xx[0] = c1+u;
134  f1 = (*function) (xx);
135  if (fgAbsValue) f1 = std::abs(f1);
136  xx[0] = c1-u;
137  f2 = (*function) (xx);
138  if (fgAbsValue) f2 = std::abs(f2);
139  s16 += w[i]*(f1 + f2);
140  }
141  s16 = c2*s16;
142  //if (std::abs(s16-c2*s8) <= fEpsilon*(1. + std::abs(s16))) {
143  double error = std::abs(s16-c2*s8);
144  if (error <= fEpsAbs || error <= fEpsRel*std::abs(s16)) {
145  h += s16;
146  if(bb != b) goto CASE1;
147  } else {
148  bb = c1;
149  if(1. + aconst*std::abs(c2) != 1) goto CASE2;
150  double maxtol = std::max(fEpsRel, fEpsAbs);
151  MATH_WARN_MSGVAL("ROOT::Math::GausIntegrator", "Failed to reach the desired tolerance ",maxtol);
152  h = s8; //this is a crude approximation (cernlib function returned 0 !)
153  }
154 
155  fLastResult = h;
156  fLastError = std::abs(s16-c2*s8);
157 
158  return h;
159 }
160 
161 
162 double GaussIntegrator::Result () const
163 {
164  // Returns the result of the last Integral calculation.
165 
166  if (!fUsedOnce)
167  MATH_ERROR_MSG("ROOT::Math::GaussIntegrator", "You must calculate the result at least once!");
168 
169  return fLastResult;
170 }
171 
173 { return fLastError; }
174 
176 { return (fUsedOnce) ? 0 : -1; }
177 
179 {
180  // Set integration function
181  fFunction = &function;
182  // reset fUsedOne flag
183  fUsedOnce = false;
184 }
185 
186 double GaussIntegrator::Integral (const std::vector< double > &/*pts*/)
187 {
188  // not impl.
189  MATH_WARN_MSG("ROOT::Math::GaussIntegrator", "This method is not implemented in this class !");
190  return -1.0;
191 }
192 
193 double GaussIntegrator::IntegralCauchy (double /*a*/, double /*b*/, double /*c*/)
194 {
195  // not impl.
196  MATH_WARN_MSG("ROOT::Math::GaussIntegrator", "This method is not implemented in this class !");
197  return -1.0;
198 }
199 
201  // set options
204 }
205 
207  // retrieve options
209  opt.SetIntegrator("Gauss");
212  opt.SetWKSize(0);
213  opt.SetNPoints(0);
214  return opt;
215 }
216 
217 
218 
219 //implementation of IntegrandTransform class
220 
222  : fSign(kPlus), fIntegrand(integrand), fBoundary(0.), fInfiniteInterval(true) {
223 }
224 
226  : fSign(sign), fIntegrand(integrand), fBoundary(boundary), fInfiniteInterval(false) {
227 }
228 
229 double IntegrandTransform::DoEval(double x) const {
230  double result = DoEval(x, fBoundary, fSign);
231  return (result += (fInfiniteInterval ? DoEval(x, 0., -1) : 0.));
232 }
233 
234 double IntegrandTransform::DoEval(double x, double boundary, int sign) const {
235  double mappedX = 1. / x - 1.;
236  return (*fIntegrand)(boundary + sign * mappedX) * std::pow(mappedX + 1., 2);;
237 }
238 
239 double IntegrandTransform::operator()(double x) const {
240  return DoEval(x);
241 }
242 
245 }
246 
247 
248 } // end namespace Math
249 } // end namespace ROOT
double Error() const
Return the estimate of the absolute Error of the last Integral calculation.
virtual void SetAbsTolerance(double eps)
This method is not implemented.
double IntegralUp(double a)
Returns Integral of function on an upper semi-infinite interval.
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition: IFunction.h:133
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
double Integral()
Returns Integral of function on an infinite interval.
TCanvas * c1
Definition: legend1.C:2
void SetWKSize(unsigned int size)
set workspace size
TH1 * h
Definition: legend2.C:5
GaussIntegrator(double absTol=-1, double relTol=-1)
Default Constructor.
TArc * a
Definition: textangle.C:12
void SetNPoints(unsigned int n)
set number of points rule values of 1,2,3,4,5,6 corresponds to 15,21,31,41,51,61 and they are used in...
virtual double DoIntegral(double a, double b, const IGenFunction *func)
Integration surrugate method.
#define MATH_WARN_MSG(loc, str)
Definition: Error.h:47
ClassImp(TIterator) Bool_t TIterator return false
Compare two iterator objects.
Definition: TIterator.cxx:20
double IntegralLow(double b)
Returns Integral of function on a lower semi-infinite interval.
virtual void SetRelTolerance(double eps)
Set the desired relative Error.
Double_t x[n]
Definition: legend1.C:17
double IntegralCauchy(double a, double b, double c)
This method is not implemented.
double pow(double, double)
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
Definition: vector.h:450
#define MATH_ERROR_MSG(loc, str)
Definition: Error.h:50
double operator()(double x) const
void AbsValue(bool flag)
Static function: set the fgAbsValue flag.
#define MATH_INFO_MSG(loc, str)
Definition: Error.h:44
const IGenFunction * fIntegrand
virtual ~GaussIntegrator()
Destructor.
Numerical one dimensional integration options.
virtual void SetOptions(const ROOT::Math::IntegratorOneDimOptions &opt)
set the options (should be re-implemented by derived classes -if more options than tolerance exist ...
double DoEval(double x) const
implementation of the evaluation function. Must be implemented by derived classes ...
return c2
Definition: legend2.C:14
void SetFunction(const IGenFunction &)
Set integration function (flag control if function must be copied inside).
double RelTolerance() const
absolute tolerance
#define MATH_WARN_MSGVAL(loc, str, x)
Definition: Error.h:67
Auxillary inner class for mapping infinite and semi-infinite integrals.
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
Namespace for new Math classes and functions.
virtual ROOT::Math::IntegratorOneDimOptions Options() const
get the option used for the integration
double f2(const double *x)
IGenFunction * Clone() const
Clone a function.
TF1 * f1
Definition: legend1.C:11
double AbsTolerance() const
non-static methods for retrivieng options
int Status() const
return the status of the last integration - 0 in case of success
double result[121]
Int_t sign(Double_t x)
Definition: CsgOps.cxx:89
double Result() const
Returns the result of the last Integral calculation.
IntegrandTransform(const IGenFunction *integrand)
void SetIntegrator(const char *name)
set 1D integrator name
void SetRelTolerance(double tol)
set the relative tolerance
const IGenFunction * fFunction
void SetAbsTolerance(double tol)
non-static methods for setting options