/* cube_int.c integrate a function over a cube */ /* this is numerical quadrature */ /* basically compute a 4D volume under 3D function */ /* compare methods for accuracy */ /* first trapezoid rule, varying step size, int f(x,y,z) dx dx dz */ /* then using Gauss-Legendre coordinates and weights */ /* remember np points or nodes means np*np*np function evaluations */ /* or (np-1)^3 cube elements */ #include #include #undef abs #define abs(x) ((x)<0.0?(-(x)):(x)) static void gaulegf(double x1, double x2, double x[], double w[], int n); static double f1(double x, double y, double z) { return x+2.0*y+3.0*z+4.0; /* linear, first order */ } static double f2(double x, double y, double z) { return x*x+2.0*y*y+3.0*z*z+4.0*x*y+5.0*x*z+6.0*y*z+ 7.0*x+8.0*y+9.0*z+10.0; /* quadratic, second order */ } static double f3(double x, double y, double z) { return x*x*x + 2.0*y*y*y + 3.0*z*z*z + 4.0*x*x*y + 5.0*x*x*z + 6.0*x*y*y + 7.0*x*y*z + 8.0*x*z*z + 9.0*y*y*z + 10.0*y*z*z + 11.0*x*x+12.0*y*y+13.0*z*z+14.0*x*y+15.0*x*z+16.0*y*z+ 17.0*x+18.0*y+19.0*z+20.0; /* cubic, third order */ } static double fe(double x, double y, double z) { return exp(x)*exp(y)*exp(z); } int main(int argc, char *argv[]) { /* simple trapezoidal integration from x=1 to x=3*/ double volume; double x, y, z, hx, hy, hz; double xmin = 1.0; double xmax = 3.0; double ymin = 0.5; double ymax = 2.0; double zmin = 0.25; double zmax = 2.25; double f1exact = 73.5; double f2exact = 543.875; double f3exact = 2887.96875; double feexact = 817.8595522; double xx[200], wx[200]; /* for Gauss-Legendre */ double yy[200], wy[200]; /* for Gauss-Legendre */ double zz[200], wz[200]; /* for Gauss-Legendre */ int i, j, k, np; printf("cube_int.c integrate to find 4D volume \n"); printf("Numerical quadrature, x=%g to x=%g, y=%g to y=%g, z=%g to z=%g \n", xmin, xmax, ymin, ymax, zmin, zmax); printf("\n"); printf("Using trapezoidal method \n"); np = 4; hx = (xmax-xmin)/(double)(np-1); hy = (ymax-ymin)/(double)(np-1); hz = (zmax-zmin)/(double)(np-1); printf("f1(x,y,z)=x+2*y+3*z+4 np=%d, hx=%g, hy=%g, hz=%g \n", np, hx, hy, hz); volume = 0.0; for(i=0; i