//! Initialisation des zones de calibration
void CalibrationUtils::initTriangles(){

    int base = 1, node_dim, node_num, triangle_num, triangle_order;
    int *triangle_neighbor, *triangle_node;
    double *node_xy;

    //Copie de la liste de points dans un vecteur
    std::vector<calibrationPoint*> *list = new std::vector<calibrationPoint*>();
	for(int i=0; i < GRID_POINTS; i++) { list->push_back(&screenPoints[i]); }

    //Lecture de la liste de points
    r8mat_header_read (list, &node_dim, &node_num );
    node_xy = r8mat_data_read (list, node_dim, node_num);

    //Application de l'algorithme de Delaunay
    triangle_order = 3;
    triangle_node = new int[triangle_order*3*node_num];
    triangle_neighbor = new int[triangle_order*3*node_num];
    dtris2( node_num, base, node_xy, &triangle_num, triangle_node, triangle_neighbor );

    //On affecte les points formant les trianges aux triangles
    i4mat_tomat (triangle_order, triangle_num, triangle_node, list, triangles);

    delete [] node_xy;
    delete [] triangle_node;
    delete [] triangle_neighbor;
}
//! Initialisation des zones de calibration
void CalibrationUtils::initTriangles(){

    int base = 1, node_dim, node_num, triangle_num, triangle_order;
    int *triangle_neighbor, *triangle_node;
    double *node_xy;

    //Lecture de la liste de points
    r8mat_header_read (cameraPoints, &node_dim, &node_num );
    node_xy = r8mat_data_read (cameraPoints, node_dim, node_num);

    //Application de l'algorithme de Delaunay
    triangle_order = 3;
    triangle_node = new int[triangle_order*3*node_num];
    triangle_neighbor = new int[triangle_order*3*node_num];

    dtris2( node_num, base, node_xy, &triangle_num, triangle_node, triangle_neighbor );

    //On affecte les points formant les trianges aux triangles
    i4mat_tomat (triangle_order, triangle_num, triangle_node, cameraPoints, triangles);

    delete [] node_xy;
    delete [] triangle_node;
    delete [] triangle_neighbor;
}
void test01 ( char *input_filename )

/******************************************************************************/
/*
  Purpose:

    TEST01 latinizes a given file.

  Discussion:

    The dataset is presumed to be an M by N array of real numbers,
    where M is the spatial dimension, and N is the number of sample points.

    The dataset is presumed to be stored in a file, with N records,
    one per each sample point.  (Comment records may be included, 
    which begin with '#'.)

    The program reads the data file, "latinizes" the data, and writes
    the latinized data to a new file.

  Modified:

    08 October 2004

  Author:

    John Burkardt
*/
{
  int m;
  int n;
  FILE *output;
  char *output_filename;
  double *table;
/*
  Need to create the output file name from the input filename.
*/
  output_filename = file_name_ext_swap ( input_filename, "latin.txt" );

  r8mat_header_read ( input_filename, &m, &n );

  printf ( "\n" );
  printf ( "  Read the header of \"%s\".\n", input_filename );
  printf ( "\n" );
  printf ( "  Spatial dimension M = %d\n", m );
  printf ( "  Number of points N  = %d\n", n );

  table = r8mat_data_read ( input_filename, m, n );

  printf ( "\n" );
  printf ( "  Read the data in \"%s\".\n", input_filename );

  r8mat_transpose_print_some ( m, n, table, 1, 1, 5, 5, 
    "  Small portion of data read from file:" );

  r8mat_latinize ( m, n, table );

  printf ( "\n" );
  printf ( "  Latinized the data.\n" );

  r8mat_transpose_print_some ( m, n, table, 1, 1, 5, 5, 
    "  Small portion of Latinized data:" );
/*
  Write the data to a file.
*/
  r8mat_write ( output_filename, m, n, table );

  printf ( "\n" );
  printf ( "  Wrote the latinized data to \"%s\".\n", output_filename );

  free ( table );

  return;
}
示例#4
0
int main ( int argc, char *argv[] )

