コード例 #1
0
    private static void sgmga_product_weight_test(int dim_num, int[] order_1d,
                                                  int order_nd, int[] rule, int[] np, double[] p,
                                                  Func <int, int, double[], double[], double[]>[] gw_compute_weights)

    //***************************************************************************80
    //
    //  Purpose:
    //
    //    SGMGA_PRODUCT_WEIGHT_TEST: weights of a mixed factor product rule.
    //
    //  Discussion:
    //
    //    This routine computes a sparse grid and compares the sum of the weights
    //    to the expected exact value.
    //
    //    The routine cannot produce a result for rules that include one or more
    //    component rules of type 10, that is, Golub-Welsch rules.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    09 June 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  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[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_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.
    //
    {
        double alpha;
        double beta;
        int    dim;
        int    i;
        //
        //  Determine the integral of 1 over the multidimensional weighted region.
        //
        int p_index = 0;

        double weight_sum_exact = 1.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("SGMGA_PRODUCT_WEIGHT_TEST - Fatal error!");
                Console.WriteLine("  Unexpected value of RULE[" + dim + "] = "
                                  + rule[dim] + ".");
                return;
            }
        }

        Console.WriteLine("");
        Console.WriteLine("SGMGA_PRODUCT_WEIGHT_TEST:");
        Console.WriteLine("  Compute the weights of a mixed factor product grid.");
        if (weight_sum_exact != 0.0)
        {
            Console.WriteLine("");
            Console.WriteLine("  As a simple test, sum these weights.");
            Console.WriteLine("  They should sum to exactly " + weight_sum_exact + "");
        }

        Console.WriteLine("");
        Console.WriteLine("  Spatial dimension DIM_NUM = " + dim_num + "");

        Console.WriteLine("");
        Console.WriteLine(" Dimension      Rule    Growth        Parameters");
        Console.WriteLine("");

        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)
                                  + "  " + order_1d[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)
                                  + "  " + order_1d[dim].ToString().PadLeft(8)
                                  + "  " + alpha.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
                break;

            case 7:
                Console.WriteLine("  " + dim.ToString().PadLeft(8)
                                  + "  " + rule[dim].ToString().PadLeft(8)
                                  + "  " + order_1d[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)
                                  + "  " + order_1d[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)
                                  + "  " + order_1d[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)
                                  + "  " + order_1d[dim].ToString().PadLeft(8) + "");
                break;

            case 11:
            {
                string cout = "  " + dim.ToString().PadLeft(8)
                              + "  " + rule[dim].ToString().PadLeft(8)
                              + "  " + order_1d[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)
                              + "  " + order_1d[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("SGMGA_PRODUCT_WEIGHT_TEST - Fatal error!");
                Console.WriteLine("  Cannot perform test for rule = " + rule[dim] + "");
                return;
            }
        }

        //
        //  Compute the weights.
        //
        double[] weight = new double[order_nd];

        SGMGAniso.sgmga_product_weight(dim_num, order_1d, order_nd, rule,
                                       np, p, gw_compute_weights, ref weight);
        //
        //  Sum the weights to get the approximation to the integral of 1.
        //
        double weight_sum = typeMethods.r8vec_sum(order_nd, weight);
        //
        //  Compare the exact and estimated integrals.
        //
        double weight_sum_error = typeMethods.r8_abs(weight_sum - weight_sum_exact);

        if (weight_sum_exact != 0.0)
        {
            Console.WriteLine("");
            Console.WriteLine("    Weight sum  Expected sum    Difference");
            Console.WriteLine("");
            Console.WriteLine("  " + weight_sum.ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + weight_sum_exact.ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + weight_sum_error.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }
        else
        {
            Console.WriteLine("");
            Console.WriteLine("    Weight sum");
            Console.WriteLine("");
            Console.WriteLine("  " + weight_sum.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }
    }