Beispiel #1
0
    private static void triangle_area_test()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TRIANGLE_AREA_TEST tests TRIANGLE_AREA.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    04 November 2015
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double[] t =
        {
            0.0, 1.0,
            0.0, 0.0,
            1.0, 0.0
        };

        Console.WriteLine("");
        Console.WriteLine("TRIANGLE_AREA_TEST");
        Console.WriteLine("  TRIANGLE_AREA computes the area of a triangle.");

        typeMethods.r8mat_transpose_print(2, 3, t, "  Triangle vertices:");

        double area = Integrals.triangle_area(t);

        Console.WriteLine("");
        Console.WriteLine("  Triangle area is " + area + "");
    }
    public static double[] triangle_monte_carlo(double[] t, int p_num, int f_num,
                                                Func <int, int, tusData> triangle_unit_sample,
                                                Func <int, double[], int, double[]> triangle_integrand, ref int seed)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TRIANGLE_MONTE_CARLO applies the Monte Carlo rule to integrate a function.
    //
    //  Discussion:
    //
    //    The function f(x,y) is to be integrated over a triangle T.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    15 August 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, double T[2*3], the triangle vertices.
    //
    //    Input, int P_NUM, the number of sample points.
    //
    //    Input, int F_NUM, the number of functions to integrate.
    //
    //    Input, external TRIANGLE_UNIT_SAMPLE, the sampling routine.
    //
    //    Input, external TRIANGLE_INTEGRAND, the integrand routine.
    //
    //    Input/output, int &SEED, a seed for the random
    //    number generator.
    //
    //    Output, dobule TRIANGLE_MONTE_CARLO[F_NUM], the approximate integrals.
    //
    {
        int i;

        double area = Integrals.triangle_area(t);

        tusData data = triangle_unit_sample(p_num, seed);

        seed = data.seed;
        double[] p = data.result;

        double[] p2 = new double[2 * p_num];

        Reference.reference_to_physical_t3(t, p_num, p, ref p2);

        double[] fp = triangle_integrand(p_num, p2, f_num);

        double[] result = new double[f_num];

        for (i = 0; i < f_num; i++)
        {
            double fp_sum = 0.0;
            int    j;
            for (j = 0; j < p_num; j++)
            {
                fp_sum += fp[i + j * f_num];
            }

            result[i] = area * fp_sum / p_num;
        }

        return(result);
    }