/******************************************************************************/
/*
  Purpose:

    MAIN is the main program for FEM_TO_MEDIT.

  Discussion:

    FEM_TO_MEDIT converts mesh data from FEM format to MEDIT format.

    The FEM format defines "node", "element", and "boundary_node_mask",
    files for a mesh.  A typical set of such files might have the names
    "suv_nodes.txt", "suv_elements.txt" and "suv_boundary_node_mask.txt".

    This program reads these files and creates a MEDIT mesh file, whose
    name might be "suv.mesh".

  Usage:

    fem_to_medit prefix

    where 'prefix' is the common filename prefix so that:

    * prefix_nodes.txt contains the coordinates of the nodes;
    * prefix_elements.txt contains the indices of nodes forming each element;
    * prefix_boundary_node_mask.txt is 0 for interior nodes, 1 for boundary nodes;
    * prefix.mesh will be the MEDIT mesh file created by the program.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    10 October 2014

  Author:

    John Burkardt
*/
{
  int *boundary_node;
  char boundary_node_mask_filename[255];
  int dim;
  int *edge_label;
  int *edge_vertex;
  int edges;
  char element_filename[255];
  int *element_node;
  int element_num;
  int element_order;
  int *hexahedron_label;
  int *hexahedron_vertex;
  int hexahedrons;
  int i;
  int j;
  char medit_filename[255];
  double *node_coord;
  int node_dim;
  char node_filename[255];
  int node_num;
  char prefix[255];
  int *quadrilateral_label;
  int *quadrilateral_vertex;
  int quadrilaterals;
  int *tetrahedron_label;
  int *tetrahedron_vertex;
  int tetrahedrons;
  int *triangle_label;
  int *triangle_vertex;
  int triangles;
  double *vertex_coordinate;
  int *vertex_label;
  int vertices;

  timestamp ( );
  printf ( "\n" );
  printf ( "FEM_TO_MEDIT:\n" );
  printf ( "  C version\n" );
  printf ( "  Read a set of FEM files.\n" );
  printf ( "  Write a corresponding MEDIT mesh file.\n" );
/*
  Get the filename prefix.
*/
  if ( argc <= 1 ) 
  {
    printf ( "\n" );
    printf ( "MESH_TO_XML:\n" );
    printf ( "  Please enter the filename prefix.\n" );

    scanf ( "%s", prefix );
  }
  else 
  {
    strcpy ( prefix, argv[1] );
  }
/*
  Create the file names.
*/
  strcpy ( node_filename, prefix );
  strcat ( node_filename, "_nodes.txt" );
  strcpy ( boundary_node_mask_filename, prefix );
  strcat ( boundary_node_mask_filename, "_boundary_node_mask.txt" );
  strcpy ( element_filename, prefix );
  strcat ( element_filename, "_elements.txt" );
  strcpy ( medit_filename, prefix );
  strcat ( medit_filename, ".mesh" );

  printf ( "\n" );
  printf ( "  Read FEM node file \"%s\"\n", node_filename );
  printf ( "    and FEM element file \"%s\"\n", element_filename );
  printf ( "    and FEM boundary node mask file \"%s\"\n", boundary_node_mask_filename );
  printf ( "  Create MEDIT file \"%s\"\n", medit_filename );
/*
  Read the FEM node data.
*/
  r8mat_header_read ( node_filename, &node_dim, &node_num );

  node_coord = r8mat_data_read ( node_filename, node_dim, node_num );

  printf ( "\n" );
  printf ( "  The node dimension is        %d\n", node_dim );
  printf ( "  The node number is           %d\n", node_num );
/*
  Read the FEM boundary node data.
*/
  boundary_node = i4mat_data_read ( boundary_node_mask_filename, 1, node_num );
/*
  Read the FEM element data.
*/
  i4mat_header_read ( element_filename, &element_order, &element_num );

  element_node = i4mat_data_read ( element_filename, element_order,
    element_num );

  printf ( "  The FEM element order is         %d\n", element_order );
  printf ( "  The FEM element number is        %d\n", element_num );
/*
  Write the MEDIT mesh data.
*/
  dim = node_dim;
  vertices = node_num;
  edges = 0;
  triangles = element_num;
  quadrilaterals = 0;
  tetrahedrons = 0;
  hexahedrons = 0;
  vertex_coordinate = ( double * ) malloc ( dim * vertices * sizeof ( double ) );
  for ( j = 0; j < vertices; j++ )
  {
    for ( i = 0; i < dim; i++ )
    {
      vertex_coordinate[i+j*dim] = node_coord[i+j*dim];
    }
  }
  vertex_label = ( int * ) malloc ( vertices * sizeof ( int ) );
  for ( j = 0; j < vertices; j++ )
  {
    vertex_label[j] = boundary_node[j];
  }
  edge_vertex = NULL;
  edge_label = NULL;
  triangle_vertex = ( int * ) malloc ( 3 * triangles * sizeof ( int ) );
  for ( j = 0; j < triangles; j++ )
  {
    for ( i = 0; i < 3; i++ )
    {
      triangle_vertex[i+j*3] = element_node[i+j*3];
    }
  }
  triangle_label = ( int * ) malloc ( triangles * sizeof ( int ) );
  for ( j = 0; j < triangles; j++ )
  {
    triangle_label[j] = 0;
  }
  quadrilateral_vertex = NULL;
  quadrilateral_label = NULL;
  tetrahedron_vertex = NULL;
  tetrahedron_label = NULL;
  hexahedron_vertex = NULL;
  hexahedron_label = NULL;

  medit_write ( medit_filename, dim, vertices, edges, triangles, quadrilaterals,
    tetrahedrons, hexahedrons, vertex_coordinate, vertex_label, edge_vertex,
    edge_label, triangle_vertex, triangle_label, quadrilateral_vertex,
    quadrilateral_label, tetrahedron_vertex, tetrahedron_label,
    hexahedron_vertex, hexahedron_label );
/*
  Free memory.
*/
  free ( element_node );
  free ( node_coord );
  free ( boundary_node );
  free ( triangle_label );
  free ( triangle_vertex );
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "FEM_TO_MEDIT:\n" );
  printf ( "  Normal end of execution.\n" );
  printf ( "\n" );
  timestamp ( );
}
int main ( int argc, char *argv[] )

