# include # include # include # include # include # include # include # include using namespace std; # include "newton_interp_1d.hpp" # include "test_interp.hpp" int main ( ); void newton_coef_1d_test ( ); void newton_value_1d_test ( ); void newton_interp_1d_test01 ( int prob ); string i4_to_string ( int i4 ); double *r8mat_copy_new ( int m, int n, double a1[] ); double *r8vec_copy_new ( int n, double a1[] ); double *r8vec_linspace_new ( int n, double a, double b ); double r8vec_max ( int n, double r8vec[] ); double r8vec_min ( int n, double r8vec[] ); double r8vec_norm_affine ( int n, double v0[], double v1[] ); void r8vec_print ( int n, double a[], string title ); void r8vec2_print ( int n, double a1[], double a2[], string title ); void timestamp ( ); //****************************************************************************80 int main ( ) //****************************************************************************80 // // Purpose: // // newton_interp_1d_test() tests newton_interp_1d(). // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 30 September 2022 // // Author: // // John Burkardt // { int prob; int prob_num; timestamp ( ); cout << "\n"; cout << "newton_interp_1d_test():\n"; cout << " C++ version\n"; cout << " Test newton_interp_1d().\n"; cout << " This test needs the test_interp() library.\n"; newton_coef_1d_test ( ); newton_value_1d_test ( ); prob_num = p00_prob_num ( ); for ( prob = 1; prob <= prob_num; prob++ ) { newton_interp_1d_test01 ( prob ); } // // Terminate. // cout << "\n"; cout << "newton_interp_1d_test():\n"; cout << " Normal end of execution.\n"; cout << "\n"; timestamp ( ); return 0; } //****************************************************************************80 void newton_coef_1d_test ( ) //****************************************************************************80 // // Purpose: // // newton_coef_1d_test() tests newton_coef_1d(). // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 10 July 2015 // // Author: // // John Burkardt // { double *cd; int nd = 5; double xd[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 }; double yd[5] = { 24.0, 0.0, 0.0, 0.0, 0.0 }; cout << "\n"; cout << "newton_coef_1d_test():\n"; cout << " newton_coef_1d() sets the coefficients for a 1D Newton interpolation.\n"; r8vec2_print ( nd, xd, yd, " Interpolation data:" ); cd = newton_coef_1d ( nd, xd, yd ); r8vec_print ( nd, cd, " Newton interpolant coefficients:" ); delete [] cd; return; } //****************************************************************************80 void newton_value_1d_test ( ) //****************************************************************************80 // // Purpose: // // newton_value_1d_test() tests newton_value_1d(). // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 10 July 2015 // // Author: // // John Burkardt // { double cd[5] = { 24.0, -24.0, +12.0, -4.0, 1.0 }; int nd = 5; int ni = 16; double x_hi; double x_lo; double xd[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 }; double *xi; double *yi; cout << "\n"; cout << "newton_value_1d_test():\n"; cout << " newton_value_1d() evaluates a Newton 1d interpolant.\n"; r8vec2_print ( nd, xd, cd, " The Newton interpolant data:" ); x_lo = 0.0; x_hi = 5.0; xi = r8vec_linspace_new ( ni, x_lo, x_hi ); yi = newton_value_1d ( nd, xd, cd, ni, xi ); r8vec2_print ( ni, xi, yi, " Newton interpolant values:" ); delete [] xi; delete [] yi; return; } //****************************************************************************80 void newton_interp_1d_test01 ( int prob ) //****************************************************************************80 // // Purpose: // // newton_interp_1d_test01() tests newton_interp_1d(). // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 10 July 2015 // // Author: // // John Burkardt // { double *cd; string command_filename; ofstream command_unit; string data_filename; ofstream data_unit; int i; double interp_error; string interp_filename; ofstream interp_unit; int j; double ld; double li; int nd; int ni; string output_filename; string title; double *xd; double *xi; double xmax; double xmin; double *xy; double *yd; double *yi; double ymax; double ymin; cout << "\n"; cout << "newton_interp_1d_test01():\n"; cout << " Interpolate data from test_interp() problem #" << prob << "\n"; nd = p00_data_num ( prob ); cout << " Number of data points = " << nd << "\n"; xy = p00_data ( prob, 2, nd ); xd = new double[nd]; yd = new double[nd]; for ( i = 0; i < nd; i++ ) { xd[i] = xy[0+i*2]; yd[i] = xy[1+i*2]; } r8vec2_print ( nd, xd, yd, " X, Y data:" ); // // Get the Newton coefficients. // cd = newton_coef_1d ( nd, xd, yd ); // // #1: Does interpolant match function at interpolation points? // ni = nd; xi = r8vec_copy_new ( ni, xd ); yi = newton_value_1d ( nd, xd, cd, ni, xi ); interp_error = r8vec_norm_affine ( ni, yi, yd ) / ( double ) ( ni ); cout << "\n"; cout << " L2 interpolation error averaged per interpolant node = " << interp_error << "\n"; delete [] xi; delete [] yi; // // #2: Compare estimated curve length to piecewise linear (minimal) curve length. // Assume data is sorted, and normalize X and Y dimensions by (XMAX-XMIN) and // (YMAX-YMIN). // xmin = r8vec_min ( nd, xd ); xmax = r8vec_max ( nd, xd ); ymin = r8vec_min ( nd, yd ); ymax = r8vec_max ( nd, yd ); ni = 501; xi = r8vec_linspace_new ( ni, xmin, xmax ); yi = newton_value_1d ( nd, xd, cd, ni, xi ); ld = 0.0; for ( i = 0; i < nd - 1; i++ ) { ld = ld + sqrt ( pow ( ( xd[i+1] - xd[i] ) / ( xmax - xmin ), 2 ) + pow ( ( yd[i+1] - yd[i] ) / ( ymax - ymin ), 2 ) ); } li = 0.0; for ( i = 0; i < ni - 1; i++ ) { li = li + sqrt ( pow ( ( xi[i+1] - xi[i] ) / ( xmax - xmin ), 2 ) + pow ( ( yi[i+1] - yi[i] ) / ( ymax - ymin ), 2 ) ); } cout << "\n"; cout << " Normalized length of piecewise linear interpolant = " << ld << "\n"; cout << " Normalized length of Newton interpolant = " << li << "\n"; delete [] xi; delete [] yi; // // Create data file. // data_filename = "data" + i4_to_string ( prob ) + ".txt"; data_unit.open ( data_filename.c_str ( ) ); for ( j = 0; j < nd; j++ ) { data_unit << " " << xd[j] << " " << yd[j] << "\n"; } data_unit.close ( ); cout << "\n"; cout << " Created graphics data file \"" << data_filename << "\".\n"; // // Create interp file. // ni = 501; xmin = r8vec_min ( nd, xd ); xmax = r8vec_max ( nd, xd ); xi = r8vec_linspace_new ( ni, xmin, xmax ); yi = newton_value_1d ( nd, xd, cd, ni, xi ); interp_filename = "interp" + i4_to_string ( prob ) + ".txt"; interp_unit.open ( interp_filename.c_str ( ) ); for ( j = 0; j < ni; j++ ) { interp_unit << " " << xi[j] << " " << yi[j] << "\n"; } interp_unit.close ( ); cout << " Created graphics interp file \"" << interp_filename << "\".\n"; // // Plot the data and the interpolant. // command_filename = "commands" + i4_to_string ( prob ) + ".txt"; command_unit.open ( command_filename.c_str ( ) ); output_filename = "plot" + i4_to_string ( prob ) + ".png"; command_unit << "# " << command_filename << "\n"; command_unit << "#\n"; command_unit << "# Usage:\n"; command_unit << "# gnuplot < " << command_filename << "\n"; command_unit << "#\n"; command_unit << "set term png\n"; command_unit << "set output '" << output_filename << "'\n"; command_unit << "set xlabel '<---X--->'\n"; command_unit << "set ylabel '<---Y--->'\n"; command_unit << "set title 'Data versus Newton polynomial interpolant'\n"; command_unit << "set grid\n"; command_unit << "set style data lines\n"; command_unit << "plot '" << data_filename << "' using 1:2 with points pt 7 ps 2 lc rgb 'blue',\\\n"; command_unit << " '" << interp_filename << "' using 1:2 lw 3 linecolor rgb 'red'\n"; command_unit.close ( ); cout << " Created graphics command file \"" << command_filename << "\".\n"; // // Free memory. // delete [] cd; delete [] xd; delete [] xi; delete [] xy; delete [] yd; delete [] yi; return; } //****************************************************************************80 string i4_to_string ( int i4 ) //****************************************************************************80 // // Purpose: // // i4_to_string() converts an I4 to a C++ string. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 16 January 2013 // // Author: // // John Burkardt // // Input: // // int I4, an integer. // // string FORMAT, the format string. // // Output: // // string I4_TO_STRING, the string. // { ostringstream fred; string value; fred << i4; value = fred.str ( ); return value; } //****************************************************************************80 double *r8mat_copy_new ( int m, int n, double a1[] ) //****************************************************************************80 // // Purpose: // // r8mat_copy_new() copies one R8MAT to a "new" R8MAT. // // Discussion: // // An R8MAT is a doubly dimensioned array of R8's, which // may be stored as a vector in column-major order. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 03 July 2008 // // Author: // // John Burkardt // // Input: // // int M, N, the number of rows and columns. // // double A1[M*N], the matrix to be copied. // // Output: // // double R8MAT_COPY_NEW[M*N], the copy of A1. // { double *a2; int i; int j; a2 = new double[m*n]; for ( j = 0; j < n; j++ ) { for ( i = 0; i < m; i++ ) { a2[i+j*m] = a1[i+j*m]; } } return a2; } //****************************************************************************80 double *r8vec_copy_new ( int n, double a1[] ) //****************************************************************************80 // // Purpose: // // r8vec_copy_new() copies an R8VEC to a new R8VEC. // // Discussion: // // An R8VEC is a vector of R8's. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 03 July 2008 // // Author: // // John Burkardt // // Input: // // int N, the number of entries in the vectors. // // double A1[N], the vector to be copied. // // Output: // // double R8VEC_COPY_NEW[N], the copy of A1. // { double *a2; int i; a2 = new double[n]; for ( i = 0; i < n; i++ ) { a2[i] = a1[i]; } return a2; } //****************************************************************************80 double *r8vec_linspace_new ( int n, double a_first, double a_last ) //****************************************************************************80 // // Purpose: // // r8vec_linspace_new() creates a vector of linearly spaced values. // // Discussion: // // An R8VEC is a vector of R8's. // // 4 points evenly spaced between 0 and 12 will yield 0, 4, 8, 12. // // In other words, the interval is divided into N-1 even subintervals, // and the endpoints of intervals are used as the points. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 29 March 2011 // // Author: // // John Burkardt // // Input: // // int N, the number of entries in the vector. // // double A_FIRST, A_LAST, the first and last entries. // // Output: // // double R8VEC_LINSPACE_NEW[N], a vector of linearly spaced data. // { double *a; int i; a = new double[n]; if ( n == 1 ) { a[0] = ( a_first + a_last ) / 2.0; } else { for ( i = 0; i < n; i++ ) { a[i] = ( ( double ) ( n - 1 - i ) * a_first + ( double ) ( i ) * a_last ) / ( double ) ( n - 1 ); } } return a; } //****************************************************************************80 double r8vec_max ( int n, double r8vec[] ) //****************************************************************************80 // // Purpose: // // r8vec_max() returns the value of the maximum element in an R8VEC. // // Discussion: // // An R8VEC is a vector of R8's. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 22 August 2010 // // Author: // // John Burkardt // // Input: // // int N, the number of entries in the array. // // double R8VEC[N], a pointer to the first entry of the array. // // Output: // // double R8VEC_MAX, the value of the maximum element. This // is set to 0.0 if N <= 0. // { int i; double value; value = r8vec[0]; for ( i = 1; i < n; i++ ) { if ( value < r8vec[i] ) { value = r8vec[i]; } } return value; } //****************************************************************************80 double r8vec_min ( int n, double r8vec[] ) //****************************************************************************80 // // Purpose: // // r8vec_min() returns the value of the minimum element in an R8VEC. // // Discussion: // // An R8VEC is a vector of R8's. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 02 July 2005 // // Author: // // John Burkardt // // Input: // // int N, the number of entries in the array. // // double R8VEC[N], the array to be checked. // // Output: // // double R8VEC_MIN, the value of the minimum element. // { int i; double value; value = r8vec[0]; for ( i = 1; i < n; i++ ) { if ( r8vec[i] < value ) { value = r8vec[i]; } } return value; } //****************************************************************************80 double r8vec_norm_affine ( int n, double v0[], double v1[] ) //****************************************************************************80 // // Purpose: // // r8vec_norm_affine() returns the affine L2 norm of an R8VEC. // // Discussion: // // The affine vector L2 norm is defined as: // // R8VEC_NORM_AFFINE(V0,V1) // = sqrt ( sum ( 1 <= I <= N ) ( V1(I) - V0(I) )^2 ) // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 27 October 2010 // // Author: // // John Burkardt // // Input: // // int N, the dimension of the vectors. // // double V0[N], the base vector. // // double V1[N], the vector. // // Output: // // double R8VEC_NORM_AFFINE, the affine L2 norm. // { int i; double value; value = 0.0; for ( i = 0; i < n; i++ ) { value = value + ( v1[i] - v0[i] ) * ( v1[i] - v0[i] ); } value = sqrt ( value ); return value; } //****************************************************************************80 void r8vec_print ( int n, double a[], string title ) //****************************************************************************80 // // Purpose: // // r8vec_print() prints an R8VEC. // // Discussion: // // An R8VEC is a vector of R8's. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 16 August 2004 // // Author: // // John Burkardt // // Input: // // int N, the number of components of the vector. // // double A[N], the vector to be printed. // // string TITLE, a title. // { int i; cout << "\n"; cout << title << "\n"; cout << "\n"; for ( i = 0; i < n; i++ ) { cout << " " << setw(8) << i << ": " << setw(14) << a[i] << "\n"; } return; } //****************************************************************************80 void r8vec2_print ( int n, double a1[], double a2[], string title ) //****************************************************************************80 // // Purpose: // // r8vec2_print() prints an R8VEC2. // // Discussion: // // An R8VEC2 is a dataset consisting of N pairs of real values, stored // as two separate vectors A1 and A2. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 19 November 2002 // // Author: // // John Burkardt // // Input: // // int N, the number of components of the vector. // // double A1[N], double A2[N], the vectors to be printed. // // string TITLE, a title. // { int i; cout << "\n"; cout << title << "\n"; cout << "\n"; for ( i = 0; i <= n - 1; i++ ) { cout << setw(6) << i << ": " << setw(14) << a1[i] << " " << setw(14) << a2[i] << "\n"; } return; } //****************************************************************************80 void timestamp ( ) //****************************************************************************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 MIT license. // // Modified: // // 08 July 2009 // // Author: // // John Burkardt // { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct std::tm *tm_ptr; std::time_t now; now = std::time ( NULL ); tm_ptr = std::localtime ( &now ); std::strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm_ptr ); std::cout << time_buffer << "\n"; return; # undef TIME_SIZE }