ROOT  6.06/09
Reference Guide
GaussLegendreIntegrator.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 
12 #include <cmath>
13 #include <string.h>
14 #include <algorithm>
15 
16 namespace ROOT {
17 namespace Math {
18 
20  GaussIntegrator(eps, eps)
21 {
22  // Basic contructor
23  fNum = num;
24  fX = 0;
25  fW = 0;
26 
28 }
29 
31 {
32  // Default Destructor
33 
34 
35  delete [] fX;
36  delete [] fW;
37 }
38 
40 {
41  // Set the number of points used in the calculation of the integral
42 
43  fNum = num;
45 }
46 
47 void GaussLegendreIntegrator::GetWeightVectors(double *x, double *w) const
48 {
49  // Returns the arrays x and w.
50 
51  std::copy(fX,fX+fNum, x);
52  std::copy(fW,fW+fNum, w);
53 }
54 
55 
56 double GaussLegendreIntegrator::DoIntegral(double a, double b, const IGenFunction* function)
57 {
58  // Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints.
59 
60  if (fNum<=0 || fX == 0 || fW == 0)
61  return 0;
62 
63  fUsedOnce = true;
64 
65  const double a0 = (b + a)/2;
66  const double b0 = (b - a)/2;
67 
68  double xx[1];
69 
70  double result = 0.0;
71  for (int i=0; i<fNum; i++)
72  {
73  xx[0] = a0 + b0*fX[i];
74  result += fW[i] * (*function)(xx);
75  }
76 
77  fLastResult = result*b0;
78  return fLastResult;
79 }
80 
81 
83 {
84  // Set the desired relative Error.
85  fEpsRel = eps;
87 }
88 
90 { MATH_WARN_MSG("ROOT::Math::GaussLegendreIntegrator", "There is no Absolute Tolerance!"); }
91 
92 
93 
95 {
96  // Given the number of sampling points this routine fills the
97  // arrays x and w.
98 
99  if (fNum<=0 || fEpsRel<=0)
100  return;
101 
102  if ( fX == 0 )
103  delete [] fX;
104 
105  if ( fW == 0 )
106  delete [] fW;
107 
108  fX = new double[fNum];
109  fW = new double[fNum];
110 
111  // The roots of symmetric is the interval, so we only have to find half of them
112  const unsigned int m = (fNum+1)/2;
113 
114  double z, pp, p1,p2, p3;
115 
116  // Loop over the desired roots
117  for (unsigned int i=0; i<m; i++) {
118  z = std::cos(3.14159265358979323846*(i+0.75)/(fNum+0.5));
119 
120  // Starting with the above approximation to the i-th root, we enter
121  // the main loop of refinement by Newton's method
122  do {
123  p1=1.0;
124  p2=0.0;
125 
126  // Loop up the recurrence relation to get the Legendre
127  // polynomial evaluated at z
128  for (int j=0; j<fNum; j++)
129  {
130  p3 = p2;
131  p2 = p1;
132  p1 = ((2.0*j+1.0)*z*p2-j*p3)/(j+1.0);
133  }
134  // p1 is now the desired Legendre polynomial. We next compute pp, its
135  // derivative, by a standard relation involving also p2, the polynomial
136  // of one lower order
137  pp = fNum*(z*p1-p2)/(z*z-1.0);
138  // Newton's method
139  z -= p1/pp;
140 
141  } while (std::fabs(p1/pp) > fEpsRel);
142 
143  // Put root and its symmetric counterpart
144  fX[i] = -z;
145  fX[fNum-i-1] = z;
146 
147  // Compute the weight and put its symmetric counterpart
148  fW[i] = 2.0/((1.0-z*z)*pp*pp);
149  fW[fNum-i-1] = fW[i];
150  }
151 }
152 
155  opt.SetAbsTolerance(0);
157  opt.SetWKSize(0);
158  opt.SetNPoints(fNum);
159  opt.SetIntegrator("GaussLegendre");
160  return opt;
161 }
162 
164 {
165  // set integration options
166 // std::cout << "fEpsilon = " << fEpsilon << std::endl;
167 // std::cout << opt.RelTolerance() << " abs " << opt.AbsTolerance() << std::endl;
168  //double tol = opt.RelTolerance(); fEpsilon = tol;
169  fEpsRel = opt.RelTolerance();
170 // std::cout << "fEpsilon = " << fEpsilon << std::endl;
171  fNum = opt.NPoints();
172  if (fNum <= 7) MATH_WARN_MSGVAL("GaussLegendreIntegrator::SetOptions","setting a low number of points ",fNum);
174 }
175 
176 } // end namespace Math
177 } // end namespace ROOT
virtual ROOT::Math::IntegratorOneDimOptions Options() const
get the option used for the integration
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition: IFunction.h:133
static double p3(double t, double a, double b, double c, double d)
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
void SetWKSize(unsigned int size)
set workspace size
GaussLegendreIntegrator(int num=10, double eps=1e-12)
Basic contructor of GaussLegendreIntegrator.
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...
void CalcGaussLegendreSamplingPoints()
Type: unsafe but fast interface filling the arrays x and w (static method)
#define MATH_WARN_MSG(loc, str)
Definition: Error.h:47
double cos(double)
virtual double DoIntegral(double a, double b, const IGenFunction *func)
Integration surrugate method.
Double_t x[n]
Definition: legend1.C:17
void GetWeightVectors(double *x, double *w) const
Returns the arrays x and w containing the abscissa and weight of the Gauss-Legendre n-point quadratur...
static double p2(double t, double a, double b, double c)
virtual void SetOptions(const ROOT::Math::IntegratorOneDimOptions &opt)
set the options (should be re-implemented by derived classes -if more options than tolerance exist ...
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
virtual ~GaussLegendreIntegrator()
Default Destructor.
virtual void SetRelTolerance(double)
Set the desired relative Error.
Numerical one dimensional integration options.
TMarker * m
Definition: textangle.C:8
User class for performing function integration.
static double p1(double t, double a, double b)
void SetNumberPoints(int num)
Set the number of points used in the calculation of the integral.
double RelTolerance() const
absolute tolerance
#define MATH_WARN_MSGVAL(loc, str, x)
Definition: Error.h:67
Namespace for new Math classes and functions.
virtual void SetAbsTolerance(double)
This method is not implemented.
unsigned int NPoints() const
maximum number of function calls
double result[121]
void SetIntegrator(const char *name)
set 1D integrator name
void SetRelTolerance(double tol)
set the relative tolerance
void SetAbsTolerance(double tol)
non-static methods for setting options