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_CAUCHY_H
00024 #define O2SCL_CERN_CAUCHY_H
00025
00026 #include <o2scl/inte.h>
00027 #include <o2scl/cern_gauss.h>
00028
00029 #ifndef DOXYGENP
00030 namespace o2scl {
00031 #endif
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 template<class param_t, class func_t> class cern_cauchy :
00060 public inte<param_t,func_t> {
00061
00062 public:
00063
00064 cern_cauchy() {
00065 x[0]=0.96028985649753623;
00066 x[1]=0.79666647741362674;
00067 x[2]=0.52553240991632899;
00068 x[3]=0.18343464249564980;
00069 x[4]=0.98940093499164993;
00070 x[5]=0.94457502307323258;
00071 x[6]=0.86563120238783175;
00072 x[7]=0.75540440835500303;
00073 x[8]=0.61787624440264375;
00074 x[9]=0.45801677765722739;
00075 x[10]=0.28160355077925891;
00076 x[11]=0.95012509837637440e-1;
00077
00078 w[0]=0.10122853629037626;
00079 w[1]=0.22238103445337447;
00080 w[2]=0.31370664587788729;
00081 w[3]=0.36268378337836198;
00082 w[4]=0.27152459411754095e-1;
00083 w[5]=0.62253523938647893e-1;
00084 w[6]=0.95158511682492785e-1;
00085 w[7]=0.12462897125553387;
00086 w[8]=0.14959598881657673;
00087 w[9]=0.16915651939500254;
00088 w[10]=0.18260341504492359;
00089 w[11]=0.18945061045506850;
00090
00091 it=&def_inte;
00092 }
00093
00094
00095 double s;
00096
00097
00098 int set_inte(inte<param_t,func_t> &i) {
00099 it=&i;
00100 return 0;
00101 }
00102
00103
00104
00105
00106 virtual int integ_err(func_t &func, double a, double b, param_t &pa,
00107 double &res, double &err) {
00108 res=integ(func,a,b,pa);
00109 err=0.0;
00110 return 0;
00111 }
00112
00113
00114
00115
00116
00117 virtual double integ(func_t &func, double a, double b, param_t &pa) {
00118 double y1, y2, y3, y4;
00119
00120 if (s==a || s==b) {
00121 set_err("Singularity on boundary in cern_cauchy::integ().",
00122 gsl_einval);
00123 return 0.0;
00124 } else if ((s<a && s<b) || (s>a && s>b)) {
00125 return it->integ(func,a,b,pa);
00126 }
00127 double h, b0;
00128 if (2.0*s<a+b) {
00129 h=it->integ(func,2.0*s-a,b,pa);
00130 b0=s-a;
00131 } else {
00132 h=it->integ(func,a,2.0*s-b,pa);
00133 b0=b-s;
00134 }
00135 double c=0.005/b0;
00136 double bb=0.0;
00137 bool loop1=true;
00138 while(loop1==true) {
00139 double s8, s16;
00140 double aa=bb;
00141 bb=b0;
00142 bool loop2=true;
00143 while(loop2==true) {
00144 double c1=(bb+aa)/2.0;
00145 double c2=(bb-aa)/2.0;
00146 double c3=s+c1;
00147 double c4=s-c1;
00148 s8=0.0;
00149 s16=0.0;
00150 for(int i=0;i<4;i++) {
00151 double u=c2*x[i];
00152 func(c3+u,y1,pa);
00153 func(c4-u,y2,pa);
00154 func(c3-u,y3,pa);
00155 func(c4+u,y4,pa);
00156 s8+=w[i]*((y1+y2)+(y3+y4));
00157 }
00158 s8*=c2;
00159 for(int i=4;i<12;i++) {
00160 double u=c2*x[i];
00161 func(c3+u,y1,pa);
00162 func(c4-u,y2,pa);
00163 func(c3-u,y3,pa);
00164 func(c4+u,y4,pa);
00165 s16+=w[i]*((y1+y2)+(y3+y4));
00166 }
00167 s16*=c2;
00168
00169 if (fabs(s16-s8)<=this->tolf*(1.0+fabs(s16))) {
00170 loop2=false;
00171 } else {
00172 bb=c1;
00173 if ((1.0+fabs(c*c2))==1.0) {
00174 loop2=false;
00175 } else {
00176 set_err
00177 ("Couldn't reach required accuracy in cern_cauchy::integ()",
00178 gsl_efailed);
00179 return 0.0;
00180 }
00181 }
00182 }
00183 h+=s16;
00184 if (bb==b0) loop1=false;
00185 }
00186 return h;
00187 }
00188
00189
00190 cern_gauss<param_t, func_t> def_inte;
00191
00192 protected:
00193
00194 #ifndef DOXYGEN_INTERNAL
00195
00196
00197
00198
00199 double x[12], w[12];
00200
00201
00202
00203 inte<param_t, func_t> *it;
00204
00205 #endif
00206
00207 };
00208
00209 #ifndef DOXYGENP
00210 }
00211 #endif
00212
00213 #endif