Object-oriented Scientific Computing Library: Version 0.910
gsl_inte_singular.h
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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.