int strStr(char *haystack, char *needle) {
     
     int m = strlen(needle);
     int n = strlen(haystack);
     int *next = new int[m];
     
     comp_next(needle, next);
     
     int i=0, j=0;
     while(i < n && j < m)
     {
         if(j == -1 || haystack[i] == needle[j])
         {
             i++;
             j++;
         }
         else
         {
             j = next[j];
         }
     }
     delete next;
     if(j == m)
         return i-m;
     else
         return -1;
 }
void test05 ( int dim_num, int level_max, int degree_max )

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

    TEST05 tests a Clenshaw Curtis sparse grid rule for monomial exactness.

  Discussion:

    This test is going to check EVERY monomial of total degree DEGREE_MAX
    or less.  Even for a moderately high dimension of DIM_NUM = 10, you
    do NOT want to use a large value of DEGREE_MAX, since there are

      1         monomials of total degree 0,
      DIM_NUM   monomials of total degree 1,
      DIM_NUM^2 monomials of total degree 2,
      DIM_NUM^3 monomials of total degree 3, and so on.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    12 March 2013

  Author:

    John Burkardt

  Parameters:

    Input, int DIM_NUM, the spatial dimension.

    Input, int LEVEL_MAX, the level.

    Input, int DEGREE_MAX, the maximum monomial total degree to check.
*/
{
  int degree;
  int dim;
  int error;
  int *expon;
  double *grid_point;
  double *grid_weight;
  int h;
  int last;
  int more;
  int point;
  int point_num;
  double quad_error;
  int t;
  double volume;

  printf ( "\n" );
  printf ( "TEST05\n" );
  printf ( "  Check the exactness of a Clenshaw Curtis sparse grid quadrature rule,\n" );
  printf ( "  applied to all monomials of orders 0 to DEGREE_MAX.\n" );
  printf ( "\n" );
  printf ( "  LEVEL_MAX = %d\n", level_max );
  printf ( "  Spatial dimension DIM_NUM = %d\n", dim_num );
  printf ( "\n" );
  printf ( "  The maximum total degree to be checked is DEGREE_MAX = %d\n", degree_max );
  printf ( "\n" );
  printf ( "  We expect this rule to be accurate up to and including total degree %d\n", 
	   2 * level_max + 1 );
/*
  Determine the number of points in the rule.
*/
  point_num = sparse_grid_cfn_size ( dim_num, level_max );

  printf ( "\n" );
  printf ( "  Number of unique points in the grid = %d\n", point_num );
/*
  Allocate space for the weights and points.
*/
  grid_weight = ( double * ) malloc ( point_num * sizeof ( double ) );
  grid_point = ( double * ) malloc ( dim_num * point_num * sizeof ( double ) );
/*
  Compute the weights and points.
*/
  sparse_grid_cc ( dim_num, level_max, point_num, grid_weight, 
  grid_point );
/*
  Rescale the weights, and translate the abscissas.
*/
  volume = pow ( 2.0, dim_num );

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

  for ( dim = 0; dim < dim_num; dim++ )
  {
    for ( point = 0; point < point_num; point++ )
    {
      grid_point[dim+point*dim_num] = ( grid_point[dim+point*dim_num] + 1.0 ) 
      / 2.0; 
    }
  }
/*
  Explore the monomials.
*/
  expon = ( int * ) malloc ( dim_num * sizeof ( int ) );

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

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

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

      quad_error = monomial_quadrature ( dim_num, expon, point_num, 
        grid_weight, grid_point );

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

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

      if ( !more )
      {
        break;
      }
    }
    printf ( "\n" );
  }

  free ( expon );
  free ( grid_point );
  free ( grid_weight );

  return;
}
void subcomp_next ( int n, int k, int a[], int *more, int *h, int *t )

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

    SUBCOMP_NEXT computes the next subcomposition of N into K parts.

  Discussion:

    A composition of the integer N into K parts is an ordered sequence
    of K nonnegative integers which sum to a value of N.

    A subcomposition of the integer N into K parts is a composition
    of M into K parts, where 0 <= M <= N.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    27 March 2009

  Author:

    Original FORTRAN77 version by Albert Nijenhuis, Herbert Wilf.
    C version by John Burkardt.

  Reference:

    Albert Nijenhuis, Herbert Wilf,
    Combinatorial Algorithms for Computers and Calculators,
    Second Edition,
    Academic Press, 1978,
    ISBN: 0-12-519260-6,
    LC: QA164.N54.

  Parameters:

    Input, int N, the integer whose subcompositions are desired.

    Input, int K, the number of parts in the subcomposition.

    Input/output, int A[K], the parts of the subcomposition.

    Input/output, int *MORE, set by the user to start the computation,
    and by the routine to terminate it.

    Input/output, int *H, *T, two internal parameters needed for the
    computation.  The user should allocate space for these in the calling
    program, include them in the calling sequence, but never alter them!
*/
{
  int i;
  static int more2 = 0;
  static int n2 = 0;
/*
  The first computation.
*/
  if ( !( *more ) )
  {
    n2 = 0;

    for ( i = 0; i < k; i++ )
    {
      a[i] = 0;
    }
    more2 = 0;
    *h = 0;
    *t = 0;

    *more = 1;
  }
/*
  Do the next element at the current value of N.
*/
  else if ( more2 )
  {
    comp_next ( n2, k, a, &more2, h, t );
  }
  else
  {
    more2 = 0;
    n2 = n2 + 1;

    comp_next ( n2, k, a, &more2, h, t );
  }
/*
  Termination occurs if MORE2 = FALSE and N2 = N.
*/
  if ( !more2 && n2 == n )
  {
    *more = 0;
  }

  return;
}
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;
}