![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, Jerry Gagelman 00005 and Andrew W. Steiner 00006 00007 This file is part of O2scl. 00008 00009 O2scl is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 O2scl is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00021 00022 ------------------------------------------------------------------- 00023 */ 00024 #ifndef O2SCL_GSL_INTE_SINGULAR_H 00025 #define O2SCL_GSL_INTE_SINGULAR_H 00026 00027 #include <cmath> 00028 00029 #include <gsl/gsl_integration.h> 00030 00031 #include <o2scl/string_conv.h> 00032 #include <o2scl/inte.h> 00033 #include <o2scl/gsl_inte_kronrod.h> 00034 00035 #ifndef DOXYGENP 00036 namespace o2scl { 00037 #endif 00038 00039 /** \brief Base class for integrating a function with a 00040 singularity (GSL) 00041 00042 This class contains the extrapolation table mechanics and the 00043 base integration function for singular integrals from GSL. The 00044 casual end-user should use the classes explained in the 00045 \ref inte_section section of the User's guide. 00046 00047 \future Some of the functions inside this class could 00048 be moved out of header files? 00049 */ 00050 template<class func_t> class gsl_inte_singular : 00051 public gsl_inte_kronrod<func_t> { 00052 00053 public: 00054 00055 /** \brief A structure for extrapolation for \ref gsl_inte_qags 00056 00057 \future Move this to a new class, with qelg() as a method 00058 */ 00059 typedef struct extrapolation_table { 00060 /// Index of new element in the first column 00061 size_t n; 00062 /// Lower diagonals of the triangular epsilon table 00063 double rlist2[52]; 00064 /// Number of calls 00065 size_t nres; 00066 /// Three most recent results 00067 double res3la[3]; 00068 } extrap_table; 00069 00070 protected: 00071 00072 /// Initialize the table 00073 void initialise_table(struct extrapolation_table *table) { 00074 table->n = 0; 00075 table->nres = 0; 00076 return; 00077 } 00078 00079 /// Append a result to the table 00080 void append_table(struct extrapolation_table *table, double y) { 00081 size_t n; 00082 n = table->n; 00083 table->rlist2[n] = y; 00084 table->n++; 00085 return; 00086 } 00087 00088 /** \brief Test if the integrand satisfies \f$ f = |f| \f$ 00089 */ 00090 inline int test_positivity(double result, double resabs) { 00091 int status = (fabs (result) >= (1 - 50 * GSL_DBL_EPSILON) * resabs); 00092 return status; 00093 } 00094 00095 /** \brief Determines the limit of a given sequence 00096 of approximations 00097 00098 For certain convergent series \f$ \sum_k a_k \f$ whose error 00099 term \f$ E_n = \sum_{k=n}^\infty a_k \f$ is well behaved, it 00100 is possible to find a transformation of the sequence that 00101 yields a faster converging series to the same limit. This 00102 method of extrapolation applies to some sequences of 00103 adaptive-approximation and error-estimation for numerical 00104 integration. This function implements the \f$ 00105 \varepsilon\f$-algorithm (\ref Wynn56, \ref Piessens83) for an 00106 extrapolation table stored in \c table. 00107 00108 Quadpack documentation 00109 \verbatim 00110 c 00111 c list of major variables 00112 c ----------------------- 00113 c e0 - the 4 elements on which the computation of a new 00114 c e1 element in the epsilon table is based 00115 c e2 00116 c e3 e0 00117 c e3 e1 new 00118 c e2 00119 c newelm - number of elements to be computed in the new 00120 c diagonal 00121 c error - error = abs(e1-e0)+abs(e2-e1)+abs(new-e2) 00122 c result - the element in the new diagonal with least value 00123 c of error 00124 c 00125 c machine dependent constants 00126 c --------------------------- 00127 c 00128 c epmach is the largest relative spacing. 00129 c oflow is the largest positive magnitude. 00130 c limexp is the maximum number of elements the epsilon 00131 c table can contain. if this number is reached, the upper 00132 c diagonal of the epsilon table is deleted. 00133 c 00134 \endverbatim 00135 */ 00136 void qelg(struct extrapolation_table *table, double *result, 00137 double *abserr) { 00138 00139 double *epstab = table->rlist2; 00140 double *res3la = table->res3la; 00141 const size_t n = table->n - 1; 00142 00143 const double current = epstab[n]; 00144 00145 double absolute = GSL_DBL_MAX; 00146 double relative = 5 * GSL_DBL_EPSILON * fabs (current); 00147 00148 const size_t newelm = n / 2; 00149 const size_t n_orig = n; 00150 size_t n_final = n; 00151 size_t i; 00152 00153 const size_t nres_orig = table->nres; 00154 00155 *result = current; 00156 *abserr = GSL_DBL_MAX; 00157 00158 if (n < 2) { 00159 *result = current; 00160 *abserr = GSL_MAX_DBL (absolute, relative); 00161 return; 00162 } 00163 00164 epstab[n + 2] = epstab[n]; 00165 epstab[n] = GSL_DBL_MAX; 00166 00167 for (i = 0; i < newelm; i++) { 00168 double res = epstab[n - 2 * i + 2]; 00169 double e0 = epstab[n - 2 * i - 2]; 00170 double e1 = epstab[n - 2 * i - 1]; 00171 double e2 = res; 00172 00173 double e1abs = fabs (e1); 00174 double delta2 = e2 - e1; 00175 double err2 = fabs (delta2); 00176 double tol2 = GSL_MAX_DBL (fabs (e2), e1abs) * GSL_DBL_EPSILON; 00177 double delta3 = e1 - e0; 00178 double err3 = fabs (delta3); 00179 double tol3 = GSL_MAX_DBL (e1abs, fabs (e0)) * GSL_DBL_EPSILON; 00180 00181 double e3, delta1, err1, tol1, ss; 00182 00183 if (err2 <= tol2 && err3 <= tol3) { 00184 /* If e0, e1 and e2 are equal to within machine accuracy, 00185 convergence is assumed. */ 00186 00187 *result = res; 00188 absolute = err2 + err3; 00189 relative = 5 * GSL_DBL_EPSILON * fabs (res); 00190 *abserr = GSL_MAX_DBL (absolute, relative); 00191 return; 00192 } 00193 00194 e3 = epstab[n - 2 * i]; 00195 epstab[n - 2 * i] = e1; 00196 delta1 = e1 - e3; 00197 err1 = fabs (delta1); 00198 tol1 = GSL_MAX_DBL (e1abs, fabs (e3)) * GSL_DBL_EPSILON; 00199 00200 /* If two elements are very close to each other, omit a part of 00201 the table by adjusting the value of n */ 00202 00203 if (err1 <= tol1 || err2 <= tol2 || err3 <= tol3) { 00204 n_final = 2 * i; 00205 break; 00206 } 00207 00208 ss = (1 / delta1 + 1 / delta2) - 1 / delta3; 00209 00210 /* Test to detect irregular behaviour in the table, and 00211 eventually omit a part of the table by adjusting the value of 00212 n. */ 00213 if (fabs (ss * e1) <= 0.0001) { 00214 n_final = 2 * i; 00215 break; 00216 } 00217 /* Compute a new element and eventually adjust the value of 00218 result. */ 00219 00220 res = e1 + 1 / ss; 00221 epstab[n - 2 * i] = res; 00222 00223 { 00224 const double error = err2 + fabs (res - e2) + err3; 00225 00226 if (error <= *abserr) { 00227 *abserr = error; 00228 *result = res; 00229 } 00230 } 00231 } 00232 00233 /* Shift the table */ 00234 00235 { 00236 const size_t limexp = 50 - 1; 00237 00238 if (n_final == limexp) { 00239 n_final = 2 * (limexp / 2); 00240 } 00241 } 00242 00243 if (n_orig % 2 == 1) { 00244 for (i = 0; i <= newelm; i++) { 00245 epstab[1 + i * 2] = epstab[i * 2 + 3]; 00246 } 00247 } else { 00248 for (i = 0; i <= newelm; i++) { 00249 epstab[i * 2] = epstab[i * 2 + 2]; 00250 } 00251 } 00252 if (n_orig != n_final) { 00253 for (i = 0; i <= n_final; i++) { 00254 epstab[i] = epstab[n_orig - n_final + i]; 00255 } 00256 } 00257 00258 table->n = n_final + 1; 00259 00260 if (nres_orig < 3) { 00261 00262 res3la[nres_orig] = *result; 00263 *abserr = GSL_DBL_MAX; 00264 00265 } else { 00266 /* Compute error estimate */ 00267 *abserr = (fabs (*result - res3la[2]) + fabs (*result - res3la[1]) 00268 + fabs (*result - res3la[0])); 00269 00270 res3la[0] = res3la[1]; 00271 res3la[1] = res3la[2]; 00272 res3la[2] = *result; 00273 } 00274 00275 /* In QUADPACK the variable table->nres is incremented at the top of 00276 qelg, so it increases on every call. This leads to the array 00277 res3la being accessed when its elements are still undefined, so I 00278 have moved the update to this point so that its value more 00279 useful. */ 00280 00281 table->nres = nres_orig + 1; 00282 00283 *abserr = GSL_MAX_DBL (*abserr, 5 * GSL_DBL_EPSILON * fabs (*result)); 00284 00285 return; 00286 } 00287 00288 /// Determine if an interval is large 00289 int large_interval (gsl_inte_workspace * workspace) { 00290 size_t i = workspace->i ; 00291 const size_t * level = workspace->level; 00292 00293 if (level[i] < workspace->maximum_level) { 00294 return 1; 00295 } else { 00296 return 0; 00297 } 00298 } 00299 00300 /// Reset workspace to work on the interval with the largest error 00301 inline void reset_nrmax (gsl_inte_workspace * workspace) { 00302 workspace->nrmax = 0; 00303 workspace->i = workspace->order[0] ; 00304 } 00305 00306 /// Increase workspace 00307 int increase_nrmax (gsl_inte_workspace * workspace) { 00308 int k; 00309 int id = workspace->nrmax; 00310 int jupbnd; 00311 00312 const size_t * level = workspace->level; 00313 const size_t * order = workspace->order; 00314 00315 size_t limit = workspace->limit ; 00316 size_t last = workspace->size - 1 ; 00317 00318 if (last > (1 + limit / 2)) { 00319 jupbnd = limit + 1 - last; 00320 } else { 00321 jupbnd = last; 00322 } 00323 00324 for (k = id; k <= jupbnd; k++) { 00325 size_t i_max = order[workspace->nrmax]; 00326 00327 workspace->i = i_max ; 00328 00329 if (level[i_max] < workspace->maximum_level) { 00330 return 1; 00331 } 00332 00333 workspace->nrmax++; 00334 00335 } 00336 return 0; 00337 } 00338 00339 /** \brief Integration function 00340 00341 \future Remove goto statements. Before this is done, it might 00342 be best to add some tests which fail in the various ways. 00343 */ 00344 int qags(func_t &func, const double a, const double b, 00345 const double l_epsabs, const double l_epsrel, 00346 double *result, double *abserr) { 00347 00348 double area, errsum; 00349 double res_ext, err_ext; 00350 double result0, abserr0, resabs0, resasc0; 00351 double tolerance; 00352 00353 double ertest = 0; 00354 double error_over_large_intervals = 0; 00355 double reseps = 0, abseps = 0, correc = 0; 00356 size_t ktmin = 0; 00357 int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0; 00358 int error_type = 0, error_type2 = 0; 00359 00360 size_t iteration = 0; 00361 00362 int positive_integrand = 0; 00363 int extrapolate = 0; 00364 int disallow_extrapolation = 0; 00365 00366 struct extrapolation_table table; 00367 00368 /* Initialize results */ 00369 00370 this->w->initialise(a,b); 00371 00372 *result = 0; 00373 *abserr = 0; 00374 00375 size_t limit=this->w->limit; 00376 00377 /* Test on accuracy */ 00378 00379 if (this->tol_abs <= 0 && (this->tol_rel < 50 * GSL_DBL_EPSILON || 00380 this->tol_rel < 0.5e-28)) { 00381 this->last_iter=0; 00382 00383 std::string estr="Tolerance cannot be achieved with given "; 00384 estr+="value of tol_abs, "+dtos(l_epsabs)+", and tol_rel, "+ 00385 dtos(l_epsrel)+", in gsl_inte_singular::qags()."; 00386 O2SCL_ERR_RET(estr.c_str(),gsl_ebadtol); 00387 } 00388 00389 /* Perform the first integration */ 00390 00391 gauss_kronrod(func,a,b,&result0,&abserr0,&resabs0,&resasc0); 00392 00393 this->w->set_initial_result (result0, abserr0); 00394 00395 tolerance = GSL_MAX_DBL (this->tol_abs, this->tol_rel * fabs (result0)); 00396 00397 if (abserr0 <= 100 * GSL_DBL_EPSILON * resabs0 && 00398 abserr0 > tolerance) { 00399 00400 *result = result0; 00401 *abserr = abserr0; 00402 00403 this->last_iter=1; 00404 00405 this->last_conv=gsl_eround; 00406 std::string estr="Cannot reach tolerance because of roundoff error "; 00407 estr+="on first attempt in gsl_inte_singular::qags()."; 00408 O2SCL_CONV_RET(estr.c_str(),gsl_eround,this->err_nonconv); 00409 00410 } else if ((abserr0 <= tolerance && 00411 abserr0 != resasc0) || abserr0 == 0.0) { 00412 00413 *result = result0; 00414 *abserr = abserr0; 00415 this->last_iter=1; 00416 return gsl_success; 00417 00418 } else if (limit == 1) { 00419 00420 *result = result0; 00421 *abserr = abserr0; 00422 00423 this->last_iter=1; 00424 this->last_conv=gsl_emaxiter; 00425 O2SCL_CONV2_RET("A maximum of 1 iteration was insufficient ", 00426 "in gsl_inte_singular::qags().", 00427 gsl_emaxiter,this->err_nonconv); 00428 } 00429 00430 /* Initialization */ 00431 00432 initialise_table (&table); 00433 append_table (&table, result0); 00434 00435 area = result0; 00436 errsum = abserr0; 00437 00438 res_ext = result0; 00439 err_ext = GSL_DBL_MAX; 00440 00441 positive_integrand = this->test_positivity (result0, resabs0); 00442 00443 iteration = 1; 00444 00445 do { 00446 00447 // Output iteration information 00448 if (this->verbose>0) { 00449 std::cout << this->type(); 00450 std::cout << " Iter: " << iteration; 00451 std::cout.setf(std::ios::showpos); 00452 std::cout << " Res: " << area; 00453 std::cout.unsetf(std::ios::showpos); 00454 std::cout << " Err: " << errsum 00455 << " Tol: " << tolerance << std::endl; 00456 if (this->verbose>1) { 00457 char ch; 00458 std::cout << "Press a key and type enter to continue. " ; 00459 std::cin >> ch; 00460 } 00461 } 00462 00463 size_t current_level; 00464 double a1, b1, a2, b2; 00465 double a_i, b_i, r_i, e_i; 00466 double area1 = 0, area2 = 0, area12 = 0; 00467 double error1 = 0, error2 = 0, error12 = 0; 00468 double resasc1, resasc2; 00469 double resabs1, resabs2; 00470 double last_e_i; 00471 00472 /* Bisect the subinterval with the largest error estimate */ 00473 00474 this->w->retrieve (&a_i, &b_i, &r_i, &e_i); 00475 00476 current_level = this->w->level[this->w->i] + 1; 00477 00478 a1 = a_i; 00479 b1 = 0.5 * (a_i + b_i); 00480 a2 = b1; 00481 b2 = b_i; 00482 00483 iteration++; 00484 00485 gauss_kronrod(func,a1,b1,&area1,&error1,&resabs1,&resasc1); 00486 gauss_kronrod(func,a2,b2,&area2,&error2,&resabs2,&resasc2); 00487 00488 area12 = area1 + area2; 00489 error12 = error1 + error2; 00490 last_e_i = e_i; 00491 00492 /* Improve previous approximations to the integral and test for 00493 accuracy. 00494 00495 We write these expressions in the same way as the original 00496 QUADPACK code so that the rounding errors are the same, which 00497 makes testing easier. 00498 */ 00499 00500 errsum = errsum + error12 - e_i; 00501 area = area + area12 - r_i; 00502 00503 tolerance = GSL_MAX_DBL (this->tol_abs, this->tol_rel * fabs (area)); 00504 if (resasc1 != error1 && resasc2 != error2) { 00505 double delta = r_i - area12; 00506 00507 if (fabs (delta) <= 1.0e-5 * fabs (area12) && 00508 error12 >= 0.99 * e_i) { 00509 if (!extrapolate) { 00510 roundoff_type1++; 00511 } else { 00512 roundoff_type2++; 00513 } 00514 } 00515 if (iteration > 10 && error12 > e_i) { 00516 roundoff_type3++; 00517 } 00518 } 00519 00520 // Test for roundoff and eventually set error flag 00521 00522 if (roundoff_type1 + roundoff_type2 >= 10 || 00523 roundoff_type3 >= 20) { 00524 /* round off error */ 00525 error_type = 2; 00526 } 00527 00528 if (roundoff_type2 >= 5) { 00529 error_type2 = 1; 00530 } 00531 00532 // Set error flag in the case of bad integrand behaviour at 00533 // a point of the integration range 00534 00535 if (this->w->subinterval_too_small (a1, a2, b2)) { 00536 error_type = 4; 00537 } 00538 00539 /* append the newly-created intervals to the list */ 00540 00541 this->w->update(a1,b1,area1,error1,a2,b2,area2,error2); 00542 00543 if (errsum <= tolerance) { 00544 00545 // Output final iteration information 00546 if (this->verbose>0) { 00547 std::cout << this->type(); 00548 std::cout << " Iter: " << iteration; 00549 std::cout.setf(std::ios::showpos); 00550 std::cout << " Res: " << area; 00551 std::cout.unsetf(std::ios::showpos); 00552 std::cout << " Err: " << errsum 00553 << " Tol: " << tolerance << std::endl; 00554 if (this->verbose>1) { 00555 char ch; 00556 std::cout << "Press a key and type enter to continue. " ; 00557 std::cin >> ch; 00558 } 00559 } 00560 00561 goto compute_result; 00562 } 00563 00564 if (error_type) { 00565 break; 00566 } 00567 00568 if (iteration >= limit - 1) { 00569 error_type = 1; 00570 break; 00571 } 00572 00573 if (iteration == 2) { 00574 error_over_large_intervals = errsum; 00575 ertest = tolerance; 00576 append_table (&table,area); 00577 continue; 00578 } 00579 00580 if (disallow_extrapolation) { 00581 continue; 00582 } 00583 00584 error_over_large_intervals += -last_e_i; 00585 00586 if (current_level < this->w->maximum_level) { 00587 error_over_large_intervals += error12; 00588 } 00589 00590 if (!extrapolate) { 00591 00592 /* test whether the interval to be bisected next is the 00593 smallest interval. */ 00594 00595 if (large_interval (this->w)) { 00596 continue; 00597 } 00598 00599 extrapolate = 1; 00600 this->w->nrmax = 1; 00601 } 00602 00603 if (!error_type2 && error_over_large_intervals > ertest) { 00604 if (increase_nrmax (this->w)) { 00605 continue; 00606 } 00607 } 00608 00609 // Perform extrapolation 00610 00611 append_table(&table,area); 00612 00613 qelg(&table,&reseps,&abseps); 00614 00615 ktmin++; 00616 00617 if (ktmin > 5 && err_ext < 0.001 * errsum) { 00618 error_type = 5; 00619 } 00620 00621 if (abseps < err_ext) { 00622 ktmin = 0; 00623 err_ext = abseps; 00624 res_ext = reseps; 00625 correc = error_over_large_intervals; 00626 ertest = GSL_MAX_DBL (this->tol_abs, 00627 this->tol_rel * fabs (reseps)); 00628 if (err_ext <= ertest) { 00629 break; 00630 } 00631 } 00632 00633 /* Prepare bisection of the smallest interval. */ 00634 00635 if (table.n == 1) { 00636 disallow_extrapolation = 1; 00637 } 00638 00639 if (error_type == 5) { 00640 break; 00641 } 00642 00643 /* work on interval with largest error */ 00644 00645 reset_nrmax (this->w); 00646 extrapolate = 0; 00647 error_over_large_intervals = errsum; 00648 00649 } while (iteration < limit); 00650 00651 *result = res_ext; 00652 *abserr = err_ext; 00653 00654 if (err_ext == GSL_DBL_MAX) 00655 goto compute_result; 00656 00657 if (error_type || error_type2) { 00658 if (error_type2) { 00659 err_ext += correc; 00660 } 00661 00662 if (error_type == 0) 00663 error_type = 3; 00664 00665 if (res_ext != 0.0 && area != 0.0) { 00666 if (err_ext / fabs (res_ext) > errsum / fabs (area)) 00667 goto compute_result; 00668 } else if (err_ext > errsum) { 00669 goto compute_result; 00670 } else if (area == 0.0) { 00671 goto return_error; 00672 } 00673 } 00674 00675 /* Test on divergence. */ 00676 00677 { 00678 double max_area = GSL_MAX_DBL (fabs (res_ext),fabs (area)); 00679 00680 if (!positive_integrand && max_area < 0.01 * resabs0) 00681 goto return_error; 00682 } 00683 00684 { 00685 double ratio = res_ext / area; 00686 00687 if (ratio < 0.01 || ratio > 100.0 || errsum > fabs (area)) 00688 error_type = 6; 00689 } 00690 00691 goto return_error; 00692 00693 compute_result: 00694 00695 *result = this->w->sum_results(); 00696 *abserr = errsum; 00697 00698 return_error: 00699 00700 if (error_type > 2) { 00701 error_type--; 00702 } 00703 00704 this->last_iter=iteration; 00705 00706 if (error_type == 0) { 00707 return gsl_success; 00708 } else if (error_type == 1) { 00709 this->last_conv=gsl_emaxiter; 00710 std::string estr="Maximum number of subdivisions ("+itos(iteration); 00711 estr+=") reached in gsl_inte_singular::qags()."; 00712 O2SCL_CONV_RET(estr.c_str(),gsl_emaxiter,this->err_nonconv); 00713 } else if (error_type == 2) { 00714 this->last_conv=gsl_eround; 00715 std::string estr="Roundoff error prevents tolerance "; 00716 estr+="from being achieved in gsl_inte_singular::qags()."; 00717 O2SCL_CONV_RET(estr.c_str(),gsl_eround,this->err_nonconv); 00718 } else if (error_type == 3) { 00719 this->last_conv=gsl_esing; 00720 std::string estr="Bad integrand behavior "; 00721 estr+="in gsl_inte_singular::qags()."; 00722 O2SCL_CONV_RET(estr.c_str(),gsl_esing,this->err_nonconv); 00723 } else if (error_type == 4) { 00724 this->last_conv=gsl_eround; 00725 std::string estr="Roundoff error detected in extrapolation table "; 00726 estr+="in gsl_inte_singular::qags()."; 00727 O2SCL_CONV_RET(estr.c_str(),gsl_eround,this->err_nonconv); 00728 } else if (error_type == 5) { 00729 this->last_conv=gsl_ediverge; 00730 std::string estr="Integral is divergent or slowly convergent "; 00731 estr+="in gsl_inte_singular::qags()."; 00732 O2SCL_CONV_RET(estr.c_str(),gsl_ediverge,this->err_nonconv); 00733 } 00734 00735 std::string estr="Could not integrate function in gsl_inte_kronrod"; 00736 estr+="::qags() (it may have returned a non-finite result)."; 00737 O2SCL_ERR(estr.c_str(),gsl_efailed); 00738 00739 return gsl_efailed; 00740 } 00741 00742 }; 00743 00744 /** \brief Integrate a function with a singularity (GSL) 00745 [abstract base] 00746 00747 This class contains the GSL-based integration function for 00748 applying transformations to the user-defined integrand. The 00749 casual end-user should use the classes explained in the 00750 \ref inte_section section of the User's guide. 00751 */ 00752 template<class func_t=funct> class gsl_inte_transform : 00753 public gsl_inte_singular<func_t> { 00754 00755 public: 00756 00757 /// The transformation to apply to the user-supplied function 00758 virtual double transform(double t, func_t &func)=0; 00759 00760 /** \brief Integration wrapper for internal transformed function 00761 type 00762 */ 00763 virtual void gauss_kronrod 00764 (func_t &func, double a, double b, 00765 double *result, double *abserr, double *resabs, double *resasc) { 00766 funct_mfptr_param<gsl_inte_transform,func_t> 00767 fmp(this,&gsl_inte_transform::transform,func); 00768 return this->gauss_kronrod_base 00769 (fmp,a,b,result,abserr,resabs,resasc); 00770 } 00771 00772 }; 00773 00774 #ifndef DOXYGENP 00775 } 00776 #endif 00777 00778 #endif
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).