public static double tetra_07(int setting, Func <int, double, double, double, double> func, double[] x, double[] y, double[] z) //****************************************************************************80 // // Purpose: // // TETRA_07 approximates an integral inside a tetrahedron in 3D. // // Integration region: // // Points inside a tetrahedron whose four corners are given. // // Discussion: // // A 64 point 7-th degree conical product Gauss formula is used, // Stroud number T3:7-1. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 March 2008 // // Author: // // John Burkardt // // Reference: // // Arthur Stroud, // Approximate Calculation of Multiple Integrals, // Prentice Hall, 1971, // ISBN: 0130438936, // LC: QA311.S85. // // Arthur Stroud, Don Secrest, // Gaussian Quadrature Formulas, // Prentice Hall, 1966, pages 42-43, // LC: QA299.4G3S7 // // Parameters: // // Input, Func< double, double, double, double > func, the name of the // user supplied function to be integrated. // // Input, double X[4], Y[4], Z[4], the coordinates of // the vertices. // // Output, double TETRAQ_07, the approximate integral of the function. // { int i; const int order = 4; double[] weight1 = new double[4]; double[] weight2 = { 0.1355069134, 0.2034645680, 0.1298475476, 0.0311809709 }; double[] weight3 = { 0.1108884156, 0.1434587898, 0.0686338872, 0.0103522407 }; double[] xtab1 = new double[4]; double[] xtab2 = { 0.0571041961, 0.2768430136, 0.5835904324, 0.8602401357 }; double[] xtab3 = { 0.0485005495, 0.2386007376, 0.5170472951, 0.7958514179 }; // // Get the Gauss-Legendre weights and abscissas for [-1,1]. // LegendreQuadrature.legendre_set(order, ref xtab1, ref weight1); // // Adjust the rule for the interval [0,1]. // const double a = -1.0; const double b = +1.0; const double c = 0.0; const double d = 1.0; QuadratureRule.rule_adjust(a, b, c, d, order, ref xtab1, ref weight1); // // Carry out the quadrature. // double quad = 0.0; for (i = 0; i < order; i++) { int j; for (j = 0; j < order; j++) { int k; for (k = 0; k < order; k++) { // // Compute the barycentric coordinates of the point in the unit triangle. // double t = xtab3[k]; double u = xtab2[j] * (1.0 - xtab3[k]); double v = xtab1[i] * (1.0 - xtab2[j]) * (1.0 - xtab3[k]); double w = 1.0 - t - u - v; // // Compute the corresponding point in the triangle. // double xval = t * x[0] + u * x[1] + v * x[2] + w * x[3]; double yval = t * y[0] + u * y[1] + v * y[2] + w * y[3]; double zval = t * z[0] + u * z[1] + v * z[2] + w * z[3]; quad += 6.0 * weight1[i] * weight2[j] * weight3[k] * func(setting, xval, yval, zval); } } } double volume = tetra_volume(x, y, z); double result = quad * volume; return(result); }
public static ClenshawCurtis.ccResult kpu(int n, double[] x_, double[] w_) //****************************************************************************80 // // Purpose: // // KPU provides data for Kronrod-Patterson quadrature with a uniform weight. // // Discussion: // // This data assumes integration over the interval [0,1] with // weight function w(x) = 1. // // This data was originally supplied with only 7 digit accuracy. // It has been replaced by higher accuracy data, which is defined over [-1,+1], // but adjusted to the interval [0,1] before return. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 11 December 2012 // // Author: // // John Burkardt. // // Reference: // // Florian Heiss, Viktor Winschel, // Likelihood approximation by numerical integration on sparse grids, // Journal of Econometrics, // Volume 144, 2008, pages 62-80. // // Alan Genz, Bradley Keister, // Fully symmetric interpolatory rules for multiple integrals // over infinite regions with Gaussian weight, // Journal of Computational and Applied Mathematics, // Volume 71, 1996, pages 299-309. // // Thomas Patterson, // The optimal addition of points to quadrature formulae, // Mathematics of Computation, // Volume 22, Number 104, October 1968, pages 847-856. // // Parameters: // // Input, int N, the order of the rule. // Only 1, 3, 7, 15, 31 and 63 are legal input values for N. // // Output, double X[N], the nodes. // // Output, double W[N], the weights. // { ClenshawCurtis.ccResult result = new() { x = x_, w = w_ }; double[] x01 = { 0.0000000 }; double[] w01 = { 2.0000000 }; double[] x03 = { -0.77459666924148337704, 0.0, 0.77459666924148337704 }; double[] w03 = { 0.555555555555555555556, 0.888888888888888888889, 0.555555555555555555556 }; double[] x07 = { -0.96049126870802028342, -0.77459666924148337704, -0.43424374934680255800, 0.0, 0.43424374934680255800, 0.77459666924148337704, 0.96049126870802028342 }; double[] w07 = { 0.104656226026467265194, 0.268488089868333440729, 0.401397414775962222905, 0.450916538658474142345, 0.401397414775962222905, 0.268488089868333440729, 0.104656226026467265194 }; double[] x15 = { -0.99383196321275502221, -0.96049126870802028342, -0.88845923287225699889, -0.77459666924148337704, -0.62110294673722640294, -0.43424374934680255800, -0.22338668642896688163, 0.0, 0.22338668642896688163, 0.43424374934680255800, 0.62110294673722640294, 0.77459666924148337704, 0.88845923287225699889, 0.96049126870802028342, 0.99383196321275502221 }; double[] w15 = { 0.0170017196299402603390, 0.0516032829970797396969, 0.0929271953151245376859, 0.134415255243784220360, 0.171511909136391380787, 0.200628529376989021034, 0.219156858401587496404, 0.225510499798206687386, 0.219156858401587496404, 0.200628529376989021034, 0.171511909136391380787, 0.134415255243784220360, 0.0929271953151245376859, 0.0516032829970797396969, 0.0170017196299402603390 }; double[] x31 = { -0.99909812496766759766, -0.99383196321275502221, -0.98153114955374010687, -0.96049126870802028342, -0.92965485742974005667, -0.88845923287225699889, -0.83672593816886873550, -0.77459666924148337704, -0.70249620649152707861, -0.62110294673722640294, -0.53131974364437562397, -0.43424374934680255800, -0.33113539325797683309, -0.22338668642896688163, -0.11248894313318662575, 0.0, 0.11248894313318662575, 0.22338668642896688163, 0.33113539325797683309, 0.43424374934680255800, 0.53131974364437562397, 0.62110294673722640294, 0.70249620649152707861, 0.77459666924148337704, 0.83672593816886873550, 0.88845923287225699889, 0.92965485742974005667, 0.96049126870802028342, 0.98153114955374010687, 0.99383196321275502221, 0.99909812496766759766 }; double[] w31 = { 0.00254478079156187441540, 0.00843456573932110624631, 0.0164460498543878109338, 0.0258075980961766535646, 0.0359571033071293220968, 0.0464628932617579865414, 0.0569795094941233574122, 0.0672077542959907035404, 0.0768796204990035310427, 0.0857559200499903511542, 0.0936271099812644736167, 0.100314278611795578771, 0.105669893580234809744, 0.109578421055924638237, 0.111956873020953456880, 0.112755256720768691607, 0.111956873020953456880, 0.109578421055924638237, 0.105669893580234809744, 0.100314278611795578771, 0.0936271099812644736167, 0.0857559200499903511542, 0.0768796204990035310427, 0.0672077542959907035404, 0.0569795094941233574122, 0.0464628932617579865414, 0.0359571033071293220968, 0.0258075980961766535646, 0.0164460498543878109338, 0.00843456573932110624631, 0.00254478079156187441540 }; double[] x63 = { -0.99987288812035761194, -0.99909812496766759766, -0.99720625937222195908, -0.99383196321275502221, -0.98868475754742947994, -0.98153114955374010687, -0.97218287474858179658, -0.96049126870802028342, -0.94634285837340290515, -0.92965485742974005667, -0.91037115695700429250, -0.88845923287225699889, -0.86390793819369047715, -0.83672593816886873550, -0.80694053195021761186, -0.77459666924148337704, -0.73975604435269475868, -0.70249620649152707861, -0.66290966002478059546, -0.62110294673722640294, -0.57719571005204581484, -0.53131974364437562397, -0.48361802694584102756, -0.43424374934680255800, -0.38335932419873034692, -0.33113539325797683309, -0.27774982202182431507, -0.22338668642896688163, -0.16823525155220746498, -0.11248894313318662575, -0.056344313046592789972, 0.0, 0.056344313046592789972, 0.11248894313318662575, 0.16823525155220746498, 0.22338668642896688163, 0.27774982202182431507, 0.33113539325797683309, 0.38335932419873034692, 0.43424374934680255800, 0.48361802694584102756, 0.53131974364437562397, 0.57719571005204581484, 0.62110294673722640294, 0.66290966002478059546, 0.70249620649152707861, 0.73975604435269475868, 0.77459666924148337704, 0.80694053195021761186, 0.83672593816886873550, 0.86390793819369047715, 0.88845923287225699889, 0.91037115695700429250, 0.92965485742974005667, 0.94634285837340290515, 0.96049126870802028342, 0.97218287474858179658, 0.98153114955374010687, 0.98868475754742947994, 0.99383196321275502221, 0.99720625937222195908, 0.99909812496766759766, 0.99987288812035761194 }; double[] w63 = { 0.000363221481845530659694, 0.00126515655623006801137, 0.00257904979468568827243, 0.00421763044155885483908, 0.00611550682211724633968, 0.00822300795723592966926, 0.0104982469096213218983, 0.0129038001003512656260, 0.0154067504665594978021, 0.0179785515681282703329, 0.0205942339159127111492, 0.0232314466399102694433, 0.0258696793272147469108, 0.0284897547458335486125, 0.0310735511116879648799, 0.0336038771482077305417, 0.0360644327807825726401, 0.0384398102494555320386, 0.0407155101169443189339, 0.0428779600250077344929, 0.0449145316536321974143, 0.0468135549906280124026, 0.0485643304066731987159, 0.0501571393058995374137, 0.0515832539520484587768, 0.0528349467901165198621, 0.0539054993352660639269, 0.0547892105279628650322, 0.0554814043565593639878, 0.0559784365104763194076, 0.0562776998312543012726, 0.0563776283603847173877, 0.0562776998312543012726, 0.0559784365104763194076, 0.0554814043565593639878, 0.0547892105279628650322, 0.0539054993352660639269, 0.0528349467901165198621, 0.0515832539520484587768, 0.0501571393058995374137, 0.0485643304066731987159, 0.0468135549906280124026, 0.0449145316536321974143, 0.0428779600250077344929, 0.0407155101169443189339, 0.0384398102494555320386, 0.0360644327807825726401, 0.0336038771482077305417, 0.0310735511116879648799, 0.0284897547458335486125, 0.0258696793272147469108, 0.0232314466399102694433, 0.0205942339159127111492, 0.0179785515681282703329, 0.0154067504665594978021, 0.0129038001003512656260, 0.0104982469096213218983, 0.00822300795723592966926, 0.00611550682211724633968, 0.00421763044155885483908, 0.00257904979468568827243, 0.00126515655623006801137, 0.000363221481845530659694 }; switch (n) { case 1: typeMethods.r8vec_copy(n, x01, ref result.x); typeMethods.r8vec_copy(n, w01, ref result.w); break; case 3: typeMethods.r8vec_copy(n, x03, ref result.x); typeMethods.r8vec_copy(n, w03, ref result.w); break; case 7: typeMethods.r8vec_copy(n, x07, ref result.x); typeMethods.r8vec_copy(n, w07, ref result.w); break; case 15: typeMethods.r8vec_copy(n, x15, ref result.x); typeMethods.r8vec_copy(n, w15, ref result.w); break; case 31: typeMethods.r8vec_copy(n, x31, ref result.x); typeMethods.r8vec_copy(n, w31, ref result.w); break; case 63: typeMethods.r8vec_copy(n, x63, ref result.x); typeMethods.r8vec_copy(n, w63, ref result.w); break; default: Console.WriteLine(""); Console.WriteLine("KPU - Fatal error!"); Console.WriteLine(" Illegal value of N."); return(result); } // // The rule as stored is for the interval [-1,+1]. // Adjust it to the interval [0,1]. // QuadratureRule.rule_adjust(-1.0, +1.0, 0.0, 1.0, n, ref result.x, ref result.w); return(result); }
public static double tetra_tproduct(int setting, Func <int, double, double, double, double> func, int order, double[] x, double[] y, double[] z) //****************************************************************************80 // // Purpose: // // TETRA_TPRODUCT approximates an integral in a tetrahedron in 3D. // // Discussion: // // Integration is carried out over the points inside an arbitrary // tetrahedron whose four vertices are given. // // An ORDER**3 point (2*ORDER-1)-th degree triangular product // Gauss-Legendre rule is used. // // With ORDER = 8, this routine is equivalent to the routine TETR15 // in the reference, page 367. // // Thanks to Joerg Behrens, [email protected], for numerous suggestions // and corrections. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 20 March 2008 // // Author: // // John Burkardt // // Reference: // // Arthur Stroud, // Approximate Calculation of Multiple Integrals, // Prentice Hall, 1971, // ISBN: 0130438936, // LC: QA311.S85. // // Parameters: // // Input, Func< double, double, double, double > func, the name of the // user supplied function to be integrated. // // Input, int ORDER, the order of the basic quadrature rules. // ORDER should be between 1 and 9. // // Input, double X[4], Y[4], Z[4], the vertices // of the tetrahedron. // // Output, double TETRA_TPRODUCT, the approximate integral of the function. // { int i; int k; switch (order) { case < 1: case > 9: Console.WriteLine(""); Console.WriteLine("TETRA_TPRODUCT - Fatal error!"); Console.WriteLine(" The quadrature rule orders must be between 1 and 9."); Console.WriteLine(" The input value was ORDER = " + order + ""); return(1); } // // Get the Gauss-Legendre ORDER point rules on [-1,1] for integrating // F(X), // X * F(X), // X * X * F(X). // double[] xtab0 = new double[order]; double[] xtab1 = new double[order]; double[] xtab2 = new double[order]; double[] weight0 = new double[order]; double[] weight1 = new double[order]; double[] weight2 = new double[order]; LegendreQuadrature.legendre_set(order, ref xtab0, ref weight0); LegendreQuadrature.legendre_set_x1(order, ref xtab1, ref weight1); LegendreQuadrature.legendre_set_x2(order, ref xtab2, ref weight2); // // Adjust the rules from [-1,1] to [0,1]. // const double a = -1.0; const double b = +1.0; const double c = 0.0; const double d = 1.0; QuadratureRule.rule_adjust(a, b, c, d, order, ref xtab0, ref weight0); QuadratureRule.rule_adjust(a, b, c, d, order, ref xtab1, ref weight1); QuadratureRule.rule_adjust(a, b, c, d, order, ref xtab2, ref weight2); // // For rules with a weight function that is not 1, the weight vectors // require further adjustment. // for (i = 0; i < order; i++) { weight1[i] /= 2.0; } for (i = 0; i < order; i++) { weight2[i] /= 4.0; } // // Carry out the quadrature. // double quad = 0.0; for (k = 0; k < order; k++) { int j; for (j = 0; j < order; j++) { for (i = 0; i < order; i++) { double xval = x[0] + (((x[3] - x[2]) * xtab0[i] + (x[2] - x[1])) * xtab1[j] + (x[1] - x[0])) * xtab2[k]; double yval = y[0] + (((y[3] - y[2]) * xtab0[i] + (y[2] - y[1])) * xtab1[j] + (y[1] - y[0])) * xtab2[k]; double zval = z[0] + (((z[3] - z[2]) * xtab0[i] + (z[2] - z[1])) * xtab1[j] + (z[1] - z[0])) * xtab2[k]; quad += 6.0 * weight0[i] * weight1[j] * weight2[k] * func(setting, xval, yval, zval); } } } // // Compute the volume of the tetrahedron. // double volume = tetra_volume(x, y, z); double result = quad * volume; return(result); }
public static ccResult cc(int n, double[] x_, double[] w_) //****************************************************************************80 // // Purpose: // // CC computes a Clenshaw Curtis quadrature rule based on order. // // Discussion: // // Our convention is that the abscissas are numbered from left to right. // // The rule is defined on [0,1]. // // The integral to approximate: // // Integral ( 0 <= X <= 1 ) F(X) dX // // The quadrature rule: // // Sum ( 1 <= I <= N ) W(I) * F ( X(I) ) // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 08 December 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int N, the order of the rule. // 1 <= N. // // Output, double X[N], the abscissas. // // Output, double W[N], the weights. // { ccResult result = new() { w = w_, x = x_ }; switch (n) { case < 1: Console.WriteLine(""); Console.WriteLine("CC - Fatal error!"); Console.WriteLine(" Illegal value of N = " + n + ""); return(result); case 1: result.x[0] = 0.0; result.w[0] = 2.0; break; default: { int i; for (i = 0; i < n; i++) { result.x[i] = Math.Cos((n - 1 - i) * Math.PI / (n - 1)); } result.x[0] = -1.0; result.x[(n + 1) / 2 - 1] = (n % 2) switch { 1 => 0.0, _ => result.x[(n + 1) / 2 - 1] }; result.x[n - 1] = +1.0; int j; for (i = 0; i < n; i++) { double theta = i * Math.PI / (n - 1); result.w[i] = 1.0; for (j = 1; j <= (n - 1) / 2; j++) { double b = 2 * j == n - 1 ? 1.0 : 2.0; result.w[i] -= b * Math.Cos(2.0 * j * theta) / (4 * j * j - 1); } } result.w[0] /= n - 1; for (j = 1; j < n - 1; j++) { result.w[j] = 2.0 * result.w[j] / (n - 1); } result.w[n - 1] /= n - 1; break; } } // // Transform from [-1,+1] to [0,1]. // QuadratureRule.rule_adjust(-1.0, +1.0, 0.0, 1.0, n, ref result.x, ref result.w); return(result); }