All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inte_gauss_cern.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2014, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 /** \file inte_gauss_cern.h
24  \brief File defining \ref o2scl::inte_gauss_cern
25 */
26 #ifndef O2SCL_CERN_GAUSS_H
27 #define O2SCL_CERN_GAUSS_H
28 
29 #include <o2scl/inte.h>
30 
31 #ifndef DOXYGEN_NO_O2NS
32 namespace o2scl {
33 #endif
34 
35  /** \brief Gaussian quadrature (CERNLIB)
36 
37  For any interval \f$ (a,b) \f$, we define \f$ g_8(a,b) \f$ and
38  \f$ g_{16}(a,b) \f$ to be the 8- and 16-point Gaussian
39  quadrature approximations to
40  \f[
41  I=\int_a^b f(x)~dx
42  \f]
43  and define
44  \f[
45  r(a,b)=\frac{|g_{16}(a,b)-g_{8}(a,b)|}{1+g_{16}(a,b)}
46  \f]
47  The function integ() returns \f$ G \f$ given by
48  \f[
49  G=\sum_{i=1}^{k} g_{16}(x_{i-1},x_i)
50  \f]
51  where \f$ x_0=a \f$ and \f$ x_k=b \f$ and the subdivision
52  points \f$ x_i \f$ are given by
53  \f[
54  x_i=x_{i-1}+\lambda(B-x_{i-1})
55  \f]
56  where \f$ \lambda \f$ is the first number in the sequence \f$
57  1,\frac{1}{2},\frac{1}{4},... \f$ for which
58  \f[
59  r(x_{i-1},x_i)<\mathrm{eps}.
60  \f]
61  If, at any stage, the ratio
62  \f[
63  q=\left| \frac{x_i-x_{i-1}}{b-a} \right|
64  \f]
65  is so small so that \f$ 1+0.005 q \f$ is indistinguishable from
66  unity, then the accuracy is required is not reachable and
67  the error handler is called.
68 
69  Unless there is severe cancellation, inte::tol_rel may be
70  considered as specifying a bound on the relative error of the
71  integral in the case that \f$ |I|>1 \f$ and an absolute error if
72  \f$ |I|<1 \f$. More precisely, if \f$ k \f$ is the number of
73  subintervals from above, and if
74  \f[
75  I_{abs} = \int_a^b |f(x)|~dx
76  \f]
77  then
78  \f[
79  \frac{|G-I|}{I_{abs}+k}<\mathrm{tol_rel}
80  \f]
81  will nearly always be true when no error is returned. For
82  functions with no singualarities in the interval, the accuracy
83  will usually be higher than this.
84 
85  If the desired accuracy is not achieved, the integration
86  functions will call the error handler and return the best guess,
87  unless \ref inte::err_nonconv is false, in which case the error
88  handler is not called.
89 
90  This function is based on the CERNLIB routines GAUSS and
91  DGAUSS which are documented at
92  http://wwwasdoc.web.cern.ch/wwwasdoc/shortwrupsdir/d103/top.html
93 
94  \future Allow user to change \c cst?
95  */
96  template<class func_t=funct11> class inte_gauss_cern : public inte<func_t> {
97 
98  public:
99 
100  inte_gauss_cern() {
101  x[0]=0.96028985649753623;
102  x[1]=0.79666647741362674;
103  x[2]=0.52553240991632899;
104  x[3]=0.18343464249564980;
105  x[4]=0.98940093499164993;
106  x[5]=0.94457502307323258;
107  x[6]=0.86563120238783175;
108  x[7]=0.75540440835500303;
109  x[8]=0.61787624440264375;
110  x[9]=0.45801677765722739;
111  x[10]=0.28160355077925891;
112  x[11]=0.95012509837637440e-1;
113 
114  w[0]=0.10122853629037626;
115  w[1]=0.22238103445337447;
116  w[2]=0.31370664587788729;
117  w[3]=0.36268378337836198;
118  w[4]=0.27152459411754095e-1;
119  w[5]=0.62253523938647893e-1;
120  w[6]=0.95158511682492785e-1;
121  w[7]=0.12462897125553387;
122  w[8]=0.14959598881657673;
123  w[9]=0.16915651939500254;
124  w[10]=0.18260341504492359;
125  w[11]=0.18945061045506850;
126  }
127 
128  /** \brief Integrate function \c func from \c a to \c b
129  giving result \c res and error \c err
130 
131  \todo Fix converge error issue here.
132  */
133  virtual int integ_err(func_t &func, double a, double b,
134  double &res, double &err) {
135  res=integ(func,a,b);
136  err=0.0;
137  //if (this->err_nonconv) return this->last_conv;
138  return success;
139  }
140 
141  /** \brief Integrate function \c func from \c a to \c b.
142  */
143  virtual double integ(func_t &func, double a, double b) {
144 
145  double y1, y2;
146 
147  size_t itx=0;
148 
149  int i;
150  bool loop=true, loop2=false;
151  static const double cst=0.005;
152  double h=0.0;
153  if (b==a) return 0.0;
154  double cnst=cst/(b-a);
155  double aa=0.0, bb=a;
156  while (loop==true || loop2==true) {
157  itx++;
158  if (loop==true) {
159  aa=bb;
160  bb=b;
161  }
162  double c1=(bb+aa)/2.0;
163  double c2=(bb-aa)/2.0;
164  double s8=0.0;
165  for(i=0;i<4;i++) {
166  double u=c2*x[i];
167  y1=func(c1+u);
168  y2=func(c1-u);
169  s8+=w[i]*(y1+y2);
170  }
171  double s16=0.0;
172  for(i=4;i<12;i++) {
173  double u=c2*x[i];
174  y1=func(c1+u);
175  y2=func(c1-u);
176  s16+=w[i]*(y1+y2);
177  }
178  s16*=c2;
179 
180  loop=false;
181  loop2=false;
182  if (fabs(s16-c2*s8)<this->tol_rel*(1.0+fabs(s16))) {
183  h+=s16;
184  if (bb!=b) loop=true;
185  } else {
186  bb=c1;
187  if (1.0+cnst*fabs(c2)!=1.0) {
188  loop2=true;
189  } else {
190  this->last_iter=itx;
191  O2SCL_CONV2("Failed to reach required accuracy in cern_",
192  "gauss::integ().",exc_efailed,this->err_nonconv);
193  return h;
194  }
195  }
196  }
197  this->last_iter=itx;
198  return h;
199  }
200 
201  protected:
202 
203 #ifndef DOXYGEN_INTERNAL
204 
205  /** \name Integration constants (Set in the constructor)
206  */
207  //@{
208  double x[12], w[12];
209  //@}
210 
211 #endif
212 
213  };
214 
215 #ifndef DOXYGEN_NO_O2NS
216 }
217 #endif
218 
219 #endif
virtual int integ_err(func_t &func, double a, double b, double &res, double &err)
Integrate function func from a to b giving result res and error err.
size_t last_iter
The most recent number of iterations taken.
Definition: inte.h:63
bool err_nonconv
If true, call the error handler if the routine does not converge or reach the desired tolerance (defa...
Definition: inte.h:81
generic failure
Definition: err_hnd.h:61
Base integration class [abstract base].
Definition: inte.h:44
#define O2SCL_CONV2(d, d2, n, b)
Set a "convergence" error, two-string version.
Definition: err_hnd.h:286
double tol_rel
The maximum relative uncertainty in the value of the integral (default )
Definition: inte.h:68
virtual double integ(func_t &func, double a, double b)
Integrate function func from a to b.
Gaussian quadrature (CERNLIB)
Success.
Definition: err_hnd.h:47

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..