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_GSL_INTE_QNG_H
00024 #define O2SCL_GSL_INTE_QNG_H
00025
00026 #include <o2scl/inte.h>
00027 #include <o2scl/gsl_inte.h>
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 namespace o2scl_inte_qng_coeffs {
00040
00041
00042 static const double x1[5] = {
00043 0.973906528517171720077964012084452,
00044 0.865063366688984510732096688423493,
00045 0.679409568299024406234327365114874,
00046 0.433395394129247190799265943165784,
00047 0.148874338981631210884826001129720
00048 } ;
00049
00050
00051 static const double w10[5] = {
00052 0.066671344308688137593568809893332,
00053 0.149451349150580593145776339657697,
00054 0.219086362515982043995534934228163,
00055 0.269266719309996355091226921569469,
00056 0.295524224714752870173892994651338
00057 } ;
00058
00059
00060 static const double x2[5] = {
00061 0.995657163025808080735527280689003,
00062 0.930157491355708226001207180059508,
00063 0.780817726586416897063717578345042,
00064 0.562757134668604683339000099272694,
00065 0.294392862701460198131126603103866
00066 } ;
00067
00068
00069 static const double w21a[5] = {
00070 0.032558162307964727478818972459390,
00071 0.075039674810919952767043140916190,
00072 0.109387158802297641899210590325805,
00073 0.134709217311473325928054001771707,
00074 0.147739104901338491374841515972068
00075 } ;
00076
00077
00078 static const double w21b[6] = {
00079 0.011694638867371874278064396062192,
00080 0.054755896574351996031381300244580,
00081 0.093125454583697605535065465083366,
00082 0.123491976262065851077958109831074,
00083 0.142775938577060080797094273138717,
00084 0.149445554002916905664936468389821
00085 } ;
00086
00087
00088 static const double x3[11] = {
00089 0.999333360901932081394099323919911,
00090 0.987433402908088869795961478381209,
00091 0.954807934814266299257919200290473,
00092 0.900148695748328293625099494069092,
00093 0.825198314983114150847066732588520,
00094 0.732148388989304982612354848755461,
00095 0.622847970537725238641159120344323,
00096 0.499479574071056499952214885499755,
00097 0.364901661346580768043989548502644,
00098 0.222254919776601296498260928066212,
00099 0.074650617461383322043914435796506
00100 } ;
00101
00102
00103 static const double w43a[10] = {
00104 0.016296734289666564924281974617663,
00105 0.037522876120869501461613795898115,
00106 0.054694902058255442147212685465005,
00107 0.067355414609478086075553166302174,
00108 0.073870199632393953432140695251367,
00109 0.005768556059769796184184327908655,
00110 0.027371890593248842081276069289151,
00111 0.046560826910428830743339154433824,
00112 0.061744995201442564496240336030883,
00113 0.071387267268693397768559114425516
00114 } ;
00115
00116
00117 static const double w43b[12] = {
00118 0.001844477640212414100389106552965,
00119 0.010798689585891651740465406741293,
00120 0.021895363867795428102523123075149,
00121 0.032597463975345689443882222526137,
00122 0.042163137935191811847627924327955,
00123 0.050741939600184577780189020092084,
00124 0.058379395542619248375475369330206,
00125 0.064746404951445885544689259517511,
00126 0.069566197912356484528633315038405,
00127 0.072824441471833208150939535192842,
00128 0.074507751014175118273571813842889,
00129 0.074722147517403005594425168280423
00130 } ;
00131
00132
00133 static const double x4[22] = {
00134 0.999902977262729234490529830591582,
00135 0.997989895986678745427496322365960,
00136 0.992175497860687222808523352251425,
00137 0.981358163572712773571916941623894,
00138 0.965057623858384619128284110607926,
00139 0.943167613133670596816416634507426,
00140 0.915806414685507209591826430720050,
00141 0.883221657771316501372117548744163,
00142 0.845710748462415666605902011504855,
00143 0.803557658035230982788739474980964,
00144 0.757005730685495558328942793432020,
00145 0.706273209787321819824094274740840,
00146 0.651589466501177922534422205016736,
00147 0.593223374057961088875273770349144,
00148 0.531493605970831932285268948562671,
00149 0.466763623042022844871966781659270,
00150 0.399424847859218804732101665817923,
00151 0.329874877106188288265053371824597,
00152 0.258503559202161551802280975429025,
00153 0.185695396568346652015917141167606,
00154 0.111842213179907468172398359241362,
00155 0.037352123394619870814998165437704
00156 } ;
00157
00158
00159 static const double w87a[21] = {
00160 0.008148377384149172900002878448190,
00161 0.018761438201562822243935059003794,
00162 0.027347451050052286161582829741283,
00163 0.033677707311637930046581056957588,
00164 0.036935099820427907614589586742499,
00165 0.002884872430211530501334156248695,
00166 0.013685946022712701888950035273128,
00167 0.023280413502888311123409291030404,
00168 0.030872497611713358675466394126442,
00169 0.035693633639418770719351355457044,
00170 0.000915283345202241360843392549948,
00171 0.005399280219300471367738743391053,
00172 0.010947679601118931134327826856808,
00173 0.016298731696787335262665703223280,
00174 0.021081568889203835112433060188190,
00175 0.025370969769253827243467999831710,
00176 0.029189697756475752501446154084920,
00177 0.032373202467202789685788194889595,
00178 0.034783098950365142750781997949596,
00179 0.036412220731351787562801163687577,
00180 0.037253875503047708539592001191226
00181 } ;
00182
00183
00184 static const double w87b[23] = {
00185 0.000274145563762072350016527092881,
00186 0.001807124155057942948341311753254,
00187 0.004096869282759164864458070683480,
00188 0.006758290051847378699816577897424,
00189 0.009549957672201646536053581325377,
00190 0.012329447652244853694626639963780,
00191 0.015010447346388952376697286041943,
00192 0.017548967986243191099665352925900,
00193 0.019938037786440888202278192730714,
00194 0.022194935961012286796332102959499,
00195 0.024339147126000805470360647041454,
00196 0.026374505414839207241503786552615,
00197 0.028286910788771200659968002987960,
00198 0.030052581128092695322521110347341,
00199 0.031646751371439929404586051078883,
00200 0.033050413419978503290785944862689,
00201 0.034255099704226061787082821046821,
00202 0.035262412660156681033782717998428,
00203 0.036076989622888701185500318003895,
00204 0.036698604498456094498018047441094,
00205 0.037120549269832576114119958413599,
00206 0.037334228751935040321235449094698,
00207 0.037361073762679023410321241766599
00208 } ;
00209
00210 }
00211
00212 #ifndef DOXYGENP
00213 namespace o2scl {
00214 #endif
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 template<class param_t, class func_t> class gsl_inte_qng :
00225 public inte<param_t,func_t>, public gsl_inte {
00226
00227 public:
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 size_t feval;
00240
00241
00242
00243 virtual double integ(func_t &func, double a, double b, param_t &pa) {
00244 double res, err;
00245 integ_err(func,a,b,pa,res,err);
00246 this->interror=err;
00247 return res;
00248 }
00249
00250
00251
00252
00253 virtual int integ_err(func_t &func, double a, double b,
00254 param_t &pa, double &res, double &err2) {
00255
00256 double fv1[5], fv2[5], fv3[5], fv4[5];
00257
00258
00259 double savfun[21];
00260
00261
00262 double res10, res21, res43, res87;
00263
00264 double result_kronrod, err;
00265
00266
00267 double resabs;
00268
00269
00270 double resasc;
00271
00272 const double o2sclf_length = 0.5 * (b - a);
00273 const double abs_o2sclf_length = fabs (o2sclf_length);
00274 const double center = 0.5 * (b + a);
00275
00276 double f_center;
00277 func(center,f_center,pa);
00278
00279 int k;
00280
00281 if (this->tolx <= 0 && (this->tolf < 50 * GSL_DBL_EPSILON ||
00282 this->tolf < 0.5e-28)) {
00283 res = 0;
00284 err2 = 0;
00285 feval = 0;
00286 GSL_ERROR
00287 ("tolerance cannot be acheived with given tolx and tolf",
00288 GSL_EBADTOL);
00289 };
00290
00291
00292
00293 res10 = 0;
00294 res21 = o2scl_inte_qng_coeffs::w21b[5] * f_center;
00295 resabs = o2scl_inte_qng_coeffs::w21b[5] * fabs (f_center);
00296
00297
00298 for (k = 0; k < 5; k++) {
00299 const double abscissa = o2sclf_length * o2scl_inte_qng_coeffs::x1[k];
00300 double fval1, fval2;
00301 func(center+abscissa,fval1,pa);
00302 func(center-abscissa,fval2,pa);
00303 const double fval = fval1 + fval2;
00304 res10 += o2scl_inte_qng_coeffs::w10[k] * fval;
00305 res21 += o2scl_inte_qng_coeffs::w21a[k] * fval;
00306 resabs += o2scl_inte_qng_coeffs::w21a[k] *
00307 (fabs (fval1) + fabs (fval2));
00308 savfun[k] = fval;
00309 fv1[k] = fval1;
00310 fv2[k] = fval2;
00311 }
00312
00313 for (k = 0; k < 5; k++) {
00314 const double abscissa = o2sclf_length * o2scl_inte_qng_coeffs::x2[k];
00315 double fval1, fval2;
00316 func(center+abscissa,fval1,pa);
00317 func(center-abscissa,fval2,pa);
00318 const double fval = fval1 + fval2;
00319 res21 += o2scl_inte_qng_coeffs::w21b[k] * fval;
00320 resabs += o2scl_inte_qng_coeffs::w21b[k] *
00321 (fabs (fval1) + fabs (fval2));
00322 savfun[k + 5] = fval;
00323 fv3[k] = fval1;
00324 fv4[k] = fval2;
00325 }
00326
00327 resabs *= abs_o2sclf_length ;
00328
00329 {
00330 const double mean = 0.5 * res21;
00331
00332 resasc = o2scl_inte_qng_coeffs::w21b[5] * fabs (f_center - mean);
00333
00334 for (k = 0; k < 5; k++) {
00335 resasc +=
00336 (o2scl_inte_qng_coeffs::w21a[k] * (fabs (fv1[k] - mean) +
00337 fabs (fv2[k] - mean))
00338 + o2scl_inte_qng_coeffs::w21b[k] * (fabs (fv3[k] - mean) +
00339 fabs (fv4[k] - mean)));
00340 }
00341 resasc *= abs_o2sclf_length ;
00342 }
00343
00344 result_kronrod = res21 * o2sclf_length;
00345
00346 err = rescale_error ((res21 - res10) * o2sclf_length, resabs, resasc) ;
00347
00348
00349
00350 if (err < this->tolx || err < this->tolf * fabs (result_kronrod)) {
00351 res = result_kronrod ;
00352 err2 = err ;
00353 feval = 21;
00354 return gsl_success;
00355 }
00356
00357
00358
00359 res43 = o2scl_inte_qng_coeffs::w43b[11] * f_center;
00360
00361 for (k = 0; k < 10; k++) {
00362 res43 += savfun[k] * o2scl_inte_qng_coeffs::w43a[k];
00363 }
00364
00365 for (k = 0; k < 11; k++) {
00366 const double abscissa = o2sclf_length * o2scl_inte_qng_coeffs::x3[k];
00367 double fval1, fval2;
00368 func(center+abscissa,fval1,pa);
00369 func(center-abscissa,fval2,pa);
00370 const double fval = fval1+fval2;
00371 res43 += fval * o2scl_inte_qng_coeffs::w43b[k];
00372 savfun[k + 10] = fval;
00373 }
00374
00375
00376 result_kronrod = res43 * o2sclf_length;
00377 err = rescale_error ((res43 - res21) * o2sclf_length, resabs, resasc);
00378
00379 if (err < this->tolx || err < this->tolf * fabs (result_kronrod)) {
00380 res = result_kronrod ;
00381 err2 = err ;
00382 feval = 43;
00383 return gsl_success;
00384 }
00385
00386
00387
00388 res87 = o2scl_inte_qng_coeffs::w87b[22] * f_center;
00389
00390 for (k = 0; k < 21; k++) {
00391 res87 += savfun[k] * o2scl_inte_qng_coeffs::w87a[k];
00392 }
00393
00394 for (k = 0; k < 22; k++) {
00395 const double abscissa = o2sclf_length * o2scl_inte_qng_coeffs::x4[k];
00396 double fval1, fval2;
00397 func(center+abscissa,fval1,pa);
00398 func(center-abscissa,fval2,pa);
00399 res87 += o2scl_inte_qng_coeffs::w87b[k] * (fval1+fval2);
00400 }
00401
00402
00403
00404 result_kronrod = res87 * o2sclf_length ;
00405
00406 err = rescale_error ((res87 - res43) * o2sclf_length, resabs, resasc);
00407
00408 if (err < this->tolx || err < this->tolf * fabs (result_kronrod)) {
00409 res = result_kronrod ;
00410 err2 = err ;
00411 feval = 87;
00412 return gsl_success;
00413 }
00414
00415
00416 res = result_kronrod ;
00417 err2 = err ;
00418 feval = 88;
00419
00420 GSL_ERROR("failed to reach tolerance with highest-order rule",
00421 GSL_ETOL) ;
00422
00423 }
00424
00425
00426 const char *type() { return "gsl_inte_qng"; }
00427
00428 };
00429
00430 #ifndef DOXYGENP
00431 }
00432 #endif
00433
00434 #endif