예제 #1
0
    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);
    }
예제 #2
0
    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);
    }
예제 #3
0
    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);
    }
예제 #4
0
    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);
    }