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); }
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) + ""); } }
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); }
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(""); }
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); }