AcouSTO  version 2.0

◆ rule75genzmalik_evalError()

static int rule75genzmalik_evalError ( rule r_,
unsigned  fdim,
integrand_v  f,
void *  fdata,
unsigned  nR,
region R 
)
static
461 {
462  /* lambda2 = sqrt(9/70), lambda4 = sqrt(9/10), lambda5 = sqrt(9/19) */
463  const double lambda2 = 0.3585685828003180919906451539079374954541;
464  const double lambda4 = 0.9486832980505137995996680633298155601160;
465  const double lambda5 = 0.6882472016116852977216287342936235251269;
466  const double weight2 = 980. / 6561.;
467  const double weight4 = 200. / 19683.;
468  const double weightE2 = 245. / 486.;
469  const double weightE4 = 25. / 729.;
470  const double ratio = (lambda2 * lambda2) / (lambda4 * lambda4);
471 
472  rule75genzmalik *r = (rule75genzmalik *) r_;
473  unsigned i, j, iR, dim = r_->dim, npts = 0;
474  double *diff, *pts, *vals;
475 
476  if (alloc_rule_pts(r_, nR)) return FAILURE;
477  pts = r_->pts; vals = r_->vals;
478 
479  for (iR = 0; iR < nR; ++iR) {
480  const double *center = R[iR].h.data;
481  const double *halfwidth = R[iR].h.data + dim;
482 
483  for (i = 0; i < dim; ++i)
484  r->p[i] = center[i];
485 
486  for (i = 0; i < dim; ++i)
487  r->widthLambda2[i] = halfwidth[i] * lambda2;
488  for (i = 0; i < dim; ++i)
489  r->widthLambda[i] = halfwidth[i] * lambda4;
490 
491  /* Evaluate points in the center, in (lambda2,0,...,0) and
492  (lambda3=lambda4, 0,...,0). */
493  evalR0_0fs4d(pts + npts*dim, dim, r->p, center,
494  r->widthLambda2, r->widthLambda);
495  npts += num0_0(dim) + 2 * numR0_0fs(dim);
496 
497  /* Calculate points for (lambda4, lambda4, 0, ...,0) */
498  evalRR0_0fs(pts + npts*dim, dim, r->p, center, r->widthLambda);
499  npts += numRR0_0fs(dim);
500 
501  /* Calculate points for (lambda5, lambda5, ..., lambda5) */
502  for (i = 0; i < dim; ++i)
503  r->widthLambda[i] = halfwidth[i] * lambda5;
504  evalR_Rfs(pts + npts*dim, dim, r->p, center, r->widthLambda);
505  npts += numR_Rfs(dim);
506  }
507 
508  /* Evaluate the integrand function(s) at all the points */
509  f(dim, npts, pts, fdata, fdim, vals);
510 
511  /* we are done with the points, and so we can re-use the pts
512  array to store the maximum difference diff[i] in each dimension
513  for each hypercube */
514  diff = pts;
515  for (i = 0; i < dim * nR; ++i) diff[i] = 0;
516 
517  for (j = 0; j < fdim; ++j) {
518  for (iR = 0; iR < nR; ++iR) {
519  double result, res5th;
520  double val0, sum2=0, sum3=0, sum4=0, sum5=0;
521  unsigned k, k0 = 0;
522 
523  /* accumulate j-th function values into j-th integrals
524  NOTE: this relies on the ordering of the eval functions
525  above, as well as on the internal structure of
526  the evalR0_0fs4d function */
527 
528  val0 = vals[0]; /* central point */
529  k0 += 1;
530 
531  for (k = 0; k < dim; ++k) {
532  double v0 = vals[k0 + 4*k];
533  double v1 = vals[(k0 + 4*k) + 1];
534  double v2 = vals[(k0 + 4*k) + 2];
535  double v3 = vals[(k0 + 4*k) + 3];
536 
537  sum2 += v0 + v1;
538  sum3 += v2 + v3;
539 
540  diff[iR * dim + k] +=
541  fabs(v0 + v1 - 2*val0 - ratio * (v2 + v3 - 2*val0));
542  }
543  k0 += 4*k;
544 
545  for (k = 0; k < numRR0_0fs(dim); ++k)
546  sum4 += vals[k0 + k];
547  k0 += k;
548 
549  for (k = 0; k < numR_Rfs(dim); ++k)
550  sum5 += vals[k0 + k];
551 
552  /* Calculate fifth and seventh order results */
553  result = R[iR].h.vol * (r->weight1 * val0 + weight2 * sum2 + r->weight3 * sum3 + weight4 * sum4 + r->weight5 * sum5);
554  res5th = R[iR].h.vol * (r->weightE1 * val0 + weightE2 * sum2 + r->weightE3 * sum3 + weightE4 * sum4);
555 
556  R[iR].ee[j].val = result;
557  R[iR].ee[j].err = fabs(res5th - result);
558 
559  vals += r_->num_points;
560  }
561  }
562 
563  /* figure out dimension to split: */
564  for (iR = 0; iR < nR; ++iR) {
565  double maxdiff = 0;
566  unsigned dimDiffMax = 0;
567 
568  for (i = 0; i < dim; ++i)
569  if (diff[iR*dim + i] > maxdiff) {
570  maxdiff = diff[iR*dim + i];
571  dimDiffMax = i;
572  }
573  R[iR].splitDim = dimDiffMax;
574  }
575  return SUCCESS;
576 }
double weightE1
Definition: cubature.c:443
static void evalR0_0fs4d(double *pts, unsigned dim, double *p, const double *c, const double *r1, const double *r2)
Definition: cubature.c:396
double * widthLambda2
Definition: cubature.c:439
static void evalR_Rfs(double *pts, unsigned dim, double *p, const double *c, const double *r)
Definition: cubature.c:347
#define SUCCESS
Definition: cubature.c:109
double weight1
Definition: cubature.c:442
double weight3
Definition: cubature.c:442
static void evalRR0_0fs(double *pts, unsigned dim, double *p, const double *c, const double *r)
Definition: cubature.c:374
unsigned splitDim
Definition: cubature.c:187
unsigned num_points
Definition: cubature.c:234
#define num0_0(dim)
Definition: cubature.c:420
double * vals
Definition: cubature.c:237
double * widthLambda
Definition: cubature.c:439
double * p
Definition: cubature.c:439
static int alloc_rule_pts(rule *r, unsigned num_regions)
Definition: cubature.c:251
unsigned dim
Definition: cubature.c:233
Definition: cubature.c:435
double * pts
Definition: cubature.c:236
#define numR0_0fs(dim)
Definition: cubature.c:421
double err
Definition: cubature.c:116
double val
Definition: cubature.c:116
double weightE3
Definition: cubature.c:443
#define numRR0_0fs(dim)
Definition: cubature.c:422
double weight5
Definition: cubature.c:442
hypercube h
Definition: cubature.c:186
double vol
Definition: cubature.c:136
#define numR_Rfs(dim)
Definition: cubature.c:423
#define FAILURE
Definition: cubature.c:110
esterr * ee
Definition: cubature.c:189
double * data
Definition: cubature.c:135