00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 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 \brief Cauchy principal value integration (CERNLIB) 00035 00036 The location of the singularity must be specified before-hand in 00037 cern_cauchy::s, and the singularity must not be at one of the 00038 endpoints. Note that when integrating a function of the form 00039 \f$ \frac{f(x)}{(x-s)} \f$, the denominator \f$ (x-s) \f$ must be 00040 specified in the argument \c func to integ(). 00041 00042 The method from \ref Longman58 is used for the decomposition of 00043 the integral, and the resulting integrals are computed using 00044 cern_gauss. 00045 00046 The uncertainty in the integral is not calculated, and is always 00047 given as zero. The default base integration object is of type 00048 \ref cern_gauss. This is the CERNLIB default, but can be 00049 modified by calling set_inte(). If the singularity is outside 00050 the region of integration, then the result from the base 00051 integration object is returned without calling the error 00052 handler. 00053 00054 Possible errors for integ() and integ_err(): 00055 - gsl_einval - Singularity is on an endpoint 00056 - gsl_efailed - Couldn't reach requested accuracy 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 /// The singularity (must be set before calling integ() or integ_err()) 00095 double s; 00096 00097 /// Set the base integration object to use 00098 int set_inte(inte<param_t,func_t> &i) { 00099 it=&i; 00100 return 0; 00101 } 00102 00103 /** \brief Integrate function \c func from \c a to \c b 00104 giving result \c res and error \c err 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 \brief Integrate function \c func from \c a to \c b 00116 */ 00117 virtual double integ(func_t &func, double a, double b, param_t &pa) { 00118 double y1, y2, y3, y4; 00119 size_t itx=0; 00120 00121 if (s==a || s==b) { 00122 set_err("Singularity on boundary in cern_cauchy::integ().", 00123 gsl_einval); 00124 return 0.0; 00125 } else if ((s<a && s<b) || (s>a && s>b)) { 00126 return it->integ(func,a,b,pa); 00127 } 00128 double h, b0; 00129 if (2.0*s<a+b) { 00130 h=it->integ(func,2.0*s-a,b,pa); 00131 b0=s-a; 00132 } else { 00133 h=it->integ(func,a,2.0*s-b,pa); 00134 b0=b-s; 00135 } 00136 double c=0.005/b0; 00137 double bb=0.0; 00138 bool loop1=true; 00139 while(loop1==true) { 00140 itx++; 00141 double s8, s16; 00142 double aa=bb; 00143 bb=b0; 00144 bool loop2=true; 00145 while(loop2==true) { 00146 double c1=(bb+aa)/2.0; 00147 double c2=(bb-aa)/2.0; 00148 double c3=s+c1; 00149 double c4=s-c1; 00150 s8=0.0; 00151 s16=0.0; 00152 for(int i=0;i<4;i++) { 00153 double u=c2*x[i]; 00154 func(c3+u,y1,pa); 00155 func(c4-u,y2,pa); 00156 func(c3-u,y3,pa); 00157 func(c4+u,y4,pa); 00158 s8+=w[i]*((y1+y2)+(y3+y4)); 00159 } 00160 s8*=c2; 00161 for(int i=4;i<12;i++) { 00162 double u=c2*x[i]; 00163 func(c3+u,y1,pa); 00164 func(c4-u,y2,pa); 00165 func(c3-u,y3,pa); 00166 func(c4+u,y4,pa); 00167 s16+=w[i]*((y1+y2)+(y3+y4)); 00168 } 00169 s16*=c2; 00170 00171 if (fabs(s16-s8)<=this->tolf*(1.0+fabs(s16))) { 00172 loop2=false; 00173 } else { 00174 bb=c1; 00175 if ((1.0+fabs(c*c2))==1.0) { 00176 loop2=false; 00177 } else { 00178 this->last_iter=itx; 00179 set_err 00180 ("Couldn't reach required accuracy in cern_cauchy::integ()", 00181 gsl_efailed); 00182 return 0.0; 00183 } 00184 } 00185 } 00186 h+=s16; 00187 if (bb==b0) loop1=false; 00188 } 00189 this->last_iter=itx; 00190 return h; 00191 } 00192 00193 /// Default integration object 00194 cern_gauss<param_t, func_t> def_inte; 00195 00196 protected: 00197 00198 #ifndef DOXYGEN_INTERNAL 00199 00200 /** \name Integration constants 00201 */ 00202 //@{ 00203 double x[12], w[12]; 00204 //@} 00205 00206 /// The base integration object 00207 inte<param_t, func_t> *it; 00208 00209 #endif 00210 00211 }; 00212 00213 #ifndef DOXYGENP 00214 } 00215 #endif 00216 00217 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page