private static void sgmg_size_test(int dim_num, int level_max_min,
                                       int level_max_max, int[] rule, int[] growth, int[] np, double[] p,
                                       Func <int, int, double[], double[], double[]>[] gw_compute_points,
                                       double tol)

    //***************************************************************************80
    //
    //  Purpose:
    //
    //    SGMG_SIZE_TEST tests SGMG_SIZE, SGMG_SIZE_TOTAL.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    20 June 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int DIM_NUM, the spatial dimension.
    //
    //    Input, int LEVEL_MAX_MIN, LEVEL_MAX_MAX, the minimum and
    //    maximum values of LEVEL_MAX.
    //
    //    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 GROWTH[DIM_NUM], the growth rule in each dimension.
    //    0, "DF", default growth associated with this quadrature rule;
    //    1, "SL", slow linear, L+1;
    //    2  "SO", slow linear odd, O=1+2((L+1)/2)
    //    3, "ML", moderate linear, 2L+1;
    //    4, "SE", slow exponential;
    //    5, "ME", moderate exponential;
    //    6, "FE", full exponential.
    //
    //    Input, int NP[RULE_NUM], the number of parameters used by each rule.
    //
    //    Input, double P[sum(NP[*])], the parameters needed by each rule.
    //
    //    Input, void ( *GW_COMPUTE_POINTS[] ) ( int order, int np, double p[], double w[] ),
    //    an array of pointers to functions which return the 1D quadrature points
    //    associated with each spatial dimension for which a Golub Welsch rule
    //    is used.
    //
    //    Input, double TOL, a tolerance for point equality.
    //
    {
        int dim;
        int level_max;

        Console.WriteLine("");
        Console.WriteLine("SGMG_SIZE_TEST");
        Console.WriteLine("  SGMG_SIZE returns the number of distinct");
        Console.WriteLine("  points in a multidimensional sparse grid with mixed factors.");
        Console.WriteLine("");
        Console.WriteLine("  SGMG_SIZE_TOTAL returns the TOTAL number of");
        Console.WriteLine("  points in a multidimensional sparse grid with mixed factors,");
        Console.WriteLine("  without checking for duplication.");
        Console.WriteLine("");
        Console.WriteLine("  Each sparse grid is of spatial dimension DIM_NUM,");
        Console.WriteLine("  and is made up of product grids of levels up to LEVEL_MAX.");
        Console.WriteLine("");
        Console.WriteLine(" Dimension      Rule  Growth rate       Parameters");
        Console.WriteLine("");

        int p_index = 0;

        for (dim = 0; dim < dim_num; dim++)
        {
            int    i;
            double alpha;
            switch (rule[dim])
            {
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8) + "");
                break;

            case 6:
                alpha    = p[p_index];
                p_index += 1;
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8)
                                  + "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
                break;

            case 7:
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8) + "");
                break;

            case 8:
                alpha    = p[p_index];
                p_index += 1;
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8)
                                  + "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
                break;

            case 9:
                alpha    = p[p_index];
                p_index += 1;
                double beta = p[p_index];
                p_index += 1;
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8)
                                  + "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14)
                                  + "  " + beta.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
                break;

            case 10:
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8) + "");
                break;

            case 11:
            {
                string cout = "  " + dim.ToString().PadLeft(8)
                              + "  " + rule[dim].ToString().PadLeft(8)
                              + "  " + growth[dim].ToString().PadLeft(8);
                for (i = 0; i < np[dim]; i++)
                {
                    alpha    = p[p_index];
                    p_index += 1;
                    cout    += "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14);
                }

                Console.WriteLine(cout);
                break;
            }

            case 12:
            {
                string cout = "  " + dim.ToString().PadLeft(8)
                              + "  " + rule[dim].ToString().PadLeft(8)
                              + "  " + growth[dim].ToString().PadLeft(8);
                for (i = 0; i < np[dim]; i++)
                {
                    alpha    = p[p_index];
                    p_index += 1;
                    cout    += "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14);
                }

                Console.WriteLine(cout);
                break;
            }

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

        Console.WriteLine("");
        Console.WriteLine(" LEVEL_MIN LEVEL_MAX POINT_NUM POINT_NUM");
        Console.WriteLine("                        Unique     Total");
        Console.WriteLine("");

        for (level_max = level_max_min; level_max <= level_max_max; level_max++)
        {
            int point_total_num = SGMG.sgmg_size_total(dim_num,
                                                       level_max, rule, growth);

            int point_num = SGMG.sgmg_size(dim_num, level_max,
                                           rule, np, p, gw_compute_points, tol, growth);

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

            Console.WriteLine("  " + level_min.ToString().PadLeft(8)
                              + "  " + level_max.ToString().PadLeft(8)
                              + "  " + point_num.ToString().PadLeft(8)
                              + "  " + point_total_num.ToString().PadLeft(8) + "");
        }
    }
