AcouSTO  version 2.0

◆ rule15gauss_evalError()

static int rule15gauss_evalError ( rule r,
unsigned  fdim,
integrand_v  f,
void *  fdata,
unsigned  nR,
region R 
)
static
622 {
623  /* Gauss quadrature weights and kronrod quadrature abscissae and
624  weights as evaluated with 80 decimal digit arithmetic by
625  L. W. Fullerton, Bell Labs, Nov. 1981. */
626  const unsigned n = 8;
627  const double xgk[8] = { /* abscissae of the 15-point kronrod rule */
628  0.991455371120812639206854697526329,
629  0.949107912342758524526189684047851,
630  0.864864423359769072789712788640926,
631  0.741531185599394439863864773280788,
632  0.586087235467691130294144838258730,
633  0.405845151377397166906606412076961,
634  0.207784955007898467600689403773245,
635  0.000000000000000000000000000000000
636  /* xgk[1], xgk[3], ... abscissae of the 7-point gauss rule.
637  xgk[0], xgk[2], ... to optimally extend the 7-point gauss rule */
638  };
639  static const double wg[4] = { /* weights of the 7-point gauss rule */
640  0.129484966168869693270611432679082,
641  0.279705391489276667901467771423780,
642  0.381830050505118944950369775488975,
643  0.417959183673469387755102040816327
644  };
645  static const double wgk[8] = { /* weights of the 15-point kronrod rule */
646  0.022935322010529224963732008058970,
647  0.063092092629978553290700663189204,
648  0.104790010322250183839876322541518,
649  0.140653259715525918745189590510238,
650  0.169004726639267902826583426598550,
651  0.190350578064785409913256402421014,
652  0.204432940075298892414161999234649,
653  0.209482141084727828012999174891714
654  };
655  unsigned j, k, iR, npts = 0;
656  double *pts, *vals;
657 
658  if (alloc_rule_pts(r, nR)) return FAILURE;
659  pts = r->pts; vals = r->vals;
660 
661  for (iR = 0; iR < nR; ++iR) {
662  const double center = R[iR].h.data[0];
663  const double halfwidth = R[iR].h.data[1];
664 
665  pts[npts++] = center;
666 
667  for (j = 0; j < (n - 1) / 2; ++j) {
668  int j2 = 2*j + 1;
669  double w = halfwidth * xgk[j2];
670  pts[npts++] = center - w;
671  pts[npts++] = center + w;
672  }
673  for (j = 0; j < n/2; ++j) {
674  int j2 = 2*j;
675  double w = halfwidth * xgk[j2];
676  pts[npts++] = center - w;
677  pts[npts++] = center + w;
678  }
679 
680  R[iR].splitDim = 0; /* no choice but to divide 0th dimension */
681  }
682 
683  f(1, npts, pts, fdata, fdim, vals);
684 
685  for (k = 0; k < fdim; ++k) {
686  for (iR = 0; iR < nR; ++iR) {
687  const double halfwidth = R[iR].h.data[1];
688  double result_gauss = vals[0] * wg[n/2 - 1];
689  double result_kronrod = vals[0] * wgk[n - 1];
690  double result_abs = fabs(result_kronrod);
691  double result_asc, mean, err;
692 
693  /* accumulate integrals */
694  npts = 1;
695  for (j = 0; j < (n - 1) / 2; ++j) {
696  int j2 = 2*j + 1;
697  double v = vals[npts] + vals[npts+1];
698  result_gauss += wg[j] * v;
699  result_kronrod += wgk[j2] * v;
700  result_abs += wgk[j2] * (fabs(vals[npts])
701  + fabs(vals[npts+1]));
702  npts += 2;
703  }
704  for (j = 0; j < n/2; ++j) {
705  int j2 = 2*j;
706  result_kronrod += wgk[j2] * (vals[npts] + vals[npts+1]);
707  result_abs += wgk[j2] * (fabs(vals[npts])
708  + fabs(vals[npts+1]));
709  npts += 2;
710  }
711 
712  /* integration result */
713  R[iR].ee[k].val = result_kronrod * halfwidth;
714 
715  /* error estimate
716  (from GSL, probably dates back to QUADPACK
717  ... not completely clear to me why we don't just use
718  fabs(result_kronrod - result_gauss) * halfwidth */
719  mean = result_kronrod * 0.5;
720  result_asc = wgk[n - 1] * fabs(vals[0] - mean);
721  npts = 1;
722  for (j = 0; j < (n - 1) / 2; ++j) {
723  int j2 = 2*j + 1;
724  result_asc += wgk[j2] * (fabs(vals[npts]-mean)
725  + fabs(vals[npts+1]-mean));
726  npts += 2;
727  }
728  for (j = 0; j < n/2; ++j) {
729  int j2 = 2*j;
730  result_asc += wgk[j2] * (fabs(vals[npts]-mean)
731  + fabs(vals[npts+1]-mean));
732  npts += 2;
733  }
734  err = fabs(result_kronrod - result_gauss) * halfwidth;
735  result_abs *= halfwidth;
736  result_asc *= halfwidth;
737  if (result_asc != 0 && err != 0) {
738  double scale = pow((200 * err / result_asc), 1.5);
739  err = (scale < 1) ? result_asc * scale : result_asc;
740  }
741  if (result_abs > DBL_MIN / (50 * DBL_EPSILON)) {
742  double min_err = 50 * DBL_EPSILON * result_abs;
743  if (min_err > err) err = min_err;
744  }
745  R[iR].ee[k].err = err;
746 
747  /* increment vals to point to next batch of results */
748  vals += 15;
749  }
750  }
751  return SUCCESS;
752 }
#define SUCCESS
Definition: cubature.c:109
unsigned splitDim
Definition: cubature.c:187
double * vals
Definition: cubature.c:237
static int alloc_rule_pts(rule *r, unsigned num_regions)
Definition: cubature.c:251
double * pts
Definition: cubature.c:236
double err
Definition: cubature.c:116
double val
Definition: cubature.c:116
hypercube h
Definition: cubature.c:186
#define FAILURE
Definition: cubature.c:110
esterr * ee
Definition: cubature.c:189
double * data
Definition: cubature.c:135