Beispiel #3
0
    private static void test05()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST05 demonstrates REFERENCE_TO_PHYSICAL_T3.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    30 January 2007
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        const int NODE_NUM = 3;

        int node;

        double[] node_xy =
        {
            0.0, 0.0,
            1.0, 0.0,
            0.0, 1.0
        };
        double[] node_xy2 =
        {
            1.0, 2.0,
            1.0, 1.0,
            3.0, 2.0
        };
        int order;

        Console.WriteLine("");
        Console.WriteLine("TEST05");
        Console.WriteLine("  REFERENCE_TO_PHYSICAL_T3 transforms a rule");
        Console.WriteLine("  on the unit (reference) triangle to a rule on ");
        Console.WriteLine("  an arbitrary (physical) triangle.");

        const int rule = 3;

        int order_num = NewtonCotesOpen.triangle_nco_order_num(rule);

        double[] xy  = new double[2 * order_num];
        double[] xy2 = new double[2 * order_num];
        double[] w   = new double[order_num];

        NewtonCotesOpen.triangle_nco_rule(rule, order_num, ref xy, ref w);
        //
        //  Here is the reference triangle, and its rule.
        //
        Console.WriteLine("");
        Console.WriteLine("  The reference triangle:");
        Console.WriteLine("");

        for (node = 0; node < NODE_NUM; node++)
        {
            Console.WriteLine("  " + (node + 1).ToString(CultureInfo.InvariantCulture).PadLeft(8)
                              + "  " + node_xy[0 + node * 2].ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + node_xy[1 + node * 2].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }

        double area = Integrals.triangle_area(node_xy);

        Console.WriteLine("");
        Console.WriteLine("  Rule " + rule + " for reference triangle");
        Console.WriteLine("  with area = " + area + "");
        Console.WriteLine("");
        Console.WriteLine("                X               Y               W");
        Console.WriteLine("");

        for (order = 0; order < order_num; order++)
        {
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(8)
                              + "  " + xy[0 + order * 2].ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + xy[1 + order * 2].ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + w[order].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }

        //
        //  Transform the rule.
        //
        Reference.reference_to_physical_t3(node_xy2, order_num, xy, ref xy2);
        //
        //  Here is the physical triangle, and its transformed rule.
        //
        Console.WriteLine("");
        Console.WriteLine("  The physical triangle:");
        Console.WriteLine("");

        for (node = 0; node < NODE_NUM; node++)
        {
            Console.WriteLine("  " + (node + 1).ToString(CultureInfo.InvariantCulture).PadLeft(8)
                              + "  " + node_xy2[0 + node * 2].ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + node_xy2[1 + node * 2].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }

        double area2 = Integrals.triangle_area(node_xy2);

        Console.WriteLine("");
        Console.WriteLine("  Rule " + rule + " for physical triangle");
        Console.WriteLine("  with area = " + area2 + "");
        Console.WriteLine("");
        Console.WriteLine("                X               Y               W");
        Console.WriteLine("");

        for (order = 0; order < order_num; order++)
        {
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(8)
                              + "  " + xy2[0 + order * 2].ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + xy2[1 + order * 2].ToString(CultureInfo.InvariantCulture).PadLeft(14)
                              + "  " + w[order].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }
    }
Beispiel #4
0
    public static double[] sample_quad_new(double[] quad_xy, int n, ref int seed)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    SAMPLE_QUAD_NEW returns random points in a quadrilateral.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    22 February 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, double QUAD_XY[2*4], the coordinates of the nodes.
    //
    //    Input, int N, the number of points to sample.
    //
    //    Input/output, int *SEED, a seed for the random
    //     number generator.
    //
    //    Output, double SAMPLE_QUAD[2*N], the sample points.
    //
    {
        int i;

        double[] t1 = new double[2 * 3];
        double[] t2 = new double[2 * 3];

        t1[0 + 0 * 2] = quad_xy[0 + 0 * 2];
        t1[1 + 0 * 2] = quad_xy[1 + 0 * 2];
        t1[0 + 1 * 2] = quad_xy[0 + 1 * 2];
        t1[1 + 1 * 2] = quad_xy[1 + 1 * 2];
        t1[0 + 2 * 2] = quad_xy[0 + 2 * 2];
        t1[1 + 2 * 2] = quad_xy[1 + 2 * 2];

        double area1 = Integrals.triangle_area(t1);

        t2[0 + 0 * 2] = quad_xy[0 + 2 * 2];
        t2[1 + 0 * 2] = quad_xy[1 + 2 * 2];
        t2[0 + 1 * 2] = quad_xy[0 + 3 * 2];
        t2[1 + 1 * 2] = quad_xy[1 + 3 * 2];
        t2[0 + 2 * 2] = quad_xy[0 + 0 * 2];
        t2[1 + 2 * 2] = quad_xy[1 + 0 * 2];

        double area2 = Integrals.triangle_area(t2);

        if (area1 < 0.0 || area2 < 0.0)
        {
            t1[0 + 0 * 2] = quad_xy[0 + 1 * 2];
            t1[1 + 0 * 2] = quad_xy[1 + 1 * 2];
            t1[0 + 1 * 2] = quad_xy[0 + 2 * 2];
            t1[1 + 1 * 2] = quad_xy[1 + 2 * 2];
            t1[0 + 2 * 2] = quad_xy[0 + 3 * 2];
            t1[1 + 2 * 2] = quad_xy[1 + 3 * 2];

            area1 = Integrals.triangle_area(t1);

            t2[0 + 0 * 2] = quad_xy[0 + 3 * 2];
            t2[1 + 0 * 2] = quad_xy[1 + 3 * 2];
            t2[0 + 1 * 2] = quad_xy[0 + 0 * 2];
            t2[1 + 1 * 2] = quad_xy[1 + 0 * 2];
            t2[0 + 2 * 2] = quad_xy[0 + 1 * 2];
            t2[1 + 2 * 2] = quad_xy[1 + 1 * 2];

            area2 = Integrals.triangle_area(t2);

            if (area1 < 0.0 || area2 < 0.0)
            {
                Console.WriteLine("");
                Console.WriteLine("SAMPLE_QUAD - Fatal error!");
                Console.WriteLine("  The quadrilateral nodes seem to be listed in");
                Console.WriteLine("  the wrong order, or the quadrilateral is");
                Console.WriteLine("  degenerate.");
                return(null);
            }
        }

        double area_total = area1 + area2;

        //
        //  Choose a triangle at random, weighted by the areas.
        //  Then choose a point in that triangle.
        //
        double[] xy = new double[2 * n];

        for (i = 0; i < n; i++)
        {
            double r = UniformRNG.r8_uniform_01(ref seed);

            if (r * area_total < area1)
            {
                typeMethods.triangle_sample(t1, 1, ref seed, ref xy, +i * 2);
            }
            else
            {
                typeMethods.triangle_sample(t2, 1, ref seed, ref xy, +i * 2);
            }
        }

        return(xy);
    }
Beispiel #5
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for TRIANGLE_EXACTNESS.
    //
    //  Discussion:
    //
    //    This program investigates the polynomial exactness of a quadrature
    //    rule for the triangle.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    31 July 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        int    degree;
        int    degree_max;
        bool   error = false;
        int    last  = 0;
        int    point;
        string quad_filename;

        Console.WriteLine("");
        Console.WriteLine("TRIANGLE_EXACTNESS");
        Console.WriteLine("");
        Console.WriteLine("  Investigate the polynomial exactness of a quadrature");
        Console.WriteLine("  rule for the triangle by integrating all monomials");
        Console.WriteLine("  of a given degree.");
        Console.WriteLine("");
        Console.WriteLine("  The rule will be adjusted to the unit triangle.");
        //
        //  Get the quadrature file root name:
        //
        try
        {
            quad_filename = args[0];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("TRIANGLE_EXACTNESS:");
            Console.WriteLine("  Enter the \"root\" name of the quadrature files.");

            quad_filename = Console.ReadLine();
        }

        //
        //  Create the names of:
        //    the quadrature X file;
        //    the quadrature W file;
        //    the quadrature R file;
        //
        string quad_r_filename = quad_filename + "_r.txt";
        string quad_w_filename = quad_filename + "_w.txt";
        string quad_x_filename = quad_filename + "_x.txt";

        //
        //  The second command line argument is the maximum degree.
        //
        try
        {
            degree_max = typeMethods.s_to_i4(args[1], ref last, ref error);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("TRIANGLE_EXACTNESS:");
            Console.WriteLine("  Please enter the maximum total degree to check.");

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

        //
        //  Summarize the input.
        //
        Console.WriteLine("");
        Console.WriteLine("TRIANGLE_EXACTNESS: 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 total degree to check = " + degree_max + "");
        //
        //  Read the X file.
        //
        TableHeader hdr       = typeMethods.r8mat_header_read(quad_x_filename);
        int         dim_num   = hdr.m;
        int         point_num = hdr.n;

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

        if (dim_num != 2)
        {
            Console.WriteLine("");
            Console.WriteLine("TRIANGLE_EXACTNESS - Fatal error!");
            Console.WriteLine("  The quadrature abscissas must be two dimensional.");
            return;
        }

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

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

        if (point_num2 != point_num)
        {
            Console.WriteLine("");
            Console.WriteLine("TRIANGLE_EXACTNESS - 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, 1, point_num);
        //
        //  Read the R file.
        //
        hdr = typeMethods.r8mat_header_read(quad_r_filename);
        int dim_num3   = hdr.m;
        int point_num3 = hdr.n;

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

        if (point_num3 != 3)
        {
            Console.WriteLine("");
            Console.WriteLine("TRIANGLE_EXACTNESS - Fatal error!");
            Console.WriteLine("  The quadrature region file should have 3 lines.");
            return;
        }

        double[] r = typeMethods.r8mat_data_read(quad_r_filename, dim_num, 3);
        //
        //  Rescale the weights.
        //
        double area = Integrals.triangle_area(r);

        for (point = 0; point < point_num; point++)
        {
            w[point] = 0.5 * w[point] / area;
        }

        //
        //  Translate the abscissas.
        //
        double[] x_ref = new double[2 * point_num];

        Triangulation.triangle_order3_physical_to_reference(r, point_num, x, ref x_ref);
        //
        //  Explore the monomials.
        //
        int[] expon = new int[dim_num];

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

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

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

                double quad_error = Integrals.triangle01_monomial_quadrature(dim_num, expon, point_num,
                                                                             x_ref, w);

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

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

                Console.WriteLine(cout);

                if (!more)
                {
                    break;
                }
            }
        }

        Console.WriteLine("");
        Console.WriteLine("TRIANGLE_EXACTNESS:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
Beispiel #6
0
    public static double area_quad(double[] quad_xy)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    AREA_QUAD returns the area of a quadrilateral.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    23 February 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, double QUAD_XY[2*4], the coordinates of the nodes.
    //
    //    Output, double AREA_QUAD, the area.
    //
    {
        double[] t1 = new double[2 * 3];
        double[] t2 = new double[2 * 3];

        t1[0 + 0 * 2] = quad_xy[0 + 0 * 2];
        t1[1 + 0 * 2] = quad_xy[1 + 0 * 2];
        t1[0 + 1 * 2] = quad_xy[0 + 1 * 2];
        t1[1 + 1 * 2] = quad_xy[1 + 1 * 2];
        t1[0 + 2 * 2] = quad_xy[0 + 2 * 2];
        t1[1 + 2 * 2] = quad_xy[1 + 2 * 2];

        double area1 = Integrals.triangle_area(t1);

        t2[0 + 0 * 2] = quad_xy[0 + 2 * 2];
        t2[1 + 0 * 2] = quad_xy[1 + 2 * 2];
        t2[0 + 1 * 2] = quad_xy[0 + 3 * 2];
        t2[1 + 1 * 2] = quad_xy[1 + 3 * 2];
        t2[0 + 2 * 2] = quad_xy[0 + 0 * 2];
        t2[1 + 2 * 2] = quad_xy[1 + 0 * 2];

        double area2 = Integrals.triangle_area(t2);

        if (area1 < 0.0 || area2 < 0.0)
        {
            t1[0 + 0 * 2] = quad_xy[0 + 1 * 2];
            t1[1 + 0 * 2] = quad_xy[1 + 1 * 2];
            t1[0 + 1 * 2] = quad_xy[0 + 2 * 2];
            t1[1 + 1 * 2] = quad_xy[1 + 2 * 2];
            t1[0 + 2 * 2] = quad_xy[0 + 3 * 2];
            t1[1 + 2 * 2] = quad_xy[1 + 3 * 2];

            area1 = Integrals.triangle_area(t1);

            t2[0 + 0 * 2] = quad_xy[0 + 3 * 2];
            t2[1 + 0 * 2] = quad_xy[1 + 3 * 2];
            t2[0 + 1 * 2] = quad_xy[0 + 0 * 2];
            t2[1 + 1 * 2] = quad_xy[1 + 0 * 2];
            t2[0 + 2 * 2] = quad_xy[0 + 1 * 2];
            t2[1 + 2 * 2] = quad_xy[1 + 1 * 2];

            area2 = Integrals.triangle_area(t2);

            if (area1 < 0.0 || area2 < 0.0)
            {
                Console.WriteLine("");
                Console.WriteLine("AREA_QUAD - Fatal error!");
                Console.WriteLine("  The quadrilateral nodes seem to be listed in");
                Console.WriteLine("  the wrong order, or the quadrilateral is");
                Console.WriteLine("  degenerate.");
                return(0);
            }
        }

        double area = area1 + area2;

        return(area);
    }