Exemple #2
0
    private static void sgmg_create_rule(int dim_num, int level_max,
                                         int[] rule, int[] growth, int[] np, double[] p,
                                         Func <int, int, double[], double[], double[]>[] gw_compute_points,
                                         Func <int, int, double[], double[], double[]>[] gw_compute_weights,
                                         double tol, string file_name)

    //***************************************************************************80
    //
    //  Purpose:
    //
    //    SGMG_CREATE_RULE creates the requested rule and writes it to a file.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    02 July 2013
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, integer DIM_NUM, the spatial dimension.
    //
    //    Input, integer LEVEL_MAX, the level that defines the grid.
    //
    //    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 GROWTH[DIM_NUM], the growth rule in each dimension.
    //    0, "DF", default growth associated with this quadrature rule;
    //    1, "SL", slow linear, L+1;
    //    2  "SO", slow linear odd, O=1+2((L+1)/2)
    //    3, "ML", moderate linear, 2L+1;
    //    4, "SE", slow exponential;
    //    5, "ME", moderate exponential;
    //    6, "FE", full exponential.
    //
    //    Input, int NP[RULE_NUM], the number of parameters used by each rule.
    //
    //    Input, double P[sum(NP[*])], the parameters needed by each rule.
    //
    //    Input, void ( *GW_COMPUTE_POINTS[] ) ( int order, int np, double p[], double x[] ),
    //    an array of pointers to functions which return the 1D quadrature points
    //    associated with each spatial dimension for which a Golub Welsch rule
    //    is used.
    //
    //    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.
    //
    //    Input, double TOL, a tolerance for point equality.
    //
    //    Input, string FILE_NAME, the main name of the output files.
    //
    {
        Console.WriteLine("");
        Console.WriteLine("SGMG_CREATE_RULE");
        Console.WriteLine("  Create the requested sparse grid rule, and write it");
        Console.WriteLine("  to X, W and R files.");
        //
        //  Compute necessary data.
        //
        int point_total_num = SGMG.sgmg_size_total(dim_num,
                                                   level_max, rule, growth);

        int point_num = SGMG.sgmg_size(dim_num, level_max,
                                       rule, np, p, gw_compute_points, tol, growth);

        int[] sparse_unique_index = new int[point_total_num];

        SGMG.sgmg_unique_index(dim_num, level_max, rule,
                               np, p, gw_compute_points, tol, point_num, point_total_num,
                               growth, ref sparse_unique_index);

        int[] sparse_order = new int[dim_num * point_num];
        int[] sparse_index = new int[dim_num * point_num];

        SGMG.sgmg_index(dim_num, level_max, rule, point_num,
                        point_total_num, sparse_unique_index, growth, ref sparse_order, ref sparse_index);
        //
        //  Compute points and weights.
        //
        double[] sparse_point = new double [dim_num * point_num];

        SGMG.sgmg_point(dim_num, level_max, rule, np,
                        p, gw_compute_points, point_num, sparse_order, sparse_index,
                        growth, ref sparse_point);

        double[] sparse_weight = new double[point_num];

        SGMG.sgmg_weight(dim_num, level_max, rule, np,
                         p, gw_compute_weights, point_num, point_total_num, sparse_unique_index,
                         growth, ref sparse_weight);
        //
        //  Write points and weights to files.
        //
        SGMG.sgmg_write(dim_num, rule, np, p,
                        point_num, sparse_weight, sparse_point, file_name);
    }