/******************************************************************************/
/*
  Purpose:

    MAIN is the main program for LEGENDRE_EXACTNESS.

  Discussion:

    This program investigates a standard Gauss-Legendre quadrature rule
    by using it to integrate monomials over [-1,1], and comparing the
    approximate result to the known exact value.

    The user specifies:
    * the "root" name of the R, W and X files that specify the rule;
    * DEGREE_MAX, the maximum monomial degree to be checked.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    15 May 2014

  Author:

    John Burkardt
*/
{
  int degree;
  int degree_max;
  int dim_num;
  int dim_num2;
  int i;
  int order;
  int point_num;
  int point_num2;
  double quad_error;
  double quad_error2;
  char quad_filename[255];
  char quad_r_filename[255];
  char quad_w_filename[255];
  char quad_x_filename[255];
  double *r;
  double *w;
  double *w2;
  double *x;
  double *x2;

  timestamp ( );
  printf ( "\n" );
  printf ( "LEGENDRE_EXACTNESS\n" );
  printf ( "  C++ version\n" );
  printf ( "\n" );
  printf ( "  Investigate the polynomial exactness of a Gauss-Legendre\n" );
  printf ( "  quadrature rule by integrating weighted\n" );
  printf ( "  monomials up to a given degree over the [-1,+1] interval.\n" );
/*
  Get the quadrature file rootname.
*/
  if ( 1 < argc )
  {
    strcpy ( quad_filename, argv[1] );
  }
  else
  {
    printf ( "\n" );
    printf ( "  Enter the quadrature file rootname:\n" );
    scanf ( "%s", quad_filename );
  }

  printf ( "\n" );
  printf ( "  The quadrature file rootname is \"%s\".\n", quad_filename );
/*
  Create the names of:
    the quadrature X file;
    the quadrature W file;
    the quadrature R file;
*/
  strcpy ( quad_w_filename, quad_filename );
  strcat ( quad_w_filename, "_w.txt" );
  strcpy ( quad_x_filename, quad_filename );
  strcat ( quad_x_filename, "_x.txt" );
  strcpy ( quad_r_filename, quad_filename );
  strcat ( quad_r_filename, "_r.txt" );
/*
  Get the maximum degree:
*/
  if ( 2 < argc )
  {
    degree_max = atoi ( argv[2] );

  }
  else
  {
    printf ( "\n" );
    printf ( "  Enter DEGREE_MAX, the maximum monomial degree to check.\n" );
    scanf ( "%d", &degree_max );
  }
/*
  Summarize the input.
*/
  printf ( "\n" );
  printf ( "LEGENDRE_EXACTNESS: User input:\n" );
  printf ( "  Quadrature rule X file = \"%s\".\n", quad_x_filename );
  printf ( "  Quadrature rule W file = \"%s\".\n", quad_w_filename );
  printf ( "  Quadrature rule R file = \"%s\".\n", quad_r_filename );
  printf ( "  Maximum degree to check = %d\n", degree_max );
/*
  Read the X file.
*/
  r8mat_header_read ( quad_x_filename, &dim_num, &order );

  if ( dim_num != 1 )
  {
    printf ( "\n" );
    printf ( "LEGENDRE_EXACTNESS - Fatal error!\n" );
    printf ( "  The spatial dimension of X should be 1.\n" );
    printf ( " The implicit input dimension was DIM_NUM = %d\n", dim_num );
    exit ( 1 );
  }

  printf ( "\n" );
  printf ( "  Spatial dimension = %d\n", dim_num );
  printf ( "  Number of points  = %d\n", order );

  x = r8mat_data_read ( quad_x_filename, dim_num, order );
/*
  Read the W file.
*/
  r8mat_header_read ( quad_w_filename, &dim_num2, &point_num );

  if ( dim_num2 != 1 )
  {
    printf ( "\n" );
    printf ( "LEGENDRE_EXACTNESS - Fatal error!\n" );
    printf ( "  The quadrature weight file should have exactly\n" );
    printf ( "  one value on each line.\n" );
    exit ( 1 );
  }

  if ( point_num != order )
  {
    printf ( "\n" );
    printf ( "LEGENDRE_EXACTNESS - Fatal error!\n" );
    printf ( "  The quadrature weight file should have exactly\n" );
    printf ( "  the same number of lines as the abscissa file.\n" );
    exit ( 1 );
  }

  w = r8mat_data_read ( quad_w_filename, dim_num, order );
/*
  Read the R file.
*/
  r8mat_header_read ( quad_r_filename, &dim_num2, &point_num2 );

  if ( dim_num2 != dim_num )
  {
    printf ( "\n" );
    printf ( "LEGENDRE_EXACTNESS - Fatal error!\n" );
    printf ( "  The quadrature region file should have the\n" );
    printf ( "  same number of values on each line as the\n" );
    printf ( "  abscissa file does.\n" );
    exit ( 1 );
  }

  if ( point_num2 != 2 )
  {
    printf ( "\n" );
    printf ( "LEGENDRE_EXACTNESS - Fatal error!\n" );
    printf ( "  The quadrature region file should have two lines.\n" );
    exit ( 1 );
  }

  r = r8mat_data_read ( quad_r_filename, dim_num, point_num2 );
/*
  Print the input quadrature rule.
*/
  printf ( "\n" );
  printf ( "  The quadrature rule to be tested is\n" );
  printf ( "  a Gauss-Legendre rule\n" );
  printf ( "  ORDER = %d\n", order );
  printf ( "\n" );
  printf ( "  Standard rule:\n" );
  printf ( "    Integral ( -1 <= x <= +1 ) f(x) dx\n" );
  printf ( "    is to be approximated by\n" );
  printf ( "    sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).\n" );
  printf ( "\n" );
  printf ( "  Weights W:\n" );
  printf ( "\n" );
  for ( i = 0; i < order; i++ )
  {
    printf ( "  w[%d] = %g\n", i, w[i] );
  }
  printf ( "\n" );
  printf ( "  Abscissas X:\n" );
  printf ( "\n" );
  for ( i = 0; i < order; i++ )
  {
    printf ( "  x[%d] = %g\n", i, x[i] );
  }
  printf ( "\n" );
  printf ( "  Region R:\n" );
  printf ( "\n" );

  for ( i = 0; i < 2; i++ )
  {
    printf ( "  r[%d] = %g\n", i, r[i] );
  }
/*
  Generate a second rule for comparison.
*/
  x2 = ( double * ) malloc ( order * sizeof ( double ) );
  w2 = ( double * ) malloc ( order * sizeof ( double ) );

  if ( order == 1 )
  {
    x2[0] = 0.0;
    w2[0] = 2.0;
  }
  else
  {
    for ( i = 0; i < order; i++ )
    {
      w2[i] = 0.0;
    }
    for ( i = 0; i < order - 1; i++ )
    {
      w2[i] = w2[i] + 1.0 / ( double ) ( order - 1 );
    }
    for ( i = 1; i < order; i++ )
    {
      w2[i] = w2[i] + 1.0 / ( double ) ( order - 1 );
    }
    for ( i = 0; i < order; i++ )
    {
      x2[i] = ( ( double ) ( order - i - 1 ) * ( -1.0 ) 
              + ( double ) (         i     ) * ( +1.0 ) ) 
              / ( double ) ( order     - 1 );
    }
  }
/*
  Explore the monomials.
*/
  printf ( "\n" );
  printf ( "  A Gauss-Legendre rule would be able to exactly\n" );
  printf ( "  integrate monomials up to and including degree = %d\n",
   2 * order - 1 );
  printf ( "\n" );
  printf ( "          Error                      Error           Degree\n" );
  printf ( "         (This rule)                (Trapezoid)\n" );
  printf ( "\n" );

  for ( degree = 0; degree <= degree_max; degree++ )
  {
    quad_error = legendre_monomial_quadrature ( degree, order, w, x );

    quad_error2 = legendre_monomial_quadrature ( degree, order, w2, x2 );

    printf ( "  %14.16g  %14.16g  %2d\n", quad_error, quad_error2, degree );
  }
/*
  Free memory.
*/
  free ( r );
  free ( w );
  free ( w2 );
  free ( x );
  free ( x2 );
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "LEGENDRE_EXACTNESS:\n" );
  printf ( "  Normal end of execution.\n" );
  printf ( "\n" );
  timestamp ( );

  return 0;
}
int main ( int argc, char *argv[] )

