# include # include # include # include # include # include # include using namespace std; int main ( int argc, char *argv[] ); char ch_cap ( char ch ); bool ch_eqi ( char ch1, char ch2 ); int ch_to_digit ( char ch ); void chebyshev2_compute ( int order, double xtab[], double weight[] ); void chebyshev2_handle ( int order, char *output ); void dtable_close_write ( ofstream &output ); void dtable_data_write ( ofstream &output, int m, int n, double table[] ); void dtable_header_write ( char *output_filename, ofstream &output, int m, int n ); void dtable_write ( char *output_filename, int m, int n, double table[], bool header ); double r8_epsilon ( void ); bool s_eqi ( char *s1, char *s2 ); void timestamp ( void ); char *timestring ( void ); //****************************************************************************80 int main ( int argc, char *argv[] ) //****************************************************************************80 // // Purpose: // // MAIN is the main program for CHEBYSHEV2_RULE. // // Discussion: // // This program computes a standard Gauss-Chebyshev type 2 quadrature rule // and writes it to a file. // // The user specifies: // * the ORDER (number of points) in the rule // * the OUTPUT option. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 01 March 2008 // // Author: // // John Burkardt // { int order; char output[81]; timestamp ( ); cout << "\n"; cout << "CHEBYSHEV2_RULE\n"; cout << " C++ version\n"; cout << "\n"; cout << " Compiled on " << __DATE__ << " at " << __TIME__ << ".\n"; cout << "\n"; cout << " Compute a Gauss-Chebyshev type 2 rule for approximating\n"; cout << "\n"; cout << " Integral ( -1 <= x <= +1 ) f(x) * sqrt ( 1 - x^2 ) dx\n"; cout << "\n"; cout << " of order ORDER.\n"; cout << "\n"; cout << " The user specifies ORDER and OUTPUT.\n"; cout << "\n"; cout << " OUTPUT is:\n"; cout << "\n"; cout << " \"C++\" for printed C++ output;\n"; cout << " \"F77\" for printed Fortran77 output;\n"; cout << " \"F90\" for printed Fortran90 output;\n"; cout << " \"MAT\" for printed MATLAB output;\n"; cout << "\n"; cout << " or:\n"; cout << "\n"; cout << " \"filename\" to generate 3 files:\n"; cout << "\n"; cout << " filename_w.txt - the weight file\n"; cout << " filename_x.txt - the abscissa file.\n"; cout << " filename_r.txt - the region file.\n"; // // Get the order. // if ( 1 < argc ) { order = atoi ( argv[1] ); } else { cout << "\n"; cout << " Enter the value of ORDER (1 or greater)\n"; cin >> order; } cout << "\n"; cout << " The requested order of the rule is = " << order << "\n"; // // Get the output option or quadrature file root name: // if ( 2 < argc ) { strcpy ( output, argv[2] ); } else { cout << "\n"; cout << " Enter OUTPUT (one of C++, F77, F90, MAT\n"; cout << " or else the \"root name\" of the quadrature files).\n"; cin >> output; } cout << "\n"; cout << " OUTPUT option is \"" << output << "\".\n"; // // Construct the rule and output it. // chebyshev2_handle ( order, output ); cout << "\n"; cout << "CHEBYSHEV2_RULE:\n"; cout << " Normal end of execution.\n"; cout << "\n"; timestamp ( ); return 0; } //****************************************************************************80 char ch_cap ( char ch ) //****************************************************************************80 // // Purpose: // // CH_CAP capitalizes a single character. // // Discussion: // // This routine should be equivalent to the library "toupper" function. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Input, char CH, the character to capitalize. // // Output, char CH_CAP, the capitalized character. // { if ( 97 <= ch && ch <= 122 ) { ch = ch - 32; } return ch; } //****************************************************************************80 bool ch_eqi ( char ch1, char ch2 ) //****************************************************************************80 // // Purpose: // // CH_EQI is true if two characters are equal, disregarding case. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Input, char CH1, CH2, the characters to compare. // // Output, bool CH_EQI, is true if the two characters are equal, // disregarding case. // { if ( 97 <= ch1 && ch1 <= 122 ) { ch1 = ch1 - 32; } if ( 97 <= ch2 && ch2 <= 122 ) { ch2 = ch2 - 32; } return ( ch1 == ch2 ); } //****************************************************************************80 int ch_to_digit ( char ch ) //****************************************************************************80 // // Purpose: // // CH_TO_DIGIT returns the integer value of a base 10 digit. // // Example: // // CH DIGIT // --- ----- // '0' 0 // '1' 1 // ... ... // '9' 9 // ' ' 0 // 'X' -1 // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Input, char CH, the decimal digit, '0' through '9' or blank are legal. // // Output, int CH_TO_DIGIT, the corresponding integer value. If the // character was 'illegal', then DIGIT is -1. // { int digit; if ( '0' <= ch && ch <= '9' ) { digit = ch - '0'; } else if ( ch == ' ' ) { digit = 0; } else { digit = -1; } return digit; } //****************************************************************************80 void chebyshev2_compute ( int order, double x[], double w[] ) //****************************************************************************80 // // Purpose: // // CHEBYSHEV2_COMPUTE computes a Gauss-Chebyshev type 2 quadrature rule. // // Discussion: // // The integration interval is [ -1, 1 ]. // // The weight function is w(x) = sqrt ( 1 - x^2 ). // // The integral to approximate: // // Integral ( -1 <= X <= 1 ) F(X) sqrt ( 1 - x^2 ) dX // // The quadrature rule: // // Sum ( 1 <= I <= ORDER ) WEIGHT(I) * F ( XTAB(I) ) // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 26 February 2008 // // Author: // // John Burkardt // // Reference: // // Philip Davis, Philip Rabinowitz, // Methods of Numerical Integration, // Second Edition, // Dover, 2007, // ISBN: 0486453391, // LC: QA299.3.D28. // // Parameters: // // Input, int ORDER, the order of the rule. // ORDER must be greater than 0. // // Output, double X[ORDER], the abscissas. // // Output, double W[ORDER], the weights. // { double angle; int i; double pi = 3.141592653589793; if ( order < 1 ) { cout << "\n"; cout << "CHEBYSHEV2_COMPUTE - Fatal error!\n"; cout << " Illegal value of ORDER = " << order << "\n"; exit ( 1 ); } for ( i = 0; i < order; i++ ) { angle = pi * ( double ) ( order - i ) / ( double ) ( order + 1 ); w[i] = pi / ( double ) ( order + 1 ) * pow ( sin ( angle ), 2 ); x[i] = cos ( angle ); } return; } //****************************************************************************80 void chebyshev2_handle ( int order, char *output ) //****************************************************************************80 // // Purpose: // // CHEBYSHEV2_HANDLE handles the requested Gauss-Chebyshev type 2 rule. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 01 March 2008 // // Author: // // John Burkardt // // Parameters: // // Input, int ORDER, the order of the rule. // // Input, char *OUTPUT, specifies the output. // * "C++'", print as C++ code. // * "F77", print as FORTRAN77 code. // * "F90", print as FORTRAN90 code. // * "MAT", print as MATLAB code. // * file, write files "file_w.txt", "file_x.txt", "file_r.txt" // defining weights, abscissas, and region. // { bool header; int i; char output_r[81]; char output_w[81]; char output_x[81]; double *r; double *w; double *x; r = new double[2]; w = new double[order]; x = new double[order]; r[0] = - 1.0; r[1] = + 1.0; chebyshev2_compute ( order, x, w ); if ( s_eqi ( output, "C++" ) ) { cout << "//\n"; cout << "// Weights W, abscissas X and range R\n"; cout << "// for a Gauss-Chebyshev type 2 quadrature rule.\n"; cout << "// ORDER = " << order << "\n"; cout << "//\n"; cout << "// Standard rule:\n"; cout << "// Integral ( -1 <= x <= +1 ) f(x) * sqrt ( 1 - x^2 ) dx\n"; cout << "// is to be approximated by\n"; cout << "// sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).\n"; cout << "//\n"; for ( i = 0; i < order; i++ ) { cout << " w[" << i << "] = " << setprecision(16) << w[i] << ";\n"; } cout << "\n"; for ( i = 0; i < order; i++ ) { cout << " x[" << i << "] = " << setprecision(16) << x[i] << ";\n"; } cout << "\n"; for ( i = 0; i < 2; i++ ) { cout << " r[" << i << "] = " << r[i] << ";\n"; } } else if ( s_eqi ( output, "F77" ) ) { cout << "c\n"; cout << "c Weights W, abscissas X and range R\n"; cout << "c for a Gauss-Chebyshev type 2 quadrature rule.\n"; cout << "c ORDER = " << order << "\n"; cout << "c\n"; cout << "c Standard rule:\n"; cout << "c Integral ( -1 <= x <= +1 ) f(x) * sqrt ( 1 - x^2 ) dx\n"; cout << "c is to be approximated by\n"; cout << "c sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).\n"; cout << "c\n"; for ( i = 0; i < order; i++ ) { cout << " w(" << i + 1 << ") = " << setprecision(16) << w[i] << "\n"; } cout << "\n"; for ( i = 0; i < order; i++ ) { cout << " x(" << i + 1 << ") = " << setprecision(16) << x[i] << "\n"; } cout << "\n"; for ( i = 0; i < 2; i++ ) { cout << " r(" << i + 1 << ") = " << r[i] << "\n"; } } else if ( s_eqi ( output, "F90" ) ) { cout << "!\n"; cout << "! Weights W, abscissas X and range R\n"; cout << "! for a Gauss-Chebyshev type 2 quadrature rule.\n"; cout << "! ORDER = " << order << "\n"; cout << "!\n"; cout << "! Standard rule:\n"; cout << "! Integral ( -1 <= x <= +1 ) f(x) * sqrt ( 1 - x^2 ) dx\n"; cout << "! is to be approximated by\n"; cout << "! sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).\n"; cout << "!\n"; for ( i = 0; i < order; i++ ) { cout << " w(" << i + 1 << ") = " << setprecision(16) << w[i] << "\n"; } cout << "\n"; for ( i = 0; i < order; i++ ) { cout << " x(" << i + 1 << ") = " << setprecision(16) << x[i] << "\n"; } cout << "\n"; for ( i = 0; i < 2; i++ ) { cout << " r(" << i + 1 << ") = " << r[i] << "\n"; } } else if ( s_eqi ( output, "MAT" ) ) { cout << "%\n"; cout << "% Weights W, abscissas X and range R\n"; cout << "% for a Gauss-Chebyshev type 2 quadrature rule.\n"; cout << "% ORDER = " << order << "\n"; cout << "%\n"; cout << "% Standard rule:\n"; cout << "% Integral ( -1 <= x <= +1 ) f(x) * sqrt ( 1 - x^2 ) dx\n"; cout << "% is to be approximated by\n"; cout << "% sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).\n"; cout << "%\n"; for ( i = 0; i < order; i++ ) { cout << " w(" << i + 1 << ") = " << setprecision(16) << w[i] << ";\n"; } cout << "\n"; for ( i = 0; i < order; i++ ) { cout << " x(" << i + 1 << ") = " << setprecision(16) << x[i] << ";\n"; } cout << "\n"; for ( i = 0; i < 2; i++ ) { cout << " r(" << i + 1 << ") = " << r[i] << ";\n"; } } else { sprintf ( output_w, "%s_w.txt", output ); sprintf ( output_x, "%s_x.txt", output ); sprintf ( output_r, "%s_r.txt", output ); cout << "\n"; cout << " Creating quadrature files.\n"; cout << "\n"; cout << " Root file name is \"" << output << "\".\n"; cout << "\n"; cout << " Weight file will be \"" << output_w << "\".\n"; cout << " Abscissa file will be \"" << output_x << "\".\n"; cout << " Region file will be \"" << output_r << "\".\n"; header = false; dtable_write ( output_w, 1, order, w, header ); dtable_write ( output_x, 1, order, x, header ); dtable_write ( output_r, 1, 2, r, header ); } delete [] r; delete [] w; delete [] x; return; } //****************************************************************************80 void dtable_close_write ( ofstream &output ) //****************************************************************************80 // // Purpose: // // DTABLE_CLOSE_WRITE closes a file to which a DTABLE was to be written. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Input, ofstream output, the output file stream. // { output.close ( ); return; } //****************************************************************************80 void dtable_data_write ( ofstream &output, int m, int n, double table[] ) //****************************************************************************80 // // Purpose: // // DTABLE_DATA_WRITE writes data to a DTABLE file. // // Discussion: // // The file should already be open. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Input, ofstream &OUTPUT, a pointer to the output stream. // // Input, int M, the spatial dimension. // // Input, int N, the number of points. // // Input, double TABLE[M*N], the table data. // { int i; int j; char *s; for ( j = 0; j < n; j++ ) { for ( i = 0; i < m; i++ ) { output << setprecision(16) << setw(24) << table[i+j*m] << " "; } output << "\n"; } output.close ( ); return; } //****************************************************************************80 void dtable_header_write ( char *output_filename, ofstream &output, int m, int n ) //****************************************************************************80 // // Purpose: // // DTABLE_HEADER_WRITE writes the header of a DTABLE file. // // Discussion: // // The file should already be open. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Input, char *OUTPUT_FILENAME, the output filename. // // Input, ofstream &OUTPUT, the output stream. // // Input, int M, the spatial dimension. // // Input, int N, the number of points. // { char *s; s = timestring ( ); output << "# " << output_filename << "\n"; output << "# created by dtable_write in table_io.C" << "\n"; output << "# at " << s << "\n"; output << "#\n"; output << "# Spatial dimension M = " << m << "\n"; output << "# Number of points N = " << n << "\n"; output << "# EPSILON (unit roundoff) = " << r8_epsilon ( ) << "\n"; output << "#\n"; delete [] s; return; } //****************************************************************************80 void dtable_write ( char *output_filename, int m, int n, double table[], bool header ) //****************************************************************************80 // // Purpose: // // DTABLE_WRITE writes information to a DTABLE file. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Input, char *OUTPUT_FILENAME, the output filename. // // Input, int M, the spatial dimension. // // Input, int N, the number of points. // // Input, double TABLE[M*N], the table data. // // Input, bool HEADER, is TRUE if the header is to be included. // { ofstream output; output.open ( output_filename ); if ( !output ) { cout << "\n"; cout << "DTABLE_WRITE - Fatal error!\n"; cout << " Could not open the output file.\n"; return; } if ( header ) { dtable_header_write ( output_filename, output, m, n ); } dtable_data_write ( output, m, n, table ); dtable_close_write ( output ); return; } //****************************************************************************80 double r8_epsilon ( void ) //****************************************************************************80 // // Purpose: // // R8_EPSILON returns the R8 roundoff unit. // // Discussion: // // The roundoff unit is a number R which is a power of 2 with the // property that, to the precision of the computer's arithmetic, // 1 < 1 + R // but // 1 = ( 1 + R / 2 ) // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Output, double R8_EPSILON, the R8 round-off unit. // { double value; value = 1.0; while ( 1.0 < ( double ) ( 1.0 + value ) ) { value = value / 2.0; } value = 2.0 * value; return value; } //****************************************************************************80 bool s_eqi ( char *s1, char *s2 ) //****************************************************************************80 // // Purpose: // // S_EQI reports whether two strings are equal, ignoring case. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Input, char *S1, char *S2, pointers to two strings. // // Output, bool S_EQI, is true if the strings are equal. // { int i; int nchar; int nchar1; int nchar2; nchar1 = strlen ( s1 ); nchar2 = strlen ( s2 ); if ( nchar1 < nchar2 ) { nchar = nchar1; } else { nchar = nchar2; } // // The strings are not equal if they differ over their common length. // for ( i = 0; i < nchar; i++ ) { if ( ch_cap ( s1[i] ) != ch_cap ( s2[i] ) ) { return false; } } // // The strings are not equal if the longer one includes nonblanks // in the tail. // if ( nchar < nchar1 ) { for ( i = nchar; i < nchar1; i++ ) { if ( s1[i] != ' ' ) { return false; } } } else if ( nchar < nchar2 ) { for ( i = nchar; i < nchar2; i++ ) { if ( s2[i] != ' ' ) { return false; } } } return true; } //****************************************************************************80 void timestamp ( void ) //****************************************************************************80 // // Purpose: // // TIMESTAMP prints the current YMDHMS date as a time stamp. // // Example: // // 31 May 2001 09:45:54 AM // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // None // { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; size_t len; time_t now; now = time ( NULL ); tm = localtime ( &now ); len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); cout << time_buffer << "\n"; return; # undef TIME_SIZE } //****************************************************************************80 char *timestring ( void ) //****************************************************************************80 // // Purpose: // // TIMESTRING returns the current YMDHMS date as a string. // // Example: // // 31 May 2001 09:45:54 AM // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 15 January 2008 // // Author: // // John Burkardt // // Parameters: // // Output, char *TIMESTRING, a string containing the current YMDHMS date. // { # define TIME_SIZE 40 const struct tm *tm; size_t len; time_t now; char *s; now = time ( NULL ); tm = localtime ( &now ); s = new char[TIME_SIZE]; len = strftime ( s, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); return s; # undef TIME_SIZE }