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", °ree_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; }