/******************************************************************************/
/*
  Purpose:

    MAIN is the main program for TRIANGULATION_NODE_TO_ELEMENT.

  Discussion:

    TRIANGULATION_NODE_TO_ELEMENT averages node values to an element value.

    This program is given a triangulation, along with the values of one or
    more data items associated with each node.

    It produces a file containing the average of the nodal values for 
    each element.

  Usage:

    triangulation_node_to_element ( 'prefix' )

    where

    * 'prefix'_nodes.txt contains the node coordinates;
    * 'prefix'_elements.txt contains the element definitions 
      (this file is optional, and if missing, the elements will be generated
      by the program);
    * 'prefix'_values.txt contains the nodal values.
    * 'prefix'_element_values will contain the averaged element data.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    08 April 2014

  Author:

    John Burkardt
*/
{
  int dim_num;
  char element_filename[255];
  int *element_node;
  int element_num;
  int element_order;
  double *element_value;
  char element_value_filename[255];
  int i;
  int j;
  int k;
  int ni;
  char node_filename[255];
  int node_num;
  double *node_xy;
  char prefix[255];
  int value_dim;
  char value_filename[255];
  int value_num;
  double *value;

  timestamp ( );
  printf ( "\n" );
  printf ( "TRIANGULATION_NODE_TO_ELEMENT:\n" );
  printf ( "  C version:\n" );
  printf ( "  Average nodal data to create element data.\n" );
  printf ( "\n" );
  printf ( "  This program expects three files:\n" );
  printf ( "  * prefix_nodes.txt,    node coordinates,\n" );
  printf ( "  * prefix_elements.txt, indices of nodes forming elements,\n" );
  printf ( "  * prefix_values.txt,   data values at nodes,\n" );
  printf ( "  and creates:\n" );
  printf ( "  * prefix_element_values.txt, averaged data at elements.\n" );
/*
  Get the filename prefix.
*/
  if ( argc <= 1 ) 
  {
    printf ( "\n" );
    printf ( "  Please enter the filename prefix.\n" );

    scanf ( "%s", prefix );
  }
  else 
  {
    strcpy ( prefix, argv[1] );
  }
/*
  Create the filenames.
*/
  strcpy ( node_filename, prefix );
  strcat ( node_filename, "_nodes.txt" );
  strcpy ( element_filename, prefix );
  strcat ( element_filename, "_elements.txt" );
  strcpy ( value_filename, prefix );
  strcat ( value_filename, "_values.txt" );
  strcpy ( element_value_filename, prefix );
  strcat ( element_value_filename, "_element_values.txt" );
/*
  Read the node data.
*/
  r8mat_header_read ( node_filename, &dim_num, &node_num );

  printf ( "\n" );
  printf ( "  Read the header of \"%s\".\n", node_filename );
  printf ( "\n" );
  printf ( "  Spatial dimension DIM_NUM = %d\n", dim_num );
  printf ( "  Number of nodes NODE_NUM  = %d\n", node_num );

  node_xy = r8mat_data_read ( node_filename, dim_num, node_num );

  printf ( "\n" );
  printf ( "  Read the data in \"%s\".\n", node_filename );

  r8mat_transpose_print_some ( dim_num, node_num, node_xy, 1, 1, dim_num, 5, 
    "  Portion of coordinate data from file:" );
/*
  Read the element data.
*/
  i4mat_header_read ( element_filename, &element_order, &element_num );

  printf ( "\n" );
  printf ( " Read the header of \"%s\".\n", element_filename );
  printf ( "\n" );
  printf ( "  Element order ELEMENT_ORDER = %d\n", element_order );
  printf ( "  Number of elements ELEMENT_NUM  = %d\n", element_num );

  element_node = i4mat_data_read ( element_filename, element_order, element_num );

  printf ( "\n" );
  printf ( "  Read the data in \"%s\".\n", element_filename );

  i4mat_transpose_print_some ( element_order, element_num, element_node, 1, 1, 
    element_order, 5, "  Portion of data read from file:" );
/*
  Read the node value data.
*/
  r8mat_header_read ( value_filename, &value_dim, &value_num );

  printf ( "\n" );
  printf ( "  Read the header of \"%s\".\n", value_filename );
  printf ( "\n" );
  printf ( "  Value dimension VALUE_DIM = %d\n", value_dim );
  printf ( "  Number of values VALUE_NUM  = %d\n", value_num );

  value = r8mat_data_read ( value_filename, value_dim, value_num );

  printf ( "\n" );
  printf ( "  Read the data in \"%s\".\n", value_filename );

  r8mat_transpose_print_some ( value_dim, value_num, value, 1, 1, value_dim, 5, 
    "  First 5 node values:" );
/*
  Detect and correct 1-based node indexing.
*/
  mesh_base_zero ( node_num, element_order, element_num, element_node );
/*
  Create the element values data.
*/
  element_value = ( double * ) malloc ( value_dim * element_num * sizeof ( double ) );

  for ( j = 0; j < element_num; j++ )
  {
    for ( i = 0; i < value_dim; i++ )
    {
      element_value[i+j*value_dim] = 0.0;
    }
  }

  for ( j = 0; j < element_num; j++ )
  {
    for ( i = 0; i < element_order; i++ )
    {
      ni = element_node[i+j*element_order];
      for ( k = 0; k < value_dim; k++ )
      {
        element_value[k+j*value_dim] = element_value[k+j*value_dim] 
          + value[k+ni*value_dim];
      }
    }
  }

  for ( j = 0; j < element_num; j++ )
  {
    for ( k = 0; k < value_dim; k++ )
    {
      element_value[k+j*value_dim] = element_value[k+j*value_dim] 
        / ( double ) ( element_order );
    }
  }
/*
  Write out the file.
*/
  r8mat_write ( element_value_filename, value_dim, element_num, element_value );

  printf ( "\n" );
  printf ( "  Element values written to '%s'\n", element_value_filename );
/*
  Free memory.
*/
  free ( element_node );
  free ( element_value );
  free ( node_xy );
  free ( value );
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "TRIANGULATION_NODE_TO_ELEMENT:\n" );
  printf ( "  Normal end of execution.\n" );

  printf ( "\n" );
  timestamp ( );

  return 0;
}
int main ( int argc, char *argv[] )

