TMB Documentation  v1.9.11
TMBad/integrate.hpp
1 #ifndef HAVE_INTEGRATE_HPP
2 #define HAVE_INTEGRATE_HPP
3 // Autogenerated - do not edit by hand !
4 #include <float.h> // INFINITY etc
5 #include "global.hpp"
6 
7 namespace TMBad {
8 
14 template <class T>
15 double value(T x) {
16  return TMBad::Value(x);
17 }
18 double value(double x);
19 template <class S, class T>
20 int imin2(S x, T y) {
21  return (x < y) ? x : y;
22 }
23 template <class S, class T>
24 double fmin2(S x, T y) {
25  return (value(x) < value(y)) ? value(x) : value(y);
26 }
27 template <class S, class T>
28 double fmax2(S x, T y) {
29  return (value(x) < value(y)) ? value(y) : value(x);
30 }
31 template <class Float, class integr_fn>
32 static void rdqagie(integr_fn f, void *ex, Float *, int *, Float *, Float *,
33  int *, Float *, Float *, int *, int *, Float *, Float *,
34  Float *, Float *, int *, int *);
35 
36 template <class Float, class integr_fn>
37 static void rdqk15i(integr_fn f, void *ex, Float *, int *, Float *, Float *,
38  Float *, Float *, Float *, Float *);
39 
40 template <class Float, class integr_fn>
41 static void rdqagse(integr_fn f, void *ex, Float *, Float *, Float *, Float *,
42  int *, Float *, Float *, int *, int *, Float *, Float *,
43  Float *, Float *, int *, int *);
44 
45 template <class Float, class integr_fn>
46 static void rdqk21(integr_fn f, void *ex, Float *, Float *, Float *, Float *,
47  Float *, Float *);
48 
49 template <class Float>
50 static void rdqpsrt(int *, int *, int *, Float *, Float *, int *, int *);
51 
52 template <class Float>
53 static void rdqelg(int *, Float *, Float *, Float *, Float *, int *);
54 
55 template <class Float, class integr_fn>
56 void Rdqagi(integr_fn f, void *ex, Float *bound, int *inf, Float *epsabs,
57  Float *epsrel, Float *result, Float *abserr, int *neval, int *ier,
58  int *limit, int *lenw, int *last, int *iwork, Float *work) {
59  int l1, l2, l3;
60  *ier = 6;
61  *neval = 0;
62  *last = 0;
63  *result = 0.;
64  *abserr = 0.;
65  if (*limit < 1 || *lenw < *limit << 2) return;
66 
67  l1 = *limit;
68  l2 = *limit + l1;
69  l3 = *limit + l2;
70 
71  rdqagie(f, ex, bound, inf, epsabs, epsrel, limit, result, abserr, neval, ier,
72  work, &work[l1], &work[l2], &work[l3], iwork, last);
73 
74  return;
75 }
76 
77 template <class Float, class integr_fn>
78 static void rdqagie(integr_fn f, void *ex, Float *bound, int *inf,
79  Float *epsabs, Float *epsrel, int *limit, Float *result,
80  Float *abserr, int *neval, int *ier, Float *alist,
81  Float *blist, Float *rlist, Float *elist, int *iord,
82  int *last) {
83  Float area, dres;
84  int ksgn;
85  Float boun;
86  int nres;
87  Float area1, area2, area12;
88  int k;
89  Float small = 0.0, erro12;
90  int ierro;
91  Float a1, a2, b1, b2, defab1, defab2, oflow;
92  int ktmin, nrmax;
93  Float uflow;
94  bool noext;
95  int iroff1, iroff2, iroff3;
96  Float res3la[3], error1, error2;
97  int id;
98  Float rlist2[52];
99  int numrl2;
100  Float defabs, epmach, erlarg = 0.0, abseps, correc = 0.0, errbnd, resabs;
101  int jupbnd;
102  Float erlast, errmax;
103  int maxerr;
104  Float reseps;
105  bool extrap;
106  Float ertest = 0.0, errsum;
107  --iord;
108  --elist;
109  --rlist;
110  --blist;
111  --alist;
112 
113  epmach = DBL_EPSILON;
114 
115  *ier = 0;
116  *neval = 0;
117  *last = 0;
118  *result = 0.;
119  *abserr = 0.;
120  alist[1] = 0.;
121  blist[1] = 1.;
122  rlist[1] = 0.;
123  elist[1] = 0.;
124  iord[1] = 0;
125  if (*epsabs <= 0. && (*epsrel < fmax2(epmach * 50., 5e-29))) *ier = 6;
126  if (*ier == 6) return;
127  boun = *bound;
128  if (*inf == 2) {
129  boun = 0.;
130  }
131 
132  static Float c_b6 = 0.;
133  static Float c_b7 = 1.;
134 
135  rdqk15i(f, ex, &boun, inf, &c_b6, &c_b7, result, abserr, &defabs, &resabs);
136 
137  *last = 1;
138  rlist[1] = *result;
139  elist[1] = *abserr;
140  iord[1] = 1;
141  dres = fabs(*result);
142  errbnd = fmax2(*epsabs, *epsrel * dres);
143  if (*abserr <= epmach * 100. * defabs && *abserr > errbnd) *ier = 2;
144  if (*limit == 1) *ier = 1;
145  if (*ier != 0 || (*abserr <= errbnd && *abserr != resabs) || *abserr == 0.)
146  goto L130;
147 
148  uflow = DBL_MIN;
149  oflow = DBL_MAX;
150  rlist2[0] = *result;
151  errmax = *abserr;
152  maxerr = 1;
153  area = *result;
154  errsum = *abserr;
155  *abserr = oflow;
156  nrmax = 1;
157  nres = 0;
158  ktmin = 0;
159  numrl2 = 2;
160  extrap = false;
161  noext = false;
162  ierro = 0;
163  iroff1 = 0;
164  iroff2 = 0;
165  iroff3 = 0;
166  ksgn = -1;
167  if (dres >= (1. - epmach * 50.) * defabs) {
168  ksgn = 1;
169  }
170 
171  for (*last = 2; *last <= *limit; ++(*last)) {
172  a1 = alist[maxerr];
173  b1 = (alist[maxerr] + blist[maxerr]) * .5;
174  a2 = b1;
175  b2 = blist[maxerr];
176  erlast = errmax;
177  rdqk15i(f, ex, &boun, inf, &a1, &b1, &area1, &error1, &resabs, &defab1);
178  rdqk15i(f, ex, &boun, inf, &a2, &b2, &area2, &error2, &resabs, &defab2);
179 
180  area12 = area1 + area2;
181  erro12 = error1 + error2;
182  errsum = errsum + erro12 - errmax;
183  area = area + area12 - rlist[maxerr];
184  if (!(defab1 == error1 || defab2 == error2)) {
185  if (fabs(rlist[maxerr] - area12) <= fabs(area12) * 1e-5 &&
186  erro12 >= errmax * .99) {
187  if (extrap)
188  ++iroff2;
189  else
190  ++iroff1;
191  }
192  if (*last > 10 && erro12 > errmax) ++iroff3;
193  }
194 
195  rlist[maxerr] = area1;
196  rlist[*last] = area2;
197  errbnd = fmax2(*epsabs, *epsrel * fabs(area));
198 
199  if (iroff1 + iroff2 >= 10 || iroff3 >= 20) *ier = 2;
200  if (iroff2 >= 5) ierro = 3;
201 
202  if (*last == *limit) *ier = 1;
203 
204  if (fmax2(fabs(a1), fabs(b2)) <=
205  (epmach * 100. + 1.) * (fabs(a2) + uflow * 1e3)) {
206  *ier = 4;
207  }
208 
209  if (error2 <= error1) {
210  alist[*last] = a2;
211  blist[maxerr] = b1;
212  blist[*last] = b2;
213  elist[maxerr] = error1;
214  elist[*last] = error2;
215  } else {
216  alist[maxerr] = a2;
217  alist[*last] = a1;
218  blist[*last] = b1;
219  rlist[maxerr] = area2;
220  rlist[*last] = area1;
221  elist[maxerr] = error2;
222  elist[*last] = error1;
223  }
224 
225  rdqpsrt(limit, last, &maxerr, &errmax, &elist[1], &iord[1], &nrmax);
226  if (errsum <= errbnd) {
227  goto L115;
228  }
229  if (*ier != 0) break;
230  if (*last == 2) {
231  small = .375;
232  erlarg = errsum;
233  ertest = errbnd;
234  rlist2[1] = area;
235  continue;
236  }
237  if (noext) continue;
238 
239  erlarg -= erlast;
240  if (fabs(b1 - a1) > small) {
241  erlarg += erro12;
242  }
243  if (!extrap) {
244  if (fabs(blist[maxerr] - alist[maxerr]) > small) {
245  continue;
246  }
247  extrap = true;
248  nrmax = 2;
249  }
250 
251  if (ierro != 3 && erlarg > ertest) {
252  id = nrmax;
253  jupbnd = *last;
254  if (*last > *limit / 2 + 2) {
255  jupbnd = *limit + 3 - *last;
256  }
257  for (k = id; k <= jupbnd; ++k) {
258  maxerr = iord[nrmax];
259  errmax = elist[maxerr];
260  if (fabs(blist[maxerr] - alist[maxerr]) > small) {
261  goto L90;
262  }
263  ++nrmax;
264  }
265  }
266 
267  ++numrl2;
268  rlist2[numrl2 - 1] = area;
269  rdqelg(&numrl2, rlist2, &reseps, &abseps, res3la, &nres);
270  ++ktmin;
271  if (ktmin > 5 && *abserr < errsum * .001) {
272  *ier = 5;
273  }
274  if (abseps >= *abserr) {
275  goto L70;
276  }
277  ktmin = 0;
278  *abserr = abseps;
279  *result = reseps;
280  correc = erlarg;
281  ertest = fmax2(*epsabs, *epsrel * fabs(reseps));
282  if (*abserr <= ertest) {
283  break;
284  }
285 
286  L70:
287  if (numrl2 == 1) {
288  noext = true;
289  }
290  if (*ier == 5) {
291  break;
292  }
293  maxerr = iord[1];
294  errmax = elist[maxerr];
295  nrmax = 1;
296  extrap = false;
297  small *= .5;
298  erlarg = errsum;
299  L90:;
300  }
301 
302  if (*abserr == oflow) {
303  goto L115;
304  }
305  if (*ier + ierro == 0) {
306  goto L110;
307  }
308  if (ierro == 3) {
309  *abserr += correc;
310  }
311  if (*ier == 0) {
312  *ier = 3;
313  }
314  if (*result == 0. || area == 0.) {
315  if (*abserr > errsum) goto L115;
316 
317  if (area == 0.) goto L130;
318  } else {
319  if (*abserr / fabs(*result) > errsum / fabs(area)) {
320  goto L115;
321  }
322  }
323 
324 L110:
325  if (ksgn == -1 && fmax2(fabs(*result), fabs(area)) <= defabs * .01) {
326  goto L130;
327  }
328  if (.01 > *result / area || *result / area > 100. || errsum > fabs(area)) {
329  *ier = 6;
330  }
331  goto L130;
332 
333 L115:
334  *result = 0.;
335  for (k = 1; k <= *last; ++k) *result += rlist[k];
336 
337  *abserr = errsum;
338 L130:
339  *neval = *last * 30 - 15;
340  if (*inf == 2) {
341  *neval <<= 1;
342  }
343  if (*ier > 2) {
344  --(*ier);
345  }
346  return;
347 }
348 
349 template <class Float, class integr_fn>
350 void Rdqags(integr_fn f, void *ex, Float *a, Float *b, Float *epsabs,
351  Float *epsrel, Float *result, Float *abserr, int *neval, int *ier,
352  int *limit, int *lenw, int *last, int *iwork, Float *work) {
353  int l1, l2, l3;
354  *ier = 6;
355  *neval = 0;
356  *last = 0;
357  *result = 0.;
358  *abserr = 0.;
359  if (*limit < 1 || *lenw < *limit * 4) return;
360 
361  l1 = *limit;
362  l2 = *limit + l1;
363  l3 = *limit + l2;
364 
365  rdqagse(f, ex, a, b, epsabs, epsrel, limit, result, abserr, neval, ier, work,
366  &work[l1], &work[l2], &work[l3], iwork, last);
367 
368  return;
369 }
370 
371 template <class Float, class integr_fn>
372 static void rdqagse(integr_fn f, void *ex, Float *a, Float *b, Float *epsabs,
373  Float *epsrel, int *limit, Float *result, Float *abserr,
374  int *neval, int *ier, Float *alist, Float *blist,
375  Float *rlist, Float *elist, int *iord, int *last) {
376  bool noext, extrap;
377  int k, ksgn, nres;
378  int ierro;
379  int ktmin, nrmax;
380  int iroff1, iroff2, iroff3;
381  int id;
382  int numrl2;
383  int jupbnd;
384  int maxerr;
385  Float res3la[3];
386  Float rlist2[52];
387  Float abseps, area, area1, area2, area12, dres, epmach;
388  Float a1, a2, b1, b2, defabs, defab1, defab2, oflow, uflow, resabs, reseps;
389  Float error1, error2, erro12, errbnd, erlast, errmax, errsum;
390 
391  Float correc = 0.0, erlarg = 0.0, ertest = 0.0, small = 0.0;
392  --iord;
393  --elist;
394  --rlist;
395  --blist;
396  --alist;
397 
398  epmach = DBL_EPSILON;
399 
400  *ier = 0;
401  *neval = 0;
402  *last = 0;
403  *result = 0.;
404  *abserr = 0.;
405  alist[1] = *a;
406  blist[1] = *b;
407  rlist[1] = 0.;
408  elist[1] = 0.;
409  if (*epsabs <= 0. && *epsrel < fmax2(epmach * 50., 5e-29)) {
410  *ier = 6;
411  return;
412  }
413 
414  uflow = DBL_MIN;
415  oflow = DBL_MAX;
416  ierro = 0;
417  rdqk21(f, ex, a, b, result, abserr, &defabs, &resabs);
418 
419  dres = fabs(*result);
420  errbnd = fmax2(*epsabs, *epsrel * dres);
421  *last = 1;
422  rlist[1] = *result;
423  elist[1] = *abserr;
424  iord[1] = 1;
425  if (*abserr <= epmach * 100. * defabs && *abserr > errbnd) *ier = 2;
426  if (*limit == 1) *ier = 1;
427  if (*ier != 0 || (*abserr <= errbnd && *abserr != resabs) || *abserr == 0.)
428  goto L140;
429 
430  rlist2[0] = *result;
431  errmax = *abserr;
432  maxerr = 1;
433  area = *result;
434  errsum = *abserr;
435  *abserr = oflow;
436  nrmax = 1;
437  nres = 0;
438  numrl2 = 2;
439  ktmin = 0;
440  extrap = false;
441  noext = false;
442  iroff1 = 0;
443  iroff2 = 0;
444  iroff3 = 0;
445  ksgn = -1;
446  if (dres >= (1. - epmach * 50.) * defabs) {
447  ksgn = 1;
448  }
449 
450  for (*last = 2; *last <= *limit; ++(*last)) {
451  a1 = alist[maxerr];
452  b1 = (alist[maxerr] + blist[maxerr]) * .5;
453  a2 = b1;
454  b2 = blist[maxerr];
455  erlast = errmax;
456  rdqk21(f, ex, &a1, &b1, &area1, &error1, &resabs, &defab1);
457  rdqk21(f, ex, &a2, &b2, &area2, &error2, &resabs, &defab2);
458 
459  area12 = area1 + area2;
460  erro12 = error1 + error2;
461  errsum = errsum + erro12 - errmax;
462  area = area + area12 - rlist[maxerr];
463  if (!(defab1 == error1 || defab2 == error2)) {
464  if (fabs(rlist[maxerr] - area12) <= fabs(area12) * 1e-5 &&
465  erro12 >= errmax * .99) {
466  if (extrap)
467  ++iroff2;
468  else
469  ++iroff1;
470  }
471  if (*last > 10 && erro12 > errmax) ++iroff3;
472  }
473  rlist[maxerr] = area1;
474  rlist[*last] = area2;
475  errbnd = fmax2(*epsabs, *epsrel * fabs(area));
476 
477  if (iroff1 + iroff2 >= 10 || iroff3 >= 20) *ier = 2;
478  if (iroff2 >= 5) ierro = 3;
479 
480  if (*last == *limit) *ier = 1;
481 
482  if (fmax2(fabs(a1), fabs(b2)) <=
483  (epmach * 100. + 1.) * (fabs(a2) + uflow * 1e3)) {
484  *ier = 4;
485  }
486 
487  if (error2 > error1) {
488  alist[maxerr] = a2;
489  alist[*last] = a1;
490  blist[*last] = b1;
491  rlist[maxerr] = area2;
492  rlist[*last] = area1;
493  elist[maxerr] = error2;
494  elist[*last] = error1;
495  } else {
496  alist[*last] = a2;
497  blist[maxerr] = b1;
498  blist[*last] = b2;
499  elist[maxerr] = error1;
500  elist[*last] = error2;
501  }
502 
503  rdqpsrt(limit, last, &maxerr, &errmax, &elist[1], &iord[1], &nrmax);
504 
505  if (errsum <= errbnd) goto L115;
506  if (*ier != 0) break;
507  if (*last == 2) {
508  small = fabs(*b - *a) * .375;
509  erlarg = errsum;
510  ertest = errbnd;
511  rlist2[1] = area;
512  continue;
513  }
514  if (noext) continue;
515 
516  erlarg -= erlast;
517  if (fabs(b1 - a1) > small) {
518  erlarg += erro12;
519  }
520  if (!extrap) {
521  if (fabs(blist[maxerr] - alist[maxerr]) > small) {
522  continue;
523  }
524  extrap = true;
525  nrmax = 2;
526  }
527 
528  if (ierro != 3 && erlarg > ertest) {
529  id = nrmax;
530  jupbnd = *last;
531  if (*last > *limit / 2 + 2) {
532  jupbnd = *limit + 3 - *last;
533  }
534  for (k = id; k <= jupbnd; ++k) {
535  maxerr = iord[nrmax];
536  errmax = elist[maxerr];
537  if (fabs(blist[maxerr] - alist[maxerr]) > small) {
538  goto L90;
539  }
540  ++nrmax;
541  }
542  }
543 
544  ++numrl2;
545  rlist2[numrl2 - 1] = area;
546  rdqelg(&numrl2, rlist2, &reseps, &abseps, res3la, &nres);
547  ++ktmin;
548  if (ktmin > 5 && *abserr < errsum * .001) {
549  *ier = 5;
550  }
551  if (abseps < *abserr) {
552  ktmin = 0;
553  *abserr = abseps;
554  *result = reseps;
555  correc = erlarg;
556  ertest = fmax2(*epsabs, *epsrel * fabs(reseps));
557  if (*abserr <= ertest) {
558  break;
559  }
560  }
561 
562  if (numrl2 == 1) {
563  noext = true;
564  }
565  if (*ier == 5) {
566  break;
567  }
568  maxerr = iord[1];
569  errmax = elist[maxerr];
570  nrmax = 1;
571  extrap = false;
572  small *= .5;
573  erlarg = errsum;
574  L90:;
575  }
576 
577  if (*abserr == oflow) goto L115;
578  if (*ier + ierro == 0) goto L110;
579  if (ierro == 3) *abserr += correc;
580  if (*ier == 0) *ier = 3;
581  if (*result == 0. || area == 0.) {
582  if (*abserr > errsum) goto L115;
583  if (area == 0.) goto L130;
584  } else {
585  if (*abserr / fabs(*result) > errsum / fabs(area)) goto L115;
586  }
587 
588 L110:
589  if (ksgn == -1 && fmax2(fabs(*result), fabs(area)) <= defabs * .01) {
590  goto L130;
591  }
592  if (.01 > *result / area || *result / area > 100. || errsum > fabs(area)) {
593  *ier = 5;
594  }
595  goto L130;
596 
597 L115:
598  *result = 0.;
599  for (k = 1; k <= *last; ++k) *result += rlist[k];
600  *abserr = errsum;
601 L130:
602  if (*ier > 2)
603  L140:
604  *neval = *last * 42 - 21;
605  return;
606 }
607 
608 template <class Float, class integr_fn>
609 static void rdqk15i(integr_fn f, void *ex, Float *boun, int *inf, Float *a,
610  Float *b, Float *result, Float *abserr, Float *resabs,
611  Float *resasc) {
612  static double wg[8] = {0., .129484966168869693270611432679082,
613  0., .27970539148927666790146777142378,
614  0., .381830050505118944950369775488975,
615  0., .417959183673469387755102040816327};
616  static double xgk[8] = {
617  .991455371120812639206854697526329, .949107912342758524526189684047851,
618  .864864423359769072789712788640926, .741531185599394439863864773280788,
619  .58608723546769113029414483825873, .405845151377397166906606412076961,
620  .207784955007898467600689403773245, 0.};
621  static double wgk[8] = {
622  .02293532201052922496373200805897, .063092092629978553290700663189204,
623  .104790010322250183839876322541518, .140653259715525918745189590510238,
624  .16900472663926790282658342659855, .190350578064785409913256402421014,
625  .204432940075298892414161999234649, .209482141084727828012999174891714};
626 
627  Float absc, dinf, resg, resk, fsum, absc1, absc2, fval1, fval2;
628  int j;
629  Float hlgth, centr, reskh, uflow;
630  Float tabsc1, tabsc2, fc, epmach;
631  Float fv1[7], fv2[7], vec[15], vec2[15];
632  epmach = DBL_EPSILON;
633  uflow = DBL_MIN;
634  dinf = (double)imin2(1, *inf);
635 
636  centr = (*a + *b) * .5;
637  hlgth = (*b - *a) * .5;
638  tabsc1 = *boun + dinf * (1. - centr) / centr;
639  vec[0] = tabsc1;
640  if (*inf == 2) {
641  vec2[0] = -tabsc1;
642  }
643  for (j = 1; j <= 7; ++j) {
644  absc = hlgth * xgk[j - 1];
645  absc1 = centr - absc;
646  absc2 = centr + absc;
647  tabsc1 = *boun + dinf * (1. - absc1) / absc1;
648  tabsc2 = *boun + dinf * (1. - absc2) / absc2;
649  vec[(j << 1) - 1] = tabsc1;
650  vec[j * 2] = tabsc2;
651  if (*inf == 2) {
652  vec2[(j << 1) - 1] = -tabsc1;
653  vec2[j * 2] = -tabsc2;
654  }
655  }
656  f(vec, 15, ex);
657  if (*inf == 2) f(vec2, 15, ex);
658  fval1 = vec[0];
659  if (*inf == 2) fval1 += vec2[0];
660  fc = fval1 / centr / centr;
661 
662  resg = wg[7] * fc;
663  resk = wgk[7] * fc;
664  *resabs = fabs(resk);
665  for (j = 1; j <= 7; ++j) {
666  absc = hlgth * xgk[j - 1];
667  absc1 = centr - absc;
668  absc2 = centr + absc;
669  tabsc1 = *boun + dinf * (1. - absc1) / absc1;
670  tabsc2 = *boun + dinf * (1. - absc2) / absc2;
671  fval1 = vec[(j << 1) - 1];
672  fval2 = vec[j * 2];
673  if (*inf == 2) {
674  fval1 += vec2[(j << 1) - 1];
675  }
676  if (*inf == 2) {
677  fval2 += vec2[j * 2];
678  }
679  fval1 = fval1 / absc1 / absc1;
680  fval2 = fval2 / absc2 / absc2;
681  fv1[j - 1] = fval1;
682  fv2[j - 1] = fval2;
683  fsum = fval1 + fval2;
684  resg += wg[j - 1] * fsum;
685  resk += wgk[j - 1] * fsum;
686  *resabs += wgk[j - 1] * (fabs(fval1) + fabs(fval2));
687  }
688  reskh = resk * .5;
689  *resasc = wgk[7] * fabs(fc - reskh);
690  for (j = 1; j <= 7; ++j) {
691  *resasc +=
692  wgk[j - 1] * (fabs(fv1[j - 1] - reskh) + fabs(fv2[j - 1] - reskh));
693  }
694  *result = resk * hlgth;
695  *resasc *= hlgth;
696  *resabs *= hlgth;
697  *abserr = fabs((resk - resg) * hlgth);
698  if (*resasc != 0. && *abserr != 0.) {
699  *abserr = *resasc * fmin2(1., pow(*abserr * 200. / *resasc, 1.5));
700  }
701  if (*resabs > uflow / (epmach * 50.)) {
702  *abserr = fmax2(epmach * 50. * *resabs, *abserr);
703  }
704  return;
705 }
706 
707 template <class Float>
708 static void rdqelg(int *n, Float *epstab, Float *result, Float *abserr,
709  Float *res3la, int *nres) {
710  int i__, indx, ib, ib2, ie, k1, k2, k3, num, newelm, limexp;
711  Float delta1, delta2, delta3, e0, e1, e1abs, e2, e3, epmach, epsinf;
712  Float oflow, ss, res;
713  Float errA, err1, err2, err3, tol1, tol2, tol3;
714  --res3la;
715  --epstab;
716 
717  epmach = DBL_EPSILON;
718  oflow = DBL_MAX;
719  ++(*nres);
720  *abserr = oflow;
721  *result = epstab[*n];
722  if (*n < 3) {
723  goto L100;
724  }
725  limexp = 50;
726  epstab[*n + 2] = epstab[*n];
727  newelm = (*n - 1) / 2;
728  epstab[*n] = oflow;
729  num = *n;
730  k1 = *n;
731  for (i__ = 1; i__ <= newelm; ++i__) {
732  k2 = k1 - 1;
733  k3 = k1 - 2;
734  res = epstab[k1 + 2];
735  e0 = epstab[k3];
736  e1 = epstab[k2];
737  e2 = res;
738  e1abs = fabs(e1);
739  delta2 = e2 - e1;
740  err2 = fabs(delta2);
741  tol2 = fmax2(fabs(e2), e1abs) * epmach;
742  delta3 = e1 - e0;
743  err3 = fabs(delta3);
744  tol3 = fmax2(e1abs, fabs(e0)) * epmach;
745  if (err2 <= tol2 && err3 <= tol3) {
746  *result = res;
747  *abserr = err2 + err3;
748 
749  goto L100;
750  }
751 
752  e3 = epstab[k1];
753  epstab[k1] = e1;
754  delta1 = e1 - e3;
755  err1 = fabs(delta1);
756  tol1 = fmax2(e1abs, fabs(e3)) * epmach;
757 
758  if (err1 > tol1 && err2 > tol2 && err3 > tol3) {
759  ss = 1. / delta1 + 1. / delta2 - 1. / delta3;
760  epsinf = fabs(ss * e1);
761 
762  if (epsinf > 1e-4) {
763  goto L30;
764  }
765  }
766 
767  *n = i__ + i__ - 1;
768  goto L50;
769 
770  L30:
771 
772  res = e1 + 1. / ss;
773  epstab[k1] = res;
774  k1 += -2;
775  errA = err2 + fabs(res - e2) + err3;
776  if (errA <= *abserr) {
777  *abserr = errA;
778  *result = res;
779  }
780  }
781 
782 L50:
783  if (*n == limexp) {
784  *n = (limexp / 2 << 1) - 1;
785  }
786 
787  if (num / 2 << 1 == num)
788  ib = 2;
789  else
790  ib = 1;
791  ie = newelm + 1;
792  for (i__ = 1; i__ <= ie; ++i__) {
793  ib2 = ib + 2;
794  epstab[ib] = epstab[ib2];
795  ib = ib2;
796  }
797  if (num != *n) {
798  indx = num - *n + 1;
799  for (i__ = 1; i__ <= *n; ++i__) {
800  epstab[i__] = epstab[indx];
801  ++indx;
802  }
803  }
804 
805  if (*nres >= 4) {
806  *abserr = fabs(*result - res3la[3]) + fabs(*result - res3la[2]) +
807  fabs(*result - res3la[1]);
808  res3la[1] = res3la[2];
809  res3la[2] = res3la[3];
810  res3la[3] = *result;
811  } else {
812  res3la[*nres] = *result;
813  *abserr = oflow;
814  }
815 
816 L100:
817  *abserr = fmax2(*abserr, epmach * 5. * fabs(*result));
818  return;
819 }
820 
821 template <class Float, class integr_fn>
822 static void rdqk21(integr_fn f, void *ex, Float *a, Float *b, Float *result,
823  Float *abserr, Float *resabs, Float *resasc) {
824  static double wg[5] = {
825  .066671344308688137593568809893332, .149451349150580593145776339657697,
826  .219086362515982043995534934228163, .269266719309996355091226921569469,
827  .295524224714752870173892994651338};
828  static double xgk[11] = {.995657163025808080735527280689003,
829  .973906528517171720077964012084452,
830  .930157491355708226001207180059508,
831  .865063366688984510732096688423493,
832  .780817726586416897063717578345042,
833  .679409568299024406234327365114874,
834  .562757134668604683339000099272694,
835  .433395394129247190799265943165784,
836  .294392862701460198131126603103866,
837  .14887433898163121088482600112972,
838  0.};
839  static double wgk[11] = {
840  .011694638867371874278064396062192, .03255816230796472747881897245939,
841  .05475589657435199603138130024458, .07503967481091995276704314091619,
842  .093125454583697605535065465083366, .109387158802297641899210590325805,
843  .123491976262065851077958109831074, .134709217311473325928054001771707,
844  .142775938577060080797094273138717, .147739104901338491374841515972068,
845  .149445554002916905664936468389821};
846 
847  Float fv1[10], fv2[10], vec[21];
848  Float absc, resg, resk, fsum, fval1, fval2;
849  Float hlgth, centr, reskh, uflow;
850  Float fc, epmach, dhlgth;
851  int j, jtw, jtwm1;
852  epmach = DBL_EPSILON;
853  uflow = DBL_MIN;
854 
855  centr = (*a + *b) * .5;
856  hlgth = (*b - *a) * .5;
857  dhlgth = fabs(hlgth);
858 
859  resg = 0.;
860  vec[0] = centr;
861  for (j = 1; j <= 5; ++j) {
862  jtw = j << 1;
863  absc = hlgth * xgk[jtw - 1];
864  vec[(j << 1) - 1] = centr - absc;
865 
866  vec[j * 2] = centr + absc;
867  }
868  for (j = 1; j <= 5; ++j) {
869  jtwm1 = (j << 1) - 1;
870  absc = hlgth * xgk[jtwm1 - 1];
871  vec[(j << 1) + 9] = centr - absc;
872  vec[(j << 1) + 10] = centr + absc;
873  }
874  f(vec, 21, ex);
875  fc = vec[0];
876  resk = wgk[10] * fc;
877  *resabs = fabs(resk);
878  for (j = 1; j <= 5; ++j) {
879  jtw = j << 1;
880  absc = hlgth * xgk[jtw - 1];
881  fval1 = vec[(j << 1) - 1];
882  fval2 = vec[j * 2];
883  fv1[jtw - 1] = fval1;
884  fv2[jtw - 1] = fval2;
885  fsum = fval1 + fval2;
886  resg += wg[j - 1] * fsum;
887  resk += wgk[jtw - 1] * fsum;
888  *resabs += wgk[jtw - 1] * (fabs(fval1) + fabs(fval2));
889  }
890  for (j = 1; j <= 5; ++j) {
891  jtwm1 = (j << 1) - 1;
892  absc = hlgth * xgk[jtwm1 - 1];
893  fval1 = vec[(j << 1) + 9];
894  fval2 = vec[(j << 1) + 10];
895  fv1[jtwm1 - 1] = fval1;
896  fv2[jtwm1 - 1] = fval2;
897  fsum = fval1 + fval2;
898  resk += wgk[jtwm1 - 1] * fsum;
899  *resabs += wgk[jtwm1 - 1] * (fabs(fval1) + fabs(fval2));
900  }
901  reskh = resk * .5;
902  *resasc = wgk[10] * fabs(fc - reskh);
903  for (j = 1; j <= 10; ++j) {
904  *resasc +=
905  wgk[j - 1] * (fabs(fv1[j - 1] - reskh) + fabs(fv2[j - 1] - reskh));
906  }
907  *result = resk * hlgth;
908  *resabs *= dhlgth;
909  *resasc *= dhlgth;
910  *abserr = fabs((resk - resg) * hlgth);
911  if (*resasc != 0. && *abserr != 0.) {
912  *abserr = *resasc * fmin2(1., pow(*abserr * 200. / *resasc, 1.5));
913  }
914  if (*resabs > uflow / (epmach * 50.)) {
915  *abserr = fmax2(epmach * 50. * *resabs, *abserr);
916  }
917  return;
918 }
919 
920 template <class Float>
921 static void rdqpsrt(int *limit, int *last, int *maxerr, Float *ermax,
922  Float *elist, int *iord, int *nrmax) {
923  int i, j, k, ido, jbnd, isucc, jupbn;
924  Float errmin, errmax;
925  --iord;
926  --elist;
927 
928  if (*last <= 2) {
929  iord[1] = 1;
930  iord[2] = 2;
931  goto Last;
932  }
933 
934  errmax = elist[*maxerr];
935  if (*nrmax > 1) {
936  ido = *nrmax - 1;
937  for (i = 1; i <= ido; ++i) {
938  isucc = iord[*nrmax - 1];
939  if (errmax <= elist[isucc]) break;
940  iord[*nrmax] = isucc;
941  --(*nrmax);
942  }
943  }
944 
945  if (*last > *limit / 2 + 2)
946  jupbn = *limit + 3 - *last;
947  else
948  jupbn = *last;
949 
950  errmin = elist[*last];
951 
952  jbnd = jupbn - 1;
953  for (i = *nrmax + 1; i <= jbnd; ++i) {
954  isucc = iord[i];
955  if (errmax >= elist[isucc]) {
956  iord[i - 1] = *maxerr;
957  for (j = i, k = jbnd; j <= jbnd; j++, k--) {
958  isucc = iord[k];
959  if (errmin < elist[isucc]) {
960  iord[k + 1] = *last;
961  goto Last;
962  }
963  iord[k + 1] = isucc;
964  }
965  iord[i] = *last;
966  goto Last;
967  }
968  iord[i - 1] = isucc;
969  }
970 
971  iord[jbnd] = *maxerr;
972  iord[jupbn] = *last;
973 
974 Last:
975 
976  *maxerr = iord[*nrmax];
977  *ermax = elist[*maxerr];
978  return;
979 }
980 
988 struct control {
989  int subdivisions;
990  double reltol;
991  double abstol;
992  control(int subdivisions_ = 100, double reltol_ = 1e-4,
993  double abstol_ = 1e-4);
994 };
995 
1010 template <class Integrand>
1011 struct Integral {
1012  typedef typename Integrand::Scalar Type;
1013 
1014  struct vectorized_integrand {
1015  Integrand f;
1016  vectorized_integrand(Integrand f_) : f(f_) {}
1017  void operator()(Type *x, int n, void *ex) {
1018  for (int i = 0; i < n; i++) x[i] = f(x[i]);
1019  }
1020  } fn;
1022  Integrand &integrand() { return fn.f; }
1023 
1024  Type epsabs, epsrel, result, abserr;
1025  int neval, ier, limit, lenw, last;
1026  std::vector<int> iwork;
1027  std::vector<Type> work;
1028  void setAccuracy(double epsrel_ = 1e-4, double epsabs_ = 1e-4) {
1029  epsabs = epsabs_;
1030  epsrel = epsrel_;
1031  result = 0;
1032  abserr = 1e4;
1033  neval = 0;
1034  ier = 0;
1035  last = 0;
1036  }
1037  void setWorkspace(int subdivisions = 100) {
1038  limit = subdivisions;
1039  lenw = 4 * limit;
1040  iwork.resize(limit);
1041  work.resize(lenw);
1042  }
1043  Type a, b, bound;
1044  int inf;
1045  void setBounds(Type a_, Type b_) {
1046  int a_finite = (a_ != -INFINITY) && (a_ != INFINITY);
1047  int b_finite = (b_ != -INFINITY) && (b_ != INFINITY);
1048  if (a_finite && b_finite) {
1049  inf = 0;
1050  a = a_;
1051  b = b_;
1052  } else if (a_finite && !b_finite) {
1053  inf = 1;
1054  bound = a_;
1055  } else if (!a_finite && b_finite) {
1056  inf = -1;
1057  bound = b_;
1058  } else {
1059  inf = 2;
1060  }
1061  }
1068  Integral(Integrand f_, Type a_, Type b_, control c = control()) : fn(f_) {
1069  setAccuracy(c.reltol, c.abstol);
1070  setWorkspace(c.subdivisions);
1071  setBounds(a_, b_);
1072  }
1073  Type operator()() {
1074  if (inf)
1075  Rdqagi(fn, NULL, &bound, &inf, &epsabs, &epsrel, &result, &abserr, &neval,
1076  &ier, &limit, &lenw, &last, &iwork[0], &work[0]);
1077  else
1078  Rdqags(fn, NULL, &a, &b, &epsabs, &epsrel, &result, &abserr, &neval, &ier,
1079  &limit, &lenw, &last, &iwork[0], &work[0]);
1080  return result;
1081  }
1082 };
1083 
1110 template <class Integrand>
1111 typename Integrand::Scalar integrate(Integrand f,
1112  typename Integrand::Scalar a = -INFINITY,
1113  typename Integrand::Scalar b = INFINITY,
1114  control c = control()) {
1115  Integral<Integrand> I(f, a, b, c);
1116  return I();
1117 }
1118 
1133 template <class Integrand>
1134 struct mvIntegral {
1135  typedef typename Integrand::Scalar Scalar;
1136  struct evaluator {
1137  typedef typename Integrand::Scalar Scalar;
1138  Integrand &f;
1139  Scalar &x;
1140  evaluator(Integrand &f_, Scalar &x_) : f(f_), x(x_) {}
1141  Scalar operator()(const Scalar &x_) {
1142  x = x_;
1143  return f();
1144  }
1145  } ev;
1146  control c;
1148  mvIntegral(Integrand &f_, Scalar &x_, Scalar a = -INFINITY,
1149  Scalar b = INFINITY, control c_ = control())
1150  : ev(f_, x_), c(c_), I(ev, a, b, c_) {}
1151  Scalar operator()() { return I(); }
1153  mvIntegral<mvIntegral> wrt(Scalar &x, Scalar a = -INFINITY,
1154  Scalar b = INFINITY) {
1155  return mvIntegral<mvIntegral>(*this, x, a, b, c);
1156  }
1157 };
1158 
1159 template <class Integrand>
1160 struct mvIntegral0 {
1161  typedef typename Integrand::Scalar Scalar;
1162  Integrand &f;
1163  control c;
1164  mvIntegral0(Integrand &f_, control c_) : f(f_), c(c_) {}
1166  mvIntegral<Integrand> wrt(Scalar &x, Scalar a = -INFINITY,
1167  Scalar b = INFINITY) {
1168  return mvIntegral<Integrand>(f, x, a, b, c);
1169  }
1170 };
1198 template <class Integrand>
1199 mvIntegral0<Integrand> mvIntegrate(Integrand &f, control c = control()) {
1200  return mvIntegral0<Integrand>(f, c);
1201 }
1202 
1203 } // namespace TMBad
1204 #endif // HAVE_INTEGRATE_HPP
Automatic differentiation library designed for TMB.
Definition: TMB.hpp:157
mvIntegral< mvIntegral > wrt(Scalar &x, Scalar a=-INFINITY, Scalar b=INFINITY)
With respect to.
Integral(Integrand f_, Type a_, Type b_, control c=control())
Constructor.
Integrand & integrand()
Return reference to integrand so the user can change parameters.
Integrand::Scalar integrate(Integrand f, typename Integrand::Scalar a=-INFINITY, typename Integrand::Scalar b=INFINITY, control c=control())
Integrate function over finite or infinite interval.
Interface to R&#39;s adaptive integrate routine.
double value(T x)
Namespace with utility functions for adaptive numerical integration.
mvIntegral0< Integrand > mvIntegrate(Integrand &f, control c=control())
Multivariate integration.
Multivariate integral class.
User control parameters for R&#39;s integrate.
License: GPL v2