Exemple #3
0
    private static void sgmg_size_tabulate(int rule_1d, int growth_1d,
                                           int np_1d, double[] p_1d,
                                           Func <int, int, double[], double[], double[]> gw_compute_points_1d,
                                           int dim_min, int dim_max, int level_max_min, int level_max_max)

    //***************************************************************************80
    //
    //  Purpose:
    //
    //    SGMG_SIZE_TABULATE tests SGMG_SIZE.
    //
    //  Discussion:
    //
    //    We do NOT consider mixed rules.  Instead, we are looking at sparse grid
    //    rules for which all dimensions use the same 1D rule family.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    13 April 2014
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int RULE_1D, the 1D rule.
    //     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 GROWTH_1D, the 1D growth rule.
    //    0, "DF", default growth associated with this quadrature rule;
    //    1, "SL", slow linear, L+1;
    //    2  "SO", slow linear odd, O=1+2((L+1)/2)
    //    3, "ML", moderate linear, 2L+1;
    //    4, "SE", slow exponential;
    //    5, "ME", moderate exponential;
    //    6, "FE", full exponential.
    //
    //    Input, int NP_1D, the number of parameters in the 1D rule.
    //
    //    Input, double P_1D[NP_1D], the parameters for the 1D rule.
    //
    //    Input, void gw_compute_points_1d ( int order, int np, double p[], double w[] ),
    //    the function to be used to compute points for the 1D rule.
    //
    //    Input, int DIM_MIN, the minimum spatial dimension.
    //
    //    Input, int DIM_MAX, the maximum spatial dimension.
    //
    //    Input, int LEVEL_MAX_MIN, the minimum value of LEVEL_MAX.
    //
    //    Input, int LEVEL_MAX_MAX, the maximum value of LEVEL_MAX.
    //
    {
        int dim_num;
        int level_max;

        Console.WriteLine("");
        Console.WriteLine("SGMG_SIZE_TABULATE");
        Console.WriteLine("  SGMG_SIZE returns the number of distinct");
        Console.WriteLine("  points in a sparse grid.");
        Console.WriteLine("");
        Console.WriteLine("  We use the same rule in all dimensions, and count the points");
        Console.WriteLine("  for a range of dimensions and levels.");
        Console.WriteLine("");
        Console.WriteLine("  1D rule index is " + rule_1d + "");
        Console.WriteLine("  1D growth index is " + growth_1d + "");
        Console.WriteLine("");

        double tol = Math.Sqrt(typeMethods.r8_epsilon());

        string cout = "   DIM: ";

        for (dim_num = dim_min; dim_num <= dim_max; dim_num++)
        {
            cout += "  " + dim_num.ToString().PadLeft(8);
        }

        Console.WriteLine(cout);
        Console.WriteLine("");
        Console.WriteLine("   LEVEL_MAX");
        Console.WriteLine("");

        for (level_max = level_max_min; level_max <= level_max_max; level_max++)
        {
            cout = "    " + level_max.ToString().PadLeft(4);

            for (dim_num = dim_min; dim_num <= dim_max; dim_num++)
            {
                int[]    rule   = new int[dim_num];
                int[]    growth = new int[dim_num];
                int[]    np     = new int[dim_num];
                int      np_sum = dim_num * np_1d;
                double[] p      = new double[np_sum];
                Func <int, int, double[], double[], double[]>[] gw_compute_points = new Func <int, int, double[], double[], double[]> [dim_num];

                const int j = 0;
                int       dim;
                for (dim = 0; dim < dim_num; dim++)
                {
                    rule[dim]   = rule_1d;
                    growth[dim] = growth_1d;
                    np[dim]     = np_1d;
                    int i;
                    for (i = 0; i < np_sum; i++)
                    {
                        p[j] = p_1d[i];
                    }

                    gw_compute_points[dim] = gw_compute_points_1d;
                }

                int point_num = SGMG.sgmg_size(dim_num, level_max, rule,
                                               np, p, gw_compute_points, tol, growth);

                cout += "  " + point_num.ToString().PadLeft(8);
            }

            Console.WriteLine(cout);
        }
    }
