PISM, A Parallel Ice Sheet Model  stable v0.5
src/earth/test_cube.c
Go to the documentation of this file.
00001 
00002 /* 
00003    Usage: ./test_cube <dim> <tol> <integrand> <maxeval>
00004 
00005    where <dim> = # dimensions, <tol> = relative tolerance,
00006    <integrand> is either 0/1/2 for the three test integrands (see below),
00007    and <maxeval> is the maximum # function evaluations (0 for none).
00008 */
00009 
00010 /* author Steven G. Johnson */
00011 
00012 #include "cubature.h"
00013 #include <math.h>
00014 
00015 int count = 0;
00016 int which_integrand = 0;
00017 const double radius = 0.50124145262344534123412; /* random */
00018 
00019 double f_test(unsigned dim, const double *x, void *data)
00020 {
00021      double val;
00022      unsigned i;
00023      ++count;
00024      switch (which_integrand) {
00025      case 0: /* discontinuous objective: volume of hypersphere */
00026           val = 0;
00027           for (i = 0; i < dim; ++i)
00028            val += x[i] * x[i];
00029           val = val < radius * radius;
00030           break;
00031      case 1: /* simple smooth (separable) objective: prod. cos(x[i]). */
00032           val = 1;
00033           for (i = 0; i < dim; ++i)
00034            val *= cos(x[i]);
00035           break;
00036      case 2: { /* integral of exp(-x^2), rescaled to (0,infinity) limits */
00037           double scale = 1.0;
00038           val = 0;
00039           for (i = 0; i < dim; ++i) {
00040            double z = (1 - x[i]) / x[i];
00041            val += z * z;
00042            scale *= M_2_SQRTPI / (x[i] * x[i]);
00043           }
00044           val = exp(-val) * scale;
00045           break;
00046      }
00047 
00048      default:
00049           fprintf(stderr, "unknown integrand %d\n", which_integrand);
00050           exit(EXIT_FAILURE);
00051      }
00052      /* if (count < 100) printf("%d: f(%g, ...) = %g\n", count, x[0], val); */
00053      return val;
00054 }
00055 
00056 /* surface area of n-dimensional unit hypersphere */
00057 static double S(unsigned n)
00058 {
00059      double val;
00060      int fact = 1;
00061      if (n % 2 == 0) { /* n even */
00062       val = 2 * pow(M_PI, n * 0.5);
00063       n = n / 2;
00064       while (n > 1) fact *= (n -= 1);
00065       val /= fact;
00066      }
00067      else { /* n odd */
00068       val = (1 << (n/2 + 1)) * pow(M_PI, n/2);
00069       while (n > 2) fact *= (n -= 2);
00070       val /= fact;
00071      }
00072      return val;
00073 }
00074 
00075 static double exact_integral(unsigned dim, const double *xmax) {
00076      unsigned i;
00077      double val;
00078      switch(which_integrand) {
00079      case 0:
00080           val = dim == 0 ? 1 : S(dim) * pow(radius * 0.5, dim) / dim;
00081           break;
00082      case 1:
00083           val = 1;
00084           for (i = 0; i < dim; ++i)
00085            val *= sin(xmax[i]);
00086           break;
00087      case 2:
00088           val = 1;
00089           break;
00090      default:
00091           fprintf(stderr, "unknown integrand %d\n", which_integrand);
00092               exit(EXIT_FAILURE);
00093      }
00094      return val;
00095 }
00096 
00097 int main(int argc, char **argv)
00098 {
00099      double *xmin, *xmax;
00100      double tol, val, err;
00101      unsigned i, dim, maxEval;
00102 
00103      dim = argc > 1 ? atoi(argv[1]) : 2;
00104      tol = argc > 2 ? atof(argv[2]) : 1e-2;
00105      which_integrand = argc > 3 ? atoi(argv[3]) : 1;
00106      maxEval = argc > 4 ? atoi(argv[4]) : 0;
00107 
00108      xmin = (double *) malloc(dim * sizeof(double));
00109      xmax = (double *) malloc(dim * sizeof(double));
00110      for (i = 0; i < dim; ++i) {
00111       xmin[i] = 0;
00112       xmax[i] = 1 + (which_integrand == 2 ? 0 : 0.4 * sin(i));
00113      }
00114 
00115      printf("%u-dim integral, tolerance = %g, integrand = %d\n",
00116         dim, tol, which_integrand);
00117      adapt_integrate(f_test, 0, dim, xmin, xmax, maxEval, 0, tol, &val, &err);
00118      printf("integration val = %g, est. err = %g, true err = %g\n",
00119         val, err, fabs(val - exact_integral(dim, xmax)));
00120      printf("#evals = %d\n", count);
00121 
00122      free(xmax);
00123      free(xmin);
00124 
00125      return 0;
00126 }
00127 
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines