예제 #1
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for SPARSE_GRID_OPEN_DATASET.
    //
    //  Discussion:
    //
    //    This program computes a quadrature rule and writes it to a file.
    //
    //    The quadrature rule is associated with a sparse grid derived from
    //    a Smolyak construction using an open 1D quadrature rule.
    //
    //    The user specifies:
    //    * the spatial dimension of the quadrature region,
    //    * the level that defines the Smolyak grid.
    //    * the open 1D quadrature rule.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    01 February 2009
    //
    //  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.
    //
    {
        int    dim;
        int    dim_num;
        int    level_max;
        int    point;
        string r_filename = "";
        int    rule;
        string w_filename = "";
        string x_filename = "";

        Console.WriteLine("");
        Console.WriteLine("SPARSE_GRID_OPEN_DATASET");
        Console.WriteLine("");
        Console.WriteLine("  Compute the abscissas and weights of a quadrature rule");
        Console.WriteLine("  associated with a sparse grid derived from a Smolyak");
        Console.WriteLine("  construction based on an open quadrature rule.");
        Console.WriteLine("");
        Console.WriteLine("  Inputs to the program include:");
        Console.WriteLine("");
        Console.WriteLine("    DIM_NUM, the spatial dimension.");
        Console.WriteLine("    (typically in the range of 2 to 10)");
        Console.WriteLine("");
        Console.WriteLine("    LEVEL_MAX, the \"level\" of the sparse grid.");
        Console.WriteLine("    (typically in the range of 0, 1, 2, 3, ...");
        Console.WriteLine("");
        Console.WriteLine("    RULE, the 1D quadrature rule");
        Console.WriteLine("    2: Fejer Type 2 (\"F2\").");
        Console.WriteLine("    3: Gauss-Patterson (\"GP\");");
        Console.WriteLine("    4: Newton-Cotes Open (\"NCO\").");
        Console.WriteLine("    5: Tanh-Sinh (\"TS\").");
        Console.WriteLine("");
        Console.WriteLine("  Output from the program includes:");
        Console.WriteLine("");
        Console.WriteLine("    A printed table of the abscissas and weights.");
        Console.WriteLine("");
        Console.WriteLine("    A set of files defining the quadrature rules.");
        Console.WriteLine("");
        Console.WriteLine("    \"***_d?_level?_x.txt\", a file of the abscissas;");
        Console.WriteLine("    \"***_d?_level?_w.txt\", a file of the weights;");
        Console.WriteLine("    \"***_d?_level?_r.txt\", a file of the ranges.");
        //
        //  Get the spatial dimension:
        //
        try
        {
            dim_num = Convert.ToInt32(args[0]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("SPARSE_GRID_OPEN_DATASET:");
            Console.WriteLine("  Enter the value of DIM_NUM.");

            dim_num = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  Spatial dimension requested is = " + dim_num + "");
        //
        //  Get the product file root name:
        //
        try
        {
            level_max = Convert.ToInt32(args[1]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("SPARSE_GRID_OPEN_DATASET:");
            Console.WriteLine("  Enter the value of LEVEL_MAX.");
            level_max = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The sparse grid level is = " + level_max + "");
        //
        //  Get the rule index:
        //
        try
        {
            rule = Convert.ToInt32(args[2]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("SPARSE_GRID_OPEN_DATASET:");
            Console.WriteLine("  Enter the value of RULE.");
            Console.WriteLine("  2 = F2   = Fejer Type 2 Rule,");
            Console.WriteLine("  3 = GP   = Gauss-Patterson,");
            Console.WriteLine("  4 = NCO  = Newton-Cotes Open,");
            Console.WriteLine("  5 = TS   = Tanh-Sinh.");
            rule = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The 1D quadrature rule index = " + rule + "");

        switch (rule)
        {
        case 2:
            Console.WriteLine("  F2:   Fejer Type 2 Rule.");
            break;

        case 3:
            Console.WriteLine("  GP:   Gauss-Patterson Rule.");
            break;

        case 4:
            Console.WriteLine("  NCO:  Newton-Cotes Open Rule.");
            break;

        case 5:
            Console.WriteLine("  TS:   Tanh-Sinh Rule.");
            break;

        default:
            Console.WriteLine("");
            Console.WriteLine("SPARSE_GRID_OPEN_DATASET - Fatal error!");
            Console.WriteLine("  Illegal value of RULE.");
            return;
        }

        //
        //  How many distinct points will there be?
        //
        int point_num = Grid.sparse_grid_ofn_size(dim_num, level_max);

        Console.WriteLine("");
        Console.WriteLine("  The number of distinct abscissas in the");
        Console.WriteLine("  quadrature rule is determined from the spatial");
        Console.WriteLine("  dimension DIM_NUM and the level LEVEL_MAX.");
        Console.WriteLine("  For the given input, this value will be = " + point_num + "");

        double[] grid_point = new double[dim_num * point_num];
        //
        //  Determine the index vector, relative to the full product grid,
        //  that identifies the points in the sparse grid.
        //
        int[] grid_index = Grid.spgrid_open_index(dim_num, level_max, point_num);

        typeMethods.i4mat_transpose_print_some(dim_num, point_num, grid_index, 1, 1,
                                               dim_num, 10, "  First 10 entries of grid index:");
        //
        //  Compute the physical coordinates of the abscissas.
        //
        int order_max = (int)Math.Pow(2, level_max + 1) - 1;

        switch (rule)
        {
        case 5:
            int    m = level_max - 3;
            int    n = (order_max + 1) / 2 - 1;
            double h = 4.0 / (order_max + 1);

            Console.WriteLine("  M = " + m
                              + "  ORDER_MAX = " + order_max
                              + "  N = " + n
                              + "  H = " + h + "");
            break;
        }

        switch (rule)
        {
        case 2:
        {
            for (point = 0; point < point_num; point++)
            {
                for (dim = 0; dim < dim_num; dim++)
                {
                    grid_point[dim + point * dim_num] =
                        Fejer2.f2_abscissa(order_max, grid_index[dim + point * dim_num]);
                }
            }

            break;
        }

        case 3:
        {
            for (point = 0; point < point_num; point++)
            {
                for (dim = 0; dim < dim_num; dim++)
                {
                    grid_point[dim + point * dim_num] =
                        PattersonQuadrature.gp_abscissa(order_max, grid_index[dim + point * dim_num]);
                }
            }

            break;
        }

        case 4:
        {
            for (point = 0; point < point_num; point++)
            {
                for (dim = 0; dim < dim_num; dim++)
                {
                    grid_point[dim + point * dim_num] =
                        NewtonCotesQuadrature.nco_abscissa(order_max, grid_index[dim + point * dim_num]);
                }
            }

            break;
        }

        case 5:
        {
            for (point = 0; point < point_num; point++)
            {
                for (dim = 0; dim < dim_num; dim++)
                {
                    grid_point[dim + point * dim_num] =
                        TanhSinh.ts_abscissa(order_max, grid_index[dim + point * dim_num]);
                }
            }

            break;
        }
        }

        typeMethods.r8mat_transpose_print_some(dim_num, point_num, grid_point, 1, 1,
                                               dim_num, 10, "  First 10 entries of grid point:");
        //
        //  Gather the weights.
        //
        double[] grid_weight = Grid.spgrid_open_weights(dim_num, level_max, point_num,
                                                        grid_index, rule);

        typeMethods.r8vec_print_some(point_num, grid_weight, 1, 10,
                                     "  First 10 grid weights:");

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

        Console.WriteLine("");
        Console.WriteLine("  Weights sum to   "
                          + weight_sum.ToString("0.################").PadLeft(24) + "");
        Console.WriteLine("  Correct value is "
                          + Math.Pow(2.0, dim_num).ToString("0.################").PadLeft(24) + "");
        switch (rule)
        {
        //
        //  Write the rule to files.
        //
        case 2:
            r_filename = "f2_d" + dim_num
                         + "_level" + level_max + "_r.txt";
            w_filename = "f2_d" + dim_num
                         + "_level" + level_max + "_w.txt";
            x_filename = "f2_d" + dim_num
                         + "_level" + level_max + "_x.txt";
            break;

        case 3:
            r_filename = "gp_d" + dim_num
                         + "_level" + level_max + "_r.txt";
            w_filename = "gp_d" + dim_num
                         + "_level" + level_max + "_w.txt";
            x_filename = "gp_d" + dim_num
                         + "_level" + level_max + "_x.txt";
            break;

        case 4:
            r_filename = "nco_d" + dim_num
                         + "_level" + level_max + "_r.txt";
            w_filename = "nco_d" + dim_num
                         + "_level" + level_max + "_w.txt";
            x_filename = "nco_d" + dim_num
                         + "_level" + level_max + "_x.txt";
            break;

        case 5:
            r_filename = "ts_d" + dim_num
                         + "_level" + level_max + "_r.txt";
            w_filename = "ts_d" + dim_num
                         + "_level" + level_max + "_w.txt";
            x_filename = "ts_d" + dim_num
                         + "_level" + level_max + "_x.txt";
            break;
        }

        Console.WriteLine("");
        Console.WriteLine("  Creating X file = \"" + x_filename + "\".");

        typeMethods.r8mat_write(x_filename, dim_num, point_num, grid_point);

        Console.WriteLine("  Creating W file = \"" + w_filename + "\".");

        typeMethods.r8mat_write(w_filename, 1, point_num, grid_weight);

        double[] grid_region = new double[dim_num * 2];

        for (dim = 0; dim < dim_num; dim++)
        {
            grid_region[dim + 0 * dim_num] = -1.0;
            grid_region[dim + 1 * dim_num] = +1.0;
        }

        Console.WriteLine("  Creating R file = \"" + r_filename + "\".");

        typeMethods.r8mat_write(r_filename, dim_num, 2, grid_region);

        Console.WriteLine("");
        Console.WriteLine("SPARSE_GRID_OPEN_DATASET:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
예제 #2
0
    public static double[] product_weights_open(int dim_num, int[] order_1d, int order_nd,
                                                int rule)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    PRODUCT_WEIGHTS_OPEN: weights for an open product rule.
    //
    //  Discussion:
    //
    //    This routine computes the weights for a quadrature rule which is
    //    a product of 1D rules of varying order.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    01 February 2009
    //
    //  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, the 1D quadrature rule being used.
    //    2, Fejer Type 2 Rule;
    //    3, Gauss-Patterson Rule,
    //    4, Newton-Cotes Open Rule,
    //    5, Tanh-Sinh Rule.
    //
    //    Output, double PRODUCT_WEIGHTS_OPEN[DIM_NUM*ORDER_ND], the product
    //    rule weights.
    //
    {
        int dim;
        int order;

        double[] w_1d = null;
        typeMethods.r8vecDPData data = new();

        double[] w_nd = new double[order_nd];

        for (order = 0; order < order_nd; order++)
        {
            w_nd[order] = 1.0;
        }

        for (dim = 0; dim < dim_num; dim++)
        {
            w_1d = rule switch
            {
                2 => Fejer2.f2_weights(order_1d[dim]),
                3 => PattersonQuadrature.gp_weights(order_1d[dim]),
                4 => NewtonCotesQuadrature.nco_weights(order_1d[dim]),
                5 => TanhSinh.ts_weights(order_1d[dim]),
                _ => w_1d
            };

            typeMethods.r8vec_direct_product2(ref data, dim, order_1d[dim], w_1d, dim_num,
                                              order_nd, ref w_nd);
        }

        return(w_nd);
    }
}