Exemple #4
0
    private static void sgmg_weight_test(int dim_num, int level_max_min,
                                         int level_max_max, int[] rule, int[] growth, int[] np, double[] p,
                                         Func <int, int, double[], double[], double[]>[] gw_compute_points,
                                         Func <int, int, double[], double[], double[]>[] gw_compute_weights,
                                         double tol)

    //***************************************************************************80
    //
    //  Purpose:
    //
    //    SGMG_WEIGHT_TEST checks the sum of the quadrature weights.
    //
    //  Discussion:
    //
    //    If any component rule is of Golub-Welsch type, we cannot compute
    //    the exact weight sum, which we set, instead, to zero.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    20 June 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int DIM_NUM, the spatial dimension.
    //
    //    Input, int LEVEL_MAX_MIN, LEVEL_MAX_MAX, the minimum and
    //    maximum values of LEVEL_MAX.
    //
    //    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 GROWTH[DIM_NUM], the growth rule in each dimension.
    //    0, "DF", default growth associated with this quadrature rule;
    //    1, "SL", slow linear, L+1;
    //    2  "SO", slow linear odd, O=1+2((L+1)/2)
    //    3, "ML", moderate linear, 2L+1;
    //    4, "SE", slow exponential;
    //    5, "ME", moderate exponential;
    //    6, "FE", full exponential.
    //
    //    Input, int NP[RULE_NUM], the number of parameters used by each rule.
    //
    //    Input, double P[sum(NP[*])], the parameters needed by each rule.
    //
    //    Input, void ( *GW_COMPUTE_POINTS[] ) ( int order, int np, double p[], double x[] ),
    //    an array of pointers to functions which return the 1D quadrature points
    //    associated with each spatial dimension for which a Golub Welsch rule
    //    is used.
    //
    //    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.
    //
    //    Input, double TOL, a tolerance for point equality.
    //
    {
        double alpha;
        double beta;
        int    dim;
        int    i;
        int    level_max;

        Console.WriteLine("");
        Console.WriteLine("SGMG_WEIGHT_TEST");
        Console.WriteLine("  Compute the weights of a sparse grid.");
        Console.WriteLine("");
        Console.WriteLine("  Each sparse grid is of spatial dimension DIM_NUM,");
        Console.WriteLine("  and is made up of product grids of levels up to LEVEL_MAX.");
        Console.WriteLine("");
        Console.WriteLine(" Dimension      Rule  Growth rate       Parameters");
        Console.WriteLine("");

        int p_index = 0;

        for (dim = 0; dim < dim_num; dim++)
        {
            switch (rule[dim])
            {
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8) + "");
                break;

            case 6:
                alpha    = p[p_index];
                p_index += 1;
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8)
                                  + "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
                break;

            case 7:
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8) + "");
                break;

            case 8:
                alpha    = p[p_index];
                p_index += 1;
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8)
                                  + "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
                break;

            case 9:
                alpha    = p[p_index];
                p_index += 1;
                beta     = p[p_index];
                p_index += 1;
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8)
                                  + "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14)
                                  + "  " + beta.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
                break;

            case 10:
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + growth[dim].ToString().PadLeft(8) + "");
                break;

            case 11:
            {
                string cout = "  " + dim.ToString().PadLeft(8)
                              + "  " + rule[dim].ToString().PadLeft(8)
                              + "  " + growth[dim].ToString().PadLeft(8);
                for (i = 0; i < np[dim]; i++)
                {
                    alpha    = p[p_index];
                    p_index += 1;
                    cout    += "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14);
                }

                Console.WriteLine(cout);
                break;
            }

            case 12:
            {
                string cout = "  " + dim.ToString().PadLeft(8)
                              + "  " + rule[dim].ToString().PadLeft(8)
                              + "  " + growth[dim].ToString().PadLeft(8);
                for (i = 0; i < np[dim]; i++)
                {
                    alpha    = p[p_index];
                    p_index += 1;
                    cout    += "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14);
                }

                Console.WriteLine(cout);
                break;
            }

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

        double weight_sum_exact = 1.0;

        p_index = 0;
        for (dim = 0; dim < dim_num; dim++)
        {
            switch (rule[dim])
            {
            case 1:
            case 2:
            case 3:
            case 4:
                weight_sum_exact *= 2.0;
                break;

            case 5:
                weight_sum_exact *= Math.Sqrt(Math.PI);
                break;

            case 6:
                alpha             = p[p_index];
                p_index          += 1;
                weight_sum_exact *= typeMethods.r8_gamma(0.5 * (alpha + 1.0));
                break;

            case 7:
                weight_sum_exact *= 1.0;
                break;

            case 8:
                alpha             = p[p_index];
                p_index          += 1;
                weight_sum_exact *= typeMethods.r8_gamma(alpha + 1.0);
                break;

            case 9:
                alpha    = p[p_index];
                p_index += 1;
                beta     = p[p_index];
                p_index += 1;
                double arg1   = -alpha;
                double arg2   = 1.0;
                double arg3   = beta + 2.0;
                double arg4   = -1.0;
                double value1 = typeMethods.r8_hyper_2f1(arg1, arg2, arg3, arg4);
                arg1 = -beta;
                arg2 = 1.0;
                arg3 = alpha + 2.0;
                arg4 = -1.0;
                double value2 = typeMethods.r8_hyper_2f1(arg1, arg2, arg3, arg4);
                weight_sum_exact *= value1 / (beta + 1.0) + value2 / (alpha + 1.0);
                break;

            case 10:
                weight_sum_exact *= Math.Sqrt(Math.PI);
                break;

            case 11:
            {
                for (i = 0; i < np[dim]; i++)
                {
                    alpha    = p[p_index];
                    p_index += 1;
                }

                weight_sum_exact = 0.0;
                break;
            }

            case 12:
            {
                for (i = 0; i < np[dim]; i++)
                {
                    alpha    = p[p_index];
                    p_index += 1;
                }

                weight_sum_exact = 0.0;
                break;
            }

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

        switch (weight_sum_exact)
        {
        case 0.0:
            Console.WriteLine("");
            Console.WriteLine("  Because this rule includes Golub-Welsch components,");
            Console.WriteLine("  we do not try to compute the exact weight sum.");
            break;

        default:
            Console.WriteLine("");
            Console.WriteLine("  As a simple test, sum these weights.");
            Console.WriteLine("  They should sum to exactly " + weight_sum_exact + "");
            break;
        }

        Console.WriteLine("");
        Console.WriteLine("     Level      Weight sum  Expected sum    Difference");
        Console.WriteLine("");

        for (level_max = level_max_min; level_max <= level_max_max; level_max++)
        {
            int point_total_num = SGMG.sgmg_size_total(dim_num,
                                                       level_max, rule, growth);

            int point_num = SGMG.sgmg_size(dim_num, level_max,
                                           rule, np, p, gw_compute_points, tol, growth);

            int[] sparse_unique_index = new int[point_total_num];

            SGMG.sgmg_unique_index(dim_num, level_max, rule,
                                   np, p, gw_compute_points, tol, point_num, point_total_num,
                                   growth, ref sparse_unique_index);

            double[] sparse_weight = new double[point_num];

            SGMG.sgmg_weight(dim_num, level_max, rule, np,
                             p, gw_compute_weights, point_num, point_total_num, sparse_unique_index,
                             growth, ref sparse_weight);

            double weight_sum = typeMethods.r8vec_sum(point_num, sparse_weight);

            double weight_sum_error = typeMethods.r8_abs(weight_sum - weight_sum_exact);

            Console.WriteLine("  " + level_max.ToString().PadLeft(8)
                              + "  " + weight_sum.ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + weight_sum_exact.ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + weight_sum_error.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }
    }