00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef O2SCL_CERN_GAUSS_H
00024 #define O2SCL_CERN_GAUSS_H
00025
00026 #include <o2scl/inte.h>
00027
00028 #ifndef DOXYGENP
00029 namespace o2scl {
00030 #endif
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 template<class param_t, class func_t> class cern_gauss :
00085 public inte<param_t,func_t> {
00086
00087 public:
00088
00089 cern_gauss() {
00090 x[0]=0.96028985649753623;
00091 x[1]=0.79666647741362674;
00092 x[2]=0.52553240991632899;
00093 x[3]=0.18343464249564980;
00094 x[4]=0.98940093499164993;
00095 x[5]=0.94457502307323258;
00096 x[6]=0.86563120238783175;
00097 x[7]=0.75540440835500303;
00098 x[8]=0.61787624440264375;
00099 x[9]=0.45801677765722739;
00100 x[10]=0.28160355077925891;
00101 x[11]=0.95012509837637440e-1;
00102
00103 w[0]=0.10122853629037626;
00104 w[1]=0.22238103445337447;
00105 w[2]=0.31370664587788729;
00106 w[3]=0.36268378337836198;
00107 w[4]=0.27152459411754095e-1;
00108 w[5]=0.62253523938647893e-1;
00109 w[6]=0.95158511682492785e-1;
00110 w[7]=0.12462897125553387;
00111 w[8]=0.14959598881657673;
00112 w[9]=0.16915651939500254;
00113 w[10]=0.18260341504492359;
00114 w[11]=0.18945061045506850;
00115 }
00116
00117
00118
00119
00120 virtual int integ_err(func_t &func, double a, double b, param_t &pa,
00121 double &res, double &err) {
00122 err_hnd->reset();
00123 res=integ(func,a,b,pa);
00124 err=0.0;
00125 return err_hnd->get_errno();
00126 }
00127
00128
00129
00130
00131 virtual double integ(func_t &func, double a, double b, param_t &pa) {
00132
00133 double y1, y2;
00134
00135 int i;
00136 bool loop=true, loop2=false;
00137 static const double cst=0.005;
00138 double h=0.0;
00139 if (b==a) return 0.0;
00140 double cnst=cst/(b-a);
00141 double aa=0.0, bb=a;
00142 while (loop==true || loop2==true) {
00143 if (loop==true) {
00144 aa=bb;
00145 bb=b;
00146 }
00147 double c1=(bb+aa)/2.0;
00148 double c2=(bb-aa)/2.0;
00149 double s8=0.0;
00150 for(i=0;i<4;i++) {
00151 double u=c2*x[i];
00152 func(c1+u,y1,pa);
00153 func(c1-u,y2,pa);
00154 s8+=w[i]*(y1+y2);
00155 }
00156 double s16=0.0;
00157 for(i=4;i<12;i++) {
00158 double u=c2*x[i];
00159 func(c1+u,y1,pa);
00160 func(c1-u,y2,pa);
00161 s16+=w[i]*(y1+y2);
00162 }
00163 s16*=c2;
00164
00165 loop=false;
00166 loop2=false;
00167 if (fabs(s16-c2*s8)<this->tolf*(1.0+fabs(s16))) {
00168 h+=s16;
00169 if (bb!=b) loop=true;
00170 } else {
00171 bb=c1;
00172 if (1.0+cnst*fabs(c2)!=1.0) {
00173 loop2=true;
00174 } else {
00175 set_err
00176 ("Failed to reach required accuracy in cern_gauss::integ().",
00177 gsl_efailed);
00178 return 0.0;
00179 }
00180 }
00181 }
00182 return h;
00183 }
00184
00185 protected:
00186
00187 #ifndef DOXYGEN_INTERNAL
00188
00189
00190
00191
00192 double x[12], w[12];
00193
00194
00195 #endif
00196
00197 };
00198
00199 #ifndef DOXYGENP
00200 }
00201 #endif
00202
00203 #endif