Пример #1
0
    private static void hermite_polynomial_test07()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    HERMITE_POLYNOMIAL_TEST07 tests HE_QUADRATURE_RULE.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    08 March 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        int e;

        double[] f;
        int      i;
        int      n;
        double   q;
        double   q_exact;

        double[] w;
        double[] x;

        Console.WriteLine("");
        Console.WriteLine("HERMITE_POLYNOMIAL_TEST07:");
        Console.WriteLine("  HE_QUADRATURE_RULE computes the quadrature rule");
        Console.WriteLine("  associated with He(n,x)");

        n = 7;
        x = new double[n];
        w = new double[n];

        HermiteQuadrature.he_quadrature_rule(n, ref x, ref w);

        typeMethods.r8vec2_print(n, x, w, "      X            W");

        Console.WriteLine("");
        Console.WriteLine("  Use the quadrature rule to estimate:");
        Console.WriteLine("");
        Console.WriteLine("    Q = Integral ( -oo < X < +00 ) X^E exp(-X^2) dx");
        Console.WriteLine("");
        Console.WriteLine("   E       Q_Estimate      Q_Exact");
        Console.WriteLine("");

        f = new double[n];

        for (e = 0; e <= 2 * n - 1; e++)
        {
            switch (e)
            {
            case 0:
            {
                for (i = 0; i < n; i++)
                {
                    f[i] = 1.0;
                }

                break;
            }

            default:
            {
                for (i = 0; i < n; i++)
                {
                    f[i] = Math.Pow(x[i], e);
                }

                break;
            }
            }

            q       = typeMethods.r8vec_dot_product(n, w, f);
            q_exact = Integral.he_integral(e);
            Console.WriteLine("  " + e.ToString().PadLeft(2)
                              + "  " + q.ToString().PadLeft(14)
                              + "  " + q_exact.ToString().PadLeft(14) + "");
        }
    }
Пример #2
0
    public static double[] burgers_viscous_time_exact1(double nu, int vxn, double[] vx, int vtn,
                                                       double[] vt)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    BURGERS_VISCOUS_TIME_EXACT1 evaluates solution #1 to the Burgers equation.
    //
    //  Discussion:
    //
    //    The form of the Burgers equation considered here is
    //
    //      du       du        d^2 u
    //      -- + u * -- = nu * -----
    //      dt       dx        dx^2
    //
    //    for -1.0 < x < +1.0, and 0 < t.
    //
    //    Initial conditions are u(x,0) = - sin(pi*x).  Boundary conditions
    //    are u(-1,t) = u(+1,t) = 0.  The viscosity parameter nu is taken
    //    to be 0.01 / pi, although this is not essential.
    //
    //    The authors note an integral representation for the solution u(x,t),
    //    and present a better version of the formula that is amenable to
    //    approximation using Hermite quadrature.
    //
    //    This program library does little more than evaluate the exact solution
    //    at a user-specified set of points, using the quadrature rule.
    //    Internally, the order of this quadrature rule is set to 8, but the
    //    user can easily modify this value if greater accuracy is desired.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    18 November 2011
    //
    //  Author:
    //
    //    John Burkardt.
    //
    //  Reference:
    //
    //    Claude Basdevant, Michel Deville, Pierre Haldenwang, J Lacroix,
    //    J Ouazzani, Roger Peyret, Paolo Orlandi, Anthony Patera,
    //    Spectral and finite difference solutions of the Burgers equation,
    //    Computers and Fluids,
    //    Volume 14, Number 1, 1986, pages 23-41.
    //
    //  Parameters:
    //
    //    Input, double NU, the viscosity.
    //
    //    Input, int VXN, the number of spatial grid points.
    //
    //    Input, double VX[VXN], the spatial grid points.
    //
    //    Input, int VTN, the number of time grid points.
    //
    //    Input, double VT[VTN], the time grid points.
    //
    //    Output, double BURGERS_VISCOUS_TIME_EXACT1[VXN*VTN], the solution of
    //    the Burgers equation at each space and time grid point.
    //
    {
        const int qn = 8;
        int       vti;

        //
        //  Compute the rule.
        //
        double[] qx = new double[qn];
        double[] qw = new double[qn];

        HermiteQuadrature.hermite_ek_compute(qn, ref qx, ref qw);
        //
        //  Evaluate U(X,T) for later times.
        //
        double[] vu = new double[vxn * vtn];

        for (vti = 0; vti < vtn; vti++)
        {
            int vxi;
            switch (vt[vti])
            {
            case 0.0:
            {
                for (vxi = 0; vxi < vxn; vxi++)
                {
                    vu[vxi + vti * vxn] = -Math.Sin(Math.PI * vx[vxi]);
                }

                break;
            }

            default:
            {
                for (vxi = 0; vxi < vxn; vxi++)
                {
                    double top = 0.0;
                    double bot = 0.0;
                    int    qi;
                    for (qi = 0; qi < qn; qi++)
                    {
                        double c = 2.0 * Math.Sqrt(nu * vt[vti]);

                        top -= qw[qi] * c *Math.Sin(Math.PI *(vx[vxi] - c * qx[qi]))
                               * Math.Exp(-Math.Cos(Math.PI * (vx[vxi] - c * qx[qi]))
                                          / (2.0 * Math.PI * nu));

                        bot += qw[qi] * c
                               * Math.Exp(-Math.Cos(Math.PI * (vx[vxi] - c * qx[qi]))
                                          / (2.0 * Math.PI *nu));

                        vu[vxi + vti * vxn] = top / bot;
                    }
                }

                break;
            }
            }
        }

        return(vu);
    }