/******************************************************************************/
/*
  Purpose:

    MAIN is the main program for HYPERCUBE_EXACTNESS.

  Usage:

    hypercube_exactness prefix degree_max

    where

    * prefix is the common prefix for the files containing the abscissa,
      weight and region information;
    * degree_max is the maximum total monomial degree to check.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    30 August 2014

  Author:

    John Burkardt
*/
{
  int degree;
  int degree_max;
  int dim;
  int dim_num;
  int dim_num2;
  int error;
  int *expon;
  int h;
  int last;
  int more;
  int point;
  int point_num;
  int point_num2;
  char prefix[255];
  double quad_error;
  char quad_r_filename[255];
  char quad_w_filename[255];
  char quad_x_filename[255];
  int t;
  double volume;
  double *weight;
  double *x;
  double *x_range;

  timestamp ( );
  printf ( "\n" );
  printf ( "HYPERCUBE_EXACTNESS\n" );
  printf ( "  C version\n" );
  printf ( "\n" );
  printf ( "  Investigate the polynomial exactness of a quadrature\n" );
  printf ( "  rule by integrating all monomials of a given degree\n" );
  printf ( "  over the [0,1] hypercube.\n" );
  printf ( "\n" );
  printf ( "  The rule will be adjusted to the [0,1] hypercube.\n" );
/*
  Get the quadrature file root name:
*/
  if ( 1 < argc )
  {
    strcpy ( prefix, argv[1] );
  }
  else
  {
    printf ( "\n" );
    printf ( "HYPERCUBE_EXACTNESS:\n" );
    printf ( "  Enter the \"root\" name of the quadrature files.\n" );

    scanf ( "%s", prefix );
  }
/*
  Construct appropriate file names.
*/
  strcpy ( quad_r_filename, prefix );
  strcat ( quad_r_filename, "_r.txt" );

  strcpy ( quad_w_filename, prefix );
  strcat ( quad_w_filename, "_w.txt" );

  strcpy ( quad_x_filename, prefix );
  strcat ( quad_x_filename, "_x.txt" );
/*
  The second command line argument is the maximum degree.
*/
  if ( 2 < argc )
  {
    degree_max = s_to_i4 ( argv[2], &last, &error );
  }
  else
  {
    printf ( "\n" );
    printf ( "HYPERCUBE_EXACTNESS:\n" );
    printf ( "  Please enter the maximum total degree to check.\n" );

    scanf ( "%d", &degree_max );
  }
/*
  Summarize the input.
*/
  printf ( "\n" );
  printf ( "HYPERCUBE_EXACTNESS: User input:\n" );
  printf ( "  Quadrature rule X file = \"%s\"\n", quad_x_filename );
  printf ( "  Quadrature rule W file = \"%s\"\n", quad_w_filename );
  printf ( "  Quadrature rule R file = \"%s\"\n", quad_r_filename );
  printf ( "  Maximum total degree to check = %d\n", degree_max );
/*
  Read the X file.
*/
  r8mat_header_read ( quad_x_filename, &dim_num, &point_num );

  printf ( "\n" );
  printf ( "  Spatial dimension = %d\n", dim_num );
  printf ( "  Number of points  = %d\n", point_num );

  x = r8mat_data_read ( quad_x_filename, dim_num, point_num );
/*
  Read the W file.
*/
  r8mat_header_read ( quad_w_filename, &dim_num2, &point_num2 );

  if ( dim_num2 != 1 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "HYPERCUBE_EXACTNESS - Fatal error!\n" );
    fprintf ( stderr, "  The quadrature weight file should have exactly\n" );
    fprintf ( stderr, "  one value on each line.\n" );
    exit ( 1 );
  }

  if ( point_num2 != point_num )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "HYPERCUBE_EXACTNESS - Fatal error!\n" );
    fprintf ( stderr, "  The quadrature weight file should have exactly\n" );
    fprintf ( stderr, "  the same number of lines as the abscissa file.\n" );
    exit ( 1 );
  }

  weight = r8mat_data_read ( quad_w_filename, 1, point_num );
