24 #ifndef O2SCL_GSL_INTE_QAWF_H
25 #define O2SCL_GSL_INTE_QAWF_H
32 #include <o2scl/inte.h>
33 #include <o2scl/inte_qawo_gsl.h>
34 #include <o2scl/inte_qagiu_gsl.h>
36 #ifndef DOXYGEN_NO_O2NS
110 double &res,
double &err) {
112 this->
otable=gsl_integration_qawo_table_alloc
119 gsl_integration_qawo_table_free(this->
otable);
126 #ifndef DOXYGEN_INTERNAL
135 int qawf(func_t &func,
const double a,
136 const double epsabs,
double *result,
double *abserr) {
139 double res_ext, err_ext;
140 double correc, total_error = 0.0, truncation_error;
143 size_t iteration = 0;
150 const double p = 0.9;
152 double initial_eps, eps;
162 size_t limit=this->
w->
limit;
174 std::string estr=
"The absolute tolerance must be positive ";
175 estr+=
"in inte_qawf_gsl::qawf().";
179 if (this->
omega == 0.0) {
180 if (this->
otable->sine == GSL_INTEG_SINE) {
192 int status=iu.
integ_err(func,a,0.0,*result,*abserr);
198 if (epsabs > GSL_DBL_MIN / (1 - p)) {
199 eps = epsabs * (1 - p);
210 err_ext = GSL_DBL_MAX;
213 cycle = (2 * floor (fabs (this->
omega)) + 1) *
214 M_PI / fabs (this->
omega);
216 gsl_integration_qawo_table_set_length (this->
otable, cycle);
220 for (iteration = 0; iteration < limit; iteration++) {
221 double area1, error1, reseps, erreps;
223 double a1 = a + iteration * cycle;
224 double b1 = a1 + cycle;
226 double epsabs1 = eps * factor;
236 errsum = errsum + error1;
240 truncation_error = 50 * fabs (area1);
242 total_error = errsum + truncation_error;
244 if (total_error < epsabs && iteration > 4) {
248 if (error1 > correc) {
253 eps = GSL_MAX_DBL (initial_eps, correc * (1.0 - p));
256 if (status && total_error < 10 * correc && iteration > 3) {
266 this->
qelg (&table, &reseps, &erreps);
270 if (ktmin >= 15 && err_ext < 0.001 * total_error) {
274 if (erreps < err_ext) {
279 if (err_ext + 10 * correc <= epsabs)
281 if (err_ext <= epsabs && 10 * correc >= epsabs)
286 std::cout <<
"inte_qawf_gsl Iter: " << iteration;
287 std::cout.setf(std::ios::showpos);
288 std::cout <<
" Res: " << area;
289 std::cout.unsetf(std::ios::showpos);
290 std::cout <<
" Err: " << total_error
291 <<
" Tol: " << epsabs << std::endl;
294 std::cout <<
"Press a key and type enter to continue. " ;
301 if (iteration == limit) error_type = 1;
303 if (err_ext == GSL_DBL_MAX)
306 err_ext = err_ext + 10 * correc;
311 if (error_type == 0) {
315 if (res_ext != 0.0 && area != 0.0) {
316 if (err_ext / fabs (res_ext) > errsum / fabs (area))
318 }
else if (err_ext > errsum) {
320 }
else if (area == 0.0) {
324 if (error_type == 4) {
325 err_ext = err_ext + truncation_error;
333 *abserr = total_error;
340 if (error_type == 0) {
342 }
else if (error_type == 1) {
343 std::string estr=
"Number of iterations was insufficient ";
344 estr+=
" in inte_qawf_gsl::qawf().";
346 }
else if (error_type == 2) {
347 std::string estr=
"Roundoff error prevents tolerance ";
348 estr+=
"from being achieved in inte_qawf_gsl::qawf().";
350 }
else if (error_type == 3) {
351 std::string estr=
"Bad integrand behavior ";
352 estr+=
" in inte_qawf_gsl::qawf().";
354 }
else if (error_type == 4) {
355 std::string estr=
"Roundoff error detected in extrapolation table ";
356 estr+=
"in inte_qawf_gsl::qawf().";
358 }
else if (error_type == 5) {
359 std::string estr=
"Integral is divergent or slowly convergent ";
360 estr+=
"in inte_qawf_gsl::qawf().";
363 std::string estr=
"Could not integrate function in inte_qawf_gsl";
364 estr+=
"::qawf() (it may have returned a non-finite result).";
371 return func(t)*sin(this->
omega*t);
377 const char *
type() {
return "inte_qawf_gsl_sin"; }
407 double &res,
double &err) {
409 this->
otable=gsl_integration_qawo_table_alloc
414 int status=this->
qawf(func,a,this->
tol_abs,&res,&err);
416 gsl_integration_qawo_table_free(this->
otable);
424 #ifndef DOXYGEN_INTERNAL
430 return func(t)*cos(this->
omega*t);
436 const char *
type() {
return "inte_qawf_gsl_cos"; }
440 #ifndef DOXYGEN_NO_O2NS
Integration workspace for the GSL integrators.
int qawo(func_t &func, const double a, const double epsabs, const double epsrel, inte_workspace_gsl *loc_w, gsl_integration_qawo_table *wf, double *result, double *abserr)
The full GSL integration routine called by integ_err()
void initialise_table(struct extrapolation_table *table)
Initialize the table.
double omega
The user-specified frequency (default 1.0)
virtual int integ_err(func_t &func, double a, double b, double &res, double &err)
Integrate function func from a to b and place the result in res and the error in err.
Adaptive integration a function with finite limits of integration (GSL)
void append_table(struct extrapolation_table *table, double y)
Append a result to the table.
apparent singularity detected
exceeded max number of iterations
const char * type()
Return string denoting type ("inte_qawf_gsl_sin")
virtual int integ_err(func_t &func, double a, double b, double &res, double &err)
Integrate function func from a to b and place the result in res and the error in err.
size_t n_levels
The number of bisection levels (default 10)
inte_workspace_gsl * cyclew
The integration workspace.
double tol_abs
The maximum absolute uncertainty in the value of the integral (default )
Integrate a function over the interval (GSL)
int initialise(double a, double b)
Initialize the workspace for an integration with limits a and b.
virtual int integ_err(func_t &func, double a, double b, double &res, double &err)
Integrate a function over the interval giving result res and error err.
int allocate(size_t sz)
Allocate a workspace.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
void append_interval(double a1, double b1, double area1, double error1)
Push a new interval to the workspace stack.
void qelg(struct extrapolation_table *table, double *result, double *abserr)
Determines the limit of a given sequence of approximations.
Adaptive integration for oscillatory integrals (GSL)
inte_workspace_gsl * w
The integration workspace.
const char * type()
Return string denoting type ("inte_qawf_gsl_cos")
size_t limit
Maximum number of subintervals allocated.
user specified an invalid tolerance
int free()
Free allocated workspace memory.
virtual double transform(double t, func_t &func)
Add the oscillating part to the integrand.
Adaptive integration for oscillatory integrals (GSL)
gsl_integration_qawo_table * otable
The integration workspace.
virtual double transform(double t, func_t &func)
Add the oscillating part to the integrand.
failed because of roundoff error
integral or series is divergent
int qawf(func_t &func, const double a, const double epsabs, double *result, double *abserr)
The full GSL integration routine called by integ_err()