Пример #3
0
    public static void product_mixed_growth_weight(int dim_num, int[] order_1d, int order_nd,
                                                   int[] rule, int[] np, double[] p,
                                                   Func <int, int, double[], double[], double[]>[] gw_compute_weights,
                                                   ref double[] weight_nd)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    PRODUCT_MIXED_GROWTH_WEIGHT computes the weights of a mixed product rule.
    //
    //  Discussion:
    //
    //    This routine computes the weights for a quadrature rule which is
    //    a product of 1D rules of varying order and kind.
    //
    //    The user must preallocate space for the output array WEIGHT_ND.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    20 June 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Fabio Nobile, Raul Tempone, Clayton Webster,
    //    A Sparse Grid Stochastic Collocation Method for Partial Differential
    //    Equations with Random Input Data,
    //    SIAM Journal on Numerical Analysis,
    //    Volume 46, Number 5, 2008, pages 2309-2345.
    //
    //  Parameters:
    //
    //    Input, int DIM_NUM, the spatial dimension.
    //
    //    Input, int ORDER_1D[DIM_NUM], the order of the 1D rules.
    //
    //    Input, int ORDER_ND, the order of the product rule.
    //
    //    Input, int RULE[DIM_NUM], the rule in each dimension.
    //     1, "CC",  Clenshaw Curtis, Closed Fully Nested.
    //     2, "F2",  Fejer Type 2, Open Fully Nested.
    //     3, "GP",  Gauss Patterson, Open Fully Nested.
    //     4, "GL",  Gauss Legendre, Open Weakly Nested.
    //     5, "GH",  Gauss Hermite, Open Weakly Nested.
    //     6, "GGH", Generalized Gauss Hermite, Open Weakly Nested.
    //     7, "LG",  Gauss Laguerre, Open Non Nested.
    //     8, "GLG", Generalized Gauss Laguerre, Open Non Nested.
    //     9, "GJ",  Gauss Jacobi, Open Non Nested.
    //    10, "HGK", Hermite Genz-Keister, Open Fully Nested.
    //    11, "UO",  User supplied Open, presumably Non Nested.
    //    12, "UC",  User supplied Closed, presumably Non Nested.
    //
    //    Input, int NP[DIM_NUM], the number of parameters used by each rule.
    //
    //    Input, double P[sum(NP[*])], the parameters needed by each rule.
    //
    //    Input, void ( *GW_COMPUTE_WEIGHTS[] ) ( int order, int np, double p[], double w[] ),
    //    an array of pointers to functions which return the 1D quadrature weights
    //    associated with each spatial dimension for which a Golub Welsch rule
    //    is used.
    //
    //    Output, double WEIGHT_ND[ORDER_ND], the product rule weights.
    //
    {
        int dim;
        int i;

        typeMethods.r8vecDPData data = new();

        for (i = 0; i < order_nd; i++)
        {
            weight_nd[i] = 1.0;
        }

        int p_index = 0;

        for (dim = 0; dim < dim_num; dim++)
        {
            double[] weight_1d = new double[order_1d[dim]];

            switch (rule[dim])
            {
            case 1:
                ClenshawCurtis.clenshaw_curtis_compute_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 2:
                Fejer2.fejer2_compute_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 3:
                PattersonQuadrature.patterson_lookup_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 4:
                Legendre.QuadratureRule.legendre_compute_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 5:
                HermiteQuadrature.hermite_compute_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 6:
                HermiteQuadrature.gen_hermite_compute_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 7:
                Laguerre.QuadratureRule.laguerre_compute_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 8:
                Laguerre.QuadratureRule.gen_laguerre_compute_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 9:
                JacobiQuadrature.jacobi_compute_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 10:
                HermiteQuadrature.hermite_genz_keister_lookup_weights_np(
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            case 11:
            case 12:
                gw_compute_weights[dim](
                    order_1d[dim], np[dim], p.Skip(+p_index).ToArray(), weight_1d);
                break;

            default:
                Console.WriteLine("");
                Console.WriteLine("PRODUCT_MIXED_GROWTH_WEIGHT - Fatal error!");
                Console.WriteLine("  Unexpected value of RULE[" + dim + "] = "
                                  + rule[dim] + ".");
                return;
            }

            p_index += np[dim];

            typeMethods.r8vec_direct_product2(ref data, dim, order_1d[dim], weight_1d,
                                              dim_num, order_nd, ref weight_nd);
        }
    }
Пример #4
0
    public static void sparse_grid_hermite_index(int dim_num, int level_max, int point_num,
                                                 ref int[] grid_index, ref int[] grid_base)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    SPARSE_GRID_HERMITE_INDEX indexes points in a Gauss-Hermite sparse grid.
    //
    //  Discussion:
    //
    //    The sparse grid is assumed to be formed from 1D Gauss-Hermite rules
    //    of ODD order, which have the property that only the central abscissa,
    //    X = 0.0, is "nested".
    //
    //    The necessary dimensions of GRID_INDEX can be determined by
    //    calling SPARSE_GRID_HERMITE_SIZE first.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    05 July 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Fabio Nobile, Raul Tempone, Clayton Webster,
    //    A Sparse Grid Stochastic Collocation Method for Partial Differential
    //    Equations with Random Input Data,
    //    SIAM Journal on Numerical Analysis,
    //    Volume 46, Number 5, 2008, pages 2309-2345.
    //
    //  Parameters:
    //
    //    Input, int DIM_NUM, the spatial dimension.
    //
    //    Input, int LEVEL_MAX, the maximum value of LEVEL.
    //
    //    Input, int POINT_NUM, the total number of points in the grids.
    //
    //    Output, int GRID_INDEX[DIM_NUM*POINT_NUM], a list of
    //    point indices, representing a subset of the product grid of level
    //    LEVEL_MAX, representing (exactly once) each point that will show up in a
    //    sparse grid of level LEVEL_MAX.
    //
    //    Output, int GRID_BASE[DIM_NUM*POINT_NUM], a list of
    //    the orders of the Gauss-Hermite rules associated with each point
    //    and dimension.
    //
    {
        int level;
        //
        //  The outer loop generates LEVELs from LEVEL_MIN to LEVEL_MAX.
        //
        int point_num2 = 0;

        int level_min = Math.Max(0, level_max + 1 - dim_num);

        int[] grid_base2 = new int[dim_num];
        int[] level_1d   = new int[dim_num];
        int[] order_1d   = new int[dim_num];

        for (level = level_min; level <= level_max; level++)
        {
            //
            //  The middle loop generates the next partition LEVEL_1D(1:DIM_NUM)
            //  that adds up to LEVEL.
            //
            bool more = false;
            int  h    = 0;
            int  t    = 0;

            for (;;)
            {
                Comp.comp_next(level, dim_num, ref level_1d, ref more, ref h, ref t);
                //
                //  Transform each 1D level to a corresponding 1D order.
                //
                ClenshawCurtis.level_to_order_open(dim_num, level_1d, ref order_1d);
                int dim;
                for (dim = 0; dim < dim_num; dim++)
                {
                    grid_base2[dim] = (order_1d[dim] - 1) / 2;
                }

                //
                //  The product of the 1D orders gives us the number of points in this grid.
                //
                int order_nd = typeMethods.i4vec_product(dim_num, order_1d);
                //
                //  The inner (hidden) loop generates all points corresponding to given grid.
                //
                int[] grid_index2 = Multigrid.multigrid_index_z(dim_num, order_1d, order_nd);
                //
                //  Determine the first level of appearance of each of the points.
                //  This allows us to flag certain points as being repeats of points
                //  generated on a grid of lower level.
                //
                //  This is SLIGHTLY tricky.
                //
                int[] grid_level = HermiteQuadrature.index_level_hermite(level, level_max, dim_num, order_nd,
                                                                         grid_index2, grid_base2);
                //
                //  Only keep those points which first appear on this level.
                //
                int point;
                for (point = 0; point < order_nd; point++)
                {
                    if (grid_level[point] != level)
                    {
                        continue;
                    }

                    for (dim = 0; dim < dim_num; dim++)
                    {
                        grid_index[dim + point_num2 * dim_num] =
                            grid_index2[dim + point * dim_num];
                        grid_base[dim + point_num2 * dim_num] = grid_base2[dim];
                    }

                    point_num2 += 1;
                }

                if (!more)
                {
                    break;
                }
            }
        }
    }
Пример #5
0
    public static void sparse_grid_hermite(int dim_num, int level_max, int point_num,
                                           ref double[] grid_weight, ref double[] grid_point)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    SPARSE_GRID_HERMITE computes a sparse grid of Gauss-Hermite points.
    //
    //  Discussion:
    //
    //    The quadrature rule is associated with a sparse grid derived from
    //    a Smolyak construction using a 1D Gauss-Hermite quadrature rule.
    //
    //    The user specifies:
    //    * the spatial dimension of the quadrature region,
    //    * the level that defines the Smolyak grid.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    05 July 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Fabio Nobile, Raul Tempone, Clayton Webster,
    //    A Sparse Grid Stochastic Collocation Method for Partial Differential
    //    Equations with Random Input Data,
    //    SIAM Journal on Numerical Analysis,
    //    Volume 46, Number 5, 2008, pages 2309-2345.
    //
    //  Parameters:
    //
    //    Input, int DIM_NUM, the spatial dimension.
    //
    //    Input, int LEVEL_MAX, controls the size of the final sparse grid.
    //
    //    Input, int POINT_NUM, the number of points in the grid, as determined
    //    by SPARSE_GRID_HERM_SIZE.
    //
    //    Output, double GRID_WEIGHT[POINT_NUM], the weights.
    //
    //    Output, double GRID_POINT[DIM_NUM*POINT_NUM], the points.
    //
    {
        int level;
        int point;
        int point3 = 0;

        for (point = 0; point < point_num; point++)
        {
            grid_weight[point] = 0.0;
        }

        //
        //  The outer loop generates LEVELs from LEVEL_MIN to LEVEL_MAX.
        //
        int point_num2 = 0;

        int level_min = Math.Max(0, level_max + 1 - dim_num);

        int[] grid_base2 = new int[dim_num];
        int[] level_1d   = new int[dim_num];
        int[] order_1d   = new int[dim_num];

        for (level = level_min; level <= level_max; level++)
        {
            //
            //  The middle loop generates the next partition LEVEL_1D(1:DIM_NUM)
            //  that adds up to LEVEL.
            //
            bool more = false;
            int  h    = 0;
            int  t    = 0;

            for (;;)
            {
                Comp.comp_next(level, dim_num, ref level_1d, ref more, ref h, ref t);
                //
                //  Transform each 1D level to a corresponding 1D order.
                //  The relationship is the same as for other OPEN rules.
                //  The GL rule differs from the other OPEN rules only in the nesting behavior.
                //
                ClenshawCurtis.level_to_order_open(dim_num, level_1d, ref order_1d);

                int dim;
                for (dim = 0; dim < dim_num; dim++)
                {
                    grid_base2[dim] = (order_1d[dim] - 1) / 2;
                }

                //
                //  The product of the 1D orders gives us the number of points in this grid.
                //
                int order_nd = typeMethods.i4vec_product(dim_num, order_1d);
                //
                //  Compute the weights for this product grid.
                //
                double[] grid_weight2 = HermiteQuadrature.product_weight_hermite(dim_num, order_1d, order_nd);
                //
                //  Now determine the coefficient of the weight.
                //
                int coeff = (int)(Math.Pow(-1, level_max - level)
                                  * Binomial.choose(dim_num - 1, level_max - level));
                //
                //  The inner (hidden) loop generates all points corresponding to given grid.
                //  The grid indices will be between -M to +M, where 2*M + 1 = ORDER_1D(DIM).
                //
                int[] grid_index2 = Multigrid.multigrid_index_z(dim_num, order_1d, order_nd);
                //
                //  Determine the first level of appearance of each of the points.
                //  This allows us to flag certain points as being repeats of points
                //  generated on a grid of lower level.
                //
                //  This is SLIGHTLY tricky.
                //
                int[] grid_level = HermiteQuadrature.index_level_hermite(level, level_max, dim_num, order_nd,
                                                                         grid_index2, grid_base2);
                //
                //  Only keep those points which first appear on this level.
                //
                for (point = 0; point < order_nd; point++)
                {
                    //
                    //  Either a "new" point (increase count, create point, create weight)
                    //
                    if (grid_level[point] == level)
                    {
                        HermiteQuadrature.hermite_abscissa(dim_num, 1, grid_index2,
                                                           grid_base2, ref grid_point, gridIndex: +point * dim_num,
                                                           gridPointIndex: +point_num2 * dim_num);

                        grid_weight[point_num2] = coeff * grid_weight2[point];

                        point_num2 += 1;
                    }
                    //
                    //  or an already existing point (create point temporarily, find match,
                    //  add weight to matched point's weight).
                    //
                    else
                    {
                        double[] grid_point_temp = new double[dim_num];

                        HermiteQuadrature.hermite_abscissa(dim_num, 1, grid_index2,
                                                           grid_base2, ref grid_point_temp, gridIndex: +point * dim_num);

                        int point2;
                        for (point2 = 0; point2 < point_num2; point2++)
                        {
                            point3 = point2;
                            for (dim = 0; dim < dim_num; dim++)
                            {
                                if (!(Math.Abs(grid_point[dim + point2 * dim_num] - grid_point_temp[dim]) >
                                      double.Epsilon))
                                {
                                    continue;
                                }

                                point3 = -1;
                                break;
                            }

                            if (point3 == point2)
                            {
                                break;
                            }
                        }

                        switch (point3)
                        {
                        case -1:
                            Console.WriteLine("");
                            Console.WriteLine("SPARSE_GRID_HERM - Fatal error!");
                            Console.WriteLine("  Could not match point.");
                            return;

                        default:
                            grid_weight[point3] += coeff * grid_weight2[point];
                            break;
                        }
                    }
                }

                if (!more)
                {
                    break;
                }
            }
        }
    }
Пример #6
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for INT_GEN_EXACTNESS_HERMITE.
    //
    //  Discussion:
    //
    //    This program investigates a generalized Gauss-Hermite quadrature rule
    //    by using it to integrate monomials over (-oo,+oo), and comparing the
    //    approximate result to the known exact value.
    //
    //    The user specifies:
    //    * the "root" name of the R, W and X files that specify the rule;
    //    * DEGREE_MAX, the maximum monomial degree to be checked.
    //    * ALPHA, the power of X used in the weight.
    //    * OPTION, whether the rule is for |x|^alpha*exp(-x*x)*f(x) or f(x).
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    05 August 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double alpha;
        int    degree;
        int    degree_max;
        int    i;
        int    option;
        string quad_filename;

        Console.WriteLine("");
        Console.WriteLine("INT_EXACTNESS_GEN_HERMITE");
        Console.WriteLine("");
        Console.WriteLine("  Investigate the polynomial exactness of a generalized Gauss-Hermite");
        Console.WriteLine("  quadrature rule by integrating exponentially weighted");
        Console.WriteLine("  monomials up to a given degree over the (-oo,+oo) interval.");
        //
        //  Get the quadrature file rootname.
        //
        try
        {
            quad_filename = args[0];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the quadrature file rootname:");
            quad_filename = Console.ReadLine();
        }

        Console.WriteLine("");
        Console.WriteLine("  The quadrature file rootname is \"" + quad_filename + "\".");
        //
        //  Create the names of:
        //    the quadrature X file;
        //    the quadrature W file;
        //    the quadrature R file;
        //
        string quad_w_filename = quad_filename + "_w.txt";
        string quad_x_filename = quad_filename + "_x.txt";
        string quad_r_filename = quad_filename + "_r.txt";

        //
        //  Get the maximum degree:
        //
        try
        {
            degree_max = Convert.ToInt32(args[1]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter DEGREE_MAX, the maximum monomial degree to check.");
            degree_max = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The requested maximum monomial degree is = " + degree_max + "");
        //
        //  Get the power of X:
        //
        try
        {
            alpha = Convert.ToDouble(args[2]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  ALPHA is the power of |X| in the weighting function");
            Console.WriteLine("");
            Console.WriteLine("  ALPHA is a real number greater than -1.0.");
            Console.WriteLine("");
            Console.WriteLine("  Please enter ALPHA.");
            alpha = Convert.ToDouble(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The requested power of |X| is = " + alpha + "");
        //
        //  The fourth command line argument is OPTION.
        //  0 for the standard rule for integrating |x|^alpha*exp(-x*x)*f(x),
        //  1 for a rule for integrating f(x).
        //
        try
        {
            option = Convert.ToInt32(args[3]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("OPTION chooses the standard or modified rule.");
            Console.WriteLine("0: standard rule for integrating |x|^alpha*exp(-x*x)*f(x)");
            Console.WriteLine("1: modified rule for integrating                     f(x)");
            option = Convert.ToInt32(Console.ReadLine());
        }

        //
        //  Summarize the input.
        //
        Console.WriteLine("");
        Console.WriteLine("INT_EXACTNESS_GEN_HERMITE: User input:");
        Console.WriteLine("  Quadrature rule X file = \"" + quad_x_filename + "\".");
        Console.WriteLine("  Quadrature rule W file = \"" + quad_w_filename + "\".");
        Console.WriteLine("  Quadrature rule R file = \"" + quad_r_filename + "\".");
        Console.WriteLine("  Maximum degree to check = " + degree_max + "");
        Console.WriteLine("  Power of |X|, ALPHA = " + alpha + "");
        switch (option)
        {
        case 0:
            Console.WriteLine("  OPTION = 0, integrate |x|^alpha*exp(-x*x)*f(x)");
            break;

        default:
            Console.WriteLine("  OPTION = 1, integrate                     f(x)");
            break;
        }

        //
        //  Read the X file.
        //
        TableHeader h       = typeMethods.r8mat_header_read(quad_x_filename);
        int         dim_num = h.m;
        int         order   = h.n;

        if (dim_num != 1)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_HERMITE - Fatal error!");
            Console.WriteLine("  The spatial dimension of X should be 1.");
            Console.WriteLine(" The implicit input dimension was DIM_NUM = " + dim_num + "");
            return;
        }

        Console.WriteLine("");
        Console.WriteLine("  Spatial dimension = " + dim_num + "");
        Console.WriteLine("  Number of points  = " + order + "");

        double[] x = typeMethods.r8mat_data_read(quad_x_filename, dim_num, order);
        //
        //  Read the W file.
        //
        h = typeMethods.r8mat_header_read(quad_w_filename);
        int dim_num2  = h.m;
        int point_num = h.n;

        if (dim_num2 != 1)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_HERMITE - Fatal error!");
            Console.WriteLine("  The quadrature weight file should have exactly");
            Console.WriteLine("  one value on each line.");
            return;
        }

        if (point_num != order)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_HERMITE - Fatal error!");
            Console.WriteLine("  The quadrature weight file should have exactly");
            Console.WriteLine("  the same number of lines as the abscissa file.");
            return;
        }

        double[] w = typeMethods.r8mat_data_read(quad_w_filename, dim_num, order);
        //
        //  Read the R file.
        //
        h        = typeMethods.r8mat_header_read(quad_r_filename);
        dim_num2 = h.m;
        int point_num2 = h.n;

        if (dim_num2 != dim_num)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_HERMITE - Fatal error!");
            Console.WriteLine("  The quadrature region file should have the");
            Console.WriteLine("  same number of values on each line as the");
            Console.WriteLine("  abscissa file does.");
            return;
        }

        if (point_num2 != 2)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_HERMITE - Fatal error!");
            Console.WriteLine("  The quadrature region file should have two lines.");
            return;
        }

        double[] r = typeMethods.r8mat_data_read(quad_r_filename, dim_num, point_num2);
        //
        //  Print the input quadrature rule.
        //
        Console.WriteLine("");
        Console.WriteLine("  The quadrature rule to be tested is");
        Console.WriteLine("  a generalized Gauss-Hermite rule");
        Console.WriteLine("  ORDER = " + order + "");
        Console.WriteLine("  ALPHA = " + alpha + "");
        Console.WriteLine("");
        switch (option)
        {
        case 0:
            Console.WriteLine("  OPTION = 0: Standard rule:");
            Console.WriteLine("    Integral ( -oo < x < +oo ) |x|^alpha exp(-x*x) f(x) dx");
            Console.WriteLine("    is to be approximated by");
            Console.WriteLine("    sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).");
            break;

        default:
            Console.WriteLine("  OPTION = 1: Modified rule:");
            Console.WriteLine("    Integral ( -oo < x < +oo ) f(x) dx");
            Console.WriteLine("    is to be approximated by");
            Console.WriteLine("    sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).");
            break;
        }

        Console.WriteLine("");
        Console.WriteLine("  Weights W:");
        Console.WriteLine("");
        for (i = 0; i < order; i++)
        {
            Console.WriteLine("  w[" + i.ToString().PadLeft(2)
                              + "] = " + w[i].ToString("0.################").PadLeft(24) + "");
        }

        Console.WriteLine("");
        Console.WriteLine("  Abscissas X:");
        Console.WriteLine("");
        for (i = 0; i < order; i++)
        {
            Console.WriteLine("  x[" + i.ToString().PadLeft(2)
                              + "] = " + x[i].ToString("0.################").PadLeft(24) + "");
        }

        Console.WriteLine("");
        Console.WriteLine("  Region R:");
        Console.WriteLine("");

        for (i = 0; i < 2; i++)
        {
            Console.WriteLine("  r[" + i.ToString().PadLeft(2)
                              + "] = " + r[i].ToString("0.################").PadLeft(24) + "");
        }

        //
        //  Explore the monomials.
        //
        Console.WriteLine("");
        Console.WriteLine("  A generalized Gauss-Hermite rule would be able to exactly");
        Console.WriteLine("  integrate monomials up to and including degree = " +
                          (2 * order - 1) + "");
        Console.WriteLine("");
        Console.WriteLine("          Error          Degree");
        Console.WriteLine("");

        for (degree = 0; degree <= degree_max; degree++)
        {
            double quad_error = HermiteQuadrature.monomial_quadrature_gen_hermite(degree, alpha, order,
                                                                                  option, w, x);

            Console.WriteLine("  " + quad_error.ToString("0.################").PadLeft(24)
                              + "  " + degree.ToString().PadLeft(2) + "");
        }

        Console.WriteLine("");
        Console.WriteLine("INT_EXACTNESS_GEN_HERMITE:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
Пример #7
0
    private static void test05(int dim_num, int level_max, int degree_max)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST05 tests a Gauss-Hermite sparse grid rule for monomial exactness.
    //
    //  Discussion:
    //
    //    This test is going to check EVERY monomial of total degree DEGREE_MAX
    //    or less.  Even for a moderately high dimension of DIM_NUM = 10, you
    //    do NOT want to use a large value of DEGREE_MAX, since there are
    //
    //      1         monomials of total degree 0,
    //      DIM_NUM   monomials of total degree 1,
    //      DIM_NUM^2 monomials of total degree 2,
    //      DIM_NUM^3 monomials of total degree 3, and so on.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    05 July 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int DIM_NUM, the spatial dimension.
    //
    //    Input, int LEVEL_MAX, the level.
    //
    //    Input, int DEGREE_MAX, the maximum monomial total degree to check.
    //
    {
        int degree;

        Console.WriteLine("");
        Console.WriteLine("TEST05");
        Console.WriteLine("  Check the exactness of a Gauss-Hermite sparse");
        Console.WriteLine("  grid quadrature rule, applied to all monomials ");
        Console.WriteLine("  of orders 0 to DEGREE_MAX.");

        int level_min = Math.Max(0, level_max + 1 - dim_num);

        Console.WriteLine("");
        Console.WriteLine("  LEVEL_MIN = " + level_min + "");
        Console.WriteLine("  LEVEL_MAX = " + level_max + "");
        Console.WriteLine("  Spatial dimension DIM_NUM = " + dim_num + "");
        Console.WriteLine("");
        Console.WriteLine("  The maximum total degree to be checked is DEGREE_MAX = " + degree_max + "");
        //
        //  Determine the number of points in the rule.
        //
        int point_num = Grid_Hermite.sparse_grid_hermite_size(dim_num, level_max);

        Console.WriteLine("");
        Console.WriteLine("  Number of unique points in the grid = " + point_num + "");
        //
        //  Allocate space for the weights and points.
        //
        double[] grid_weight = new double[point_num];
        double[] grid_point  = new double[dim_num * point_num];
        //
        //  Compute the weights and points.
        //
        Grid_Hermite.sparse_grid_hermite(dim_num, level_max, point_num, ref grid_weight, ref grid_point);
        //
        //  Explore the monomials.
        //
        int[] expon = new int[dim_num];

        Console.WriteLine("");
        Console.WriteLine("      Error      Total   Monomial");
        Console.WriteLine("                 Degree  Exponents");

        for (degree = 0; degree <= degree_max; degree++)
        {
            bool more = false;
            int  h    = 0;
            int  t    = 0;

            Console.WriteLine("");
            for (;;)
            {
                Comp.comp_next(degree, dim_num, ref expon, ref more, ref h, ref t);

                double quad_error = HermiteQuadrature.monomial_quadrature_hermite(dim_num, expon, point_num,
                                                                                  grid_weight, grid_point);

                string cout = "  " + quad_error.ToString("0.#").PadLeft(12)
                              + "     " + degree.ToString(CultureInfo.InvariantCulture).PadLeft(2)
                              + "      ";

                int dim;
                for (dim = 0; dim < dim_num; dim++)
                {
                    cout += expon[dim].ToString(CultureInfo.InvariantCulture).PadLeft(3);
                }

                Console.WriteLine(cout);

                if (!more)
                {
                    break;
                }
            }
        }
    }