/*
  Read the R file.
*/
  r8mat_header_read ( quad_r_filename, &dim_num2, &point_num2 );

  if ( dim_num2 != dim_num )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "HYPERCUBE_EXACTNESS - Fatal error!\n" );
    fprintf ( stderr, "  The quadrature region file should have the same\n" );
    fprintf ( stderr, "  number of values on each line as the abscissa file\n" );
    fprintf ( stderr, "  does.\n" );
    exit ( 1 );
  }

  if ( point_num2 != 2 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "HYPERCUBE_EXACTNESS - Fatal error!\n" );
    fprintf ( stderr, "  The quadrature region file should have two lines.\n" );
    exit ( 1 );
  }

  x_range = r8mat_data_read ( quad_r_filename, dim_num, 2 );
/*
  Rescale the weights, and translate the abscissas.
*/
  volume = 1.0;
  for ( dim = 0; dim < dim_num; dim++ )
  {
    volume = volume * ( x_range[dim+1*dim_num] - x_range[dim+0*dim_num] );
  }
  volume = fabs ( volume );

  for ( point = 0; point < point_num; point++ )
  {
    weight[point] = weight[point] / volume;
  }

  for ( dim = 0; dim < dim_num; dim++ )
  {
    for ( point = 0; point < point_num; point++ )
    {
      x[dim+point*dim_num] =
          ( x[dim+point*dim_num]   - x_range[dim+0*dim_num] )
        / ( x_range[dim+1*dim_num] - x_range[dim+0*dim_num] );
    }
  }
/*
  Explore the monomials.
*/
  expon = ( int * ) malloc ( dim_num * sizeof ( int ) );

  printf ( "\n" );
  printf ( "      Error    Degree  Exponents\n" );
  printf ( "\n" );

  for ( degree = 0; degree <= degree_max; degree++ )
  {
    more = 0;
    h = 0;
    t = 0;

    for ( ; ; )
    {
      comp_next ( degree, dim_num, expon, &more, &h, &t );

      quad_error = monomial_quadrature ( dim_num, expon, point_num, weight, x );

      printf ( "  %12g     %2d  ", quad_error, degree );

      for ( dim = 0; dim < dim_num; dim++ )
      {
        printf ( "%3d", expon[dim] );
      }
      printf ( "\n" );

      if ( !more )
      {
        break;
      }
    }
    printf ( "\n" );
  }
/*
  Free memory.
*/
  free ( expon );
  free ( weight );
  free ( x );
  free ( x_range );
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "HYPERCUBE_EXACTNESS:\n" );
  printf ( "  Normal end of execution.\n" );
  printf ( "\n" );
  timestamp ( );

  return 0;
}