3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <gsl/gsl_math.h>
24 #include <gsl/gsl_errno.h>
25 #include <gsl/gsl_integration.h>
27 #include "initialise.c"
32 gsl_integration_qawf (gsl_function * f,
36 gsl_integration_workspace * workspace,
37 gsl_integration_workspace * cycle_workspace,
38 gsl_integration_qawo_table * wf,
39 double *result, double *abserr)
42 double res_ext, err_ext;
43 double correc, total_error = 0.0, truncation_error;
48 struct extrapolation_table table;
51 double omega = wf->omega;
55 double initial_eps, eps;
58 /* Initialize results */
60 initialise (workspace, a, a);
65 if (limit > workspace->limit)
67 GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ;
70 /* Test on accuracy */
74 GSL_ERROR ("absolute tolerance epsabs must be positive", GSL_EBADTOL) ;
79 if (wf->sine == GSL_INTEG_SINE)
81 /* The function sin(w x) f(x) is always zero for w = 0 */
90 /* The function cos(w x) f(x) is always f(x) for w = 0 */
92 int status = gsl_integration_qagiu (f, a, epsabs, 0.0,
93 cycle_workspace->limit,
100 if (epsabs > GSL_DBL_MIN / (1 - p))
102 eps = epsabs * (1 - p);
115 err_ext = GSL_DBL_MAX;
118 cycle = (2 * floor (fabs (omega)) + 1) * M_PI / fabs (omega);
120 gsl_integration_qawo_table_set_length (wf, cycle);
122 initialise_table (&table);
124 for (iteration = 0; iteration < limit; iteration++)
126 double area1, error1, reseps, erreps;
128 double a1 = a + iteration * cycle;
129 double b1 = a1 + cycle;
131 double epsabs1 = eps * factor;
133 int status = gsl_integration_qawo (f, a1, epsabs1, 0.0, limit,
137 append_interval (workspace, a1, b1, area1, error1);
142 errsum = errsum + error1;
144 /* estimate the truncation error as 50 times the final term */
146 truncation_error = 50 * fabs (area1);
148 total_error = errsum + truncation_error;
150 if (total_error < epsabs && iteration > 4)
162 eps = GSL_MAX_DBL (initial_eps, correc * (1.0 - p));
165 if (status && total_error < 10 * correc && iteration > 3)
170 append_table (&table, area);
177 qelg (&table, &reseps, &erreps);
181 if (ktmin >= 15 && err_ext < 0.001 * total_error)
186 if (erreps < err_ext)
192 if (err_ext + 10 * correc <= epsabs)
194 if (err_ext <= epsabs && 10 * correc >= epsabs)
200 if (iteration == limit)
203 if (err_ext == GSL_DBL_MAX)
206 err_ext = err_ext + 10 * correc;
216 if (res_ext != 0.0 && area != 0.0)
218 if (err_ext / fabs (res_ext) > errsum / fabs (area))
221 else if (err_ext > errsum)
225 else if (area == 0.0)
232 err_ext = err_ext + truncation_error;
240 *abserr = total_error;
251 else if (error_type == 1)
253 GSL_ERROR ("number of iterations was insufficient", GSL_EMAXITER);
255 else if (error_type == 2)
257 GSL_ERROR ("cannot reach tolerance because of roundoff error",
260 else if (error_type == 3)
262 GSL_ERROR ("bad integrand behavior found in the integration interval",
265 else if (error_type == 4)
267 GSL_ERROR ("roundoff error detected in the extrapolation table",
270 else if (error_type == 5)
272 GSL_ERROR ("integral is divergent, or slowly convergent",
277 GSL_ERROR ("could not integrate function", GSL_EFAILED);