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.
22 #include <gsl/gsl_errno.h>
23 #include <gsl/gsl_integration.h>
26 qagp (const gsl_function *f,
27 const double *pts, const size_t npts,
28 const double epsabs, const double epsrel, const size_t limit,
29 gsl_integration_workspace * workspace,
30 double *result, double *abserr,
31 gsl_integration_rule * q);
33 #include "initialise.c"
41 #include "positivity.c"
44 gsl_integration_qagp (const gsl_function *f,
45 double * pts, size_t npts,
46 double epsabs, double epsrel, size_t limit,
47 gsl_integration_workspace * workspace,
48 double * result, double * abserr)
50 int status = qagp (f, pts, npts,
51 epsabs, epsrel, limit,
54 &gsl_integration_qk21) ;
61 qagp (const gsl_function * f,
62 const double *pts, const size_t npts,
63 const double epsabs, const double epsrel,
65 gsl_integration_workspace * workspace,
66 double *result, double *abserr,
67 gsl_integration_rule * q)
70 double res_ext, err_ext;
71 double result0, abserr0, resabs0;
75 double error_over_large_intervals = 0;
76 double reseps = 0, abseps = 0, correc = 0;
78 int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0;
79 int error_type = 0, error_type2 = 0;
83 int positive_integrand = 0;
85 int disallow_extrapolation = 0;
87 struct extrapolation_table table;
89 const size_t nint = npts - 1; /* number of intervals */
91 size_t *ndin = workspace->level; /* temporarily alias ndin to level */
95 /* Initialize results */
100 /* Test on validity of parameters */
102 if (limit > workspace->limit)
104 GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ;
107 if (npts > workspace->limit)
109 GSL_ERROR ("npts exceeds size of workspace", GSL_EINVAL);
112 if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28))
114 GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel",
118 /* Check that the integration range and break points are an
119 ascending sequence */
121 for (i = 0; i < nint; i++)
123 if (pts[i + 1] < pts[i])
125 GSL_ERROR ("points are not in an ascending sequence", GSL_EINVAL);
129 /* Perform the first integration */
135 initialise (workspace, 0.0, 0.0) ;
137 for (i = 0; i < nint; i++)
139 double area1, error1, resabs1, resasc1;
140 const double a1 = pts[i];
141 const double b1 = pts[i + 1];
143 q (f, a1, b1, &area1, &error1, &resabs1, &resasc1);
145 result0 = result0 + area1;
146 abserr0 = abserr0 + error1;
147 resabs0 = resabs0 + resabs1;
149 append_interval (workspace, a1, b1, area1, error1);
151 if (error1 == resasc1 && error1 != 0.0)
161 /* Compute the initial error estimate */
165 for (i = 0; i < nint; i++)
169 workspace->elist[i] = abserr0;
172 errsum = errsum + workspace->elist[i];
176 for (i = 0; i < nint; i++)
178 workspace->level[i] = 0;
181 /* Sort results into order of decreasing error via the indirection
184 sort_results (workspace);
186 /* Test on accuracy */
188 tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0));
190 if (abserr0 <= 100 * GSL_DBL_EPSILON * resabs0 && abserr0 > tolerance)
195 GSL_ERROR ("cannot reach tolerance because of roundoff error"
196 "on first attempt", GSL_EROUND);
198 else if (abserr0 <= tolerance)
210 GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER);
215 initialise_table (&table);
216 append_table (&table, result0);
221 err_ext = GSL_DBL_MAX;
223 error_over_large_intervals = errsum;
226 positive_integrand = test_positivity (result0, resabs0);
228 iteration = nint - 1;
232 size_t current_level;
233 double a1, b1, a2, b2;
234 double a_i, b_i, r_i, e_i;
235 double area1 = 0, area2 = 0, area12 = 0;
236 double error1 = 0, error2 = 0, error12 = 0;
237 double resasc1, resasc2;
238 double resabs1, resabs2;
241 /* Bisect the subinterval with the largest error estimate */
243 retrieve (workspace, &a_i, &b_i, &r_i, &e_i);
245 current_level = workspace->level[workspace->i] + 1;
248 b1 = 0.5 * (a_i + b_i);
254 q (f, a1, b1, &area1, &error1, &resabs1, &resasc1);
255 q (f, a2, b2, &area2, &error2, &resabs2, &resasc2);
257 area12 = area1 + area2;
258 error12 = error1 + error2;
261 /* Improve previous approximations to the integral and test for
264 We write these expressions in the same way as the original
265 QUADPACK code so that the rounding errors are the same, which
266 makes testing easier. */
268 errsum = errsum + error12 - e_i;
269 area = area + area12 - r_i;
271 tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area));
273 if (resasc1 != error1 && resasc2 != error2)
275 double delta = r_i - area12;
277 if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i)
289 if (i > 10 && error12 > e_i)
295 /* Test for roundoff and eventually set error flag */
297 if (roundoff_type1 + roundoff_type2 >= 10 || roundoff_type3 >= 20)
299 error_type = 2; /* round off error */
302 if (roundoff_type2 >= 5)
307 /* set error flag in the case of bad integrand behaviour at
308 a point of the integration range */
310 if (subinterval_too_small (a1, a2, b2))
315 /* append the newly-created intervals to the list */
317 update (workspace, a1, b1, area1, error1, a2, b2, area2, error2);
319 if (errsum <= tolerance)
329 if (iteration >= limit - 1)
335 if (disallow_extrapolation)
340 error_over_large_intervals += -last_e_i;
342 if (current_level < workspace->maximum_level)
344 error_over_large_intervals += error12;
349 /* test whether the interval to be bisected next is the
350 smallest interval. */
351 if (large_interval (workspace))
355 workspace->nrmax = 1;
358 /* The smallest interval has the largest error. Before
359 bisecting decrease the sum of the errors over the larger
360 intervals (error_over_large_intervals) and perform
363 if (!error_type2 && error_over_large_intervals > ertest)
365 if (increase_nrmax (workspace))
369 /* Perform extrapolation */
371 append_table (&table, area);
375 goto skip_extrapolation;
378 qelg (&table, &reseps, &abseps);
382 if (ktmin > 5 && err_ext < 0.001 * errsum)
387 if (abseps < err_ext)
392 correc = error_over_large_intervals;
393 ertest = GSL_MAX_DBL (epsabs, epsrel * fabs (reseps));
394 if (err_ext <= ertest)
398 /* Prepare bisection of the smallest interval. */
402 disallow_extrapolation = 1;
412 reset_nrmax (workspace);
414 error_over_large_intervals = errsum;
417 while (iteration < limit);
422 if (err_ext == GSL_DBL_MAX)
425 if (error_type || error_type2)
435 if (result != 0 && area != 0)
437 if (err_ext / fabs (res_ext) > errsum / fabs (area))
440 else if (err_ext > errsum)
444 else if (area == 0.0)
450 /* Test on divergence. */
453 double max_area = GSL_MAX_DBL (fabs (res_ext), fabs (area));
455 if (!positive_integrand && max_area < 0.01 * resabs0)
460 double ratio = res_ext / area;
462 if (ratio < 0.01 || ratio > 100 || errsum > fabs (area))
470 *result = sum_results (workspace);
482 else if (error_type == 1)
484 GSL_ERROR ("number of iterations was insufficient", GSL_EMAXITER);
486 else if (error_type == 2)
488 GSL_ERROR ("cannot reach tolerance because of roundoff error",
491 else if (error_type == 3)
493 GSL_ERROR ("bad integrand behavior found in the integration interval",
496 else if (error_type == 4)
498 GSL_ERROR ("roundoff error detected in the extrapolation table",
501 else if (error_type == 5)
503 GSL_ERROR ("integral is divergent, or slowly convergent",
508 GSL_ERROR ("could not integrate function", GSL_EFAILED);