# include # include # include # include # include # include # include "pwl_interp_1d.h" # include "test_interp.h" int main ( ); void pwl_basis_1d_test ( ); void pwl_value_1d_test ( ); void pwl_interp_1d_test01 ( int prob ); void r8mat_print ( int m, int n, double a[], char *title ); void r8mat_print_some ( int m, int n, double a[], int ilo, int jlo, int ihi, int jhi, char *title ); void r8mat_transpose_print ( int m, int n, double a[], char *title ); void r8mat_transpose_print_some ( int m, int n, double a[], int ilo, int jlo, int ihi, int jhi, char *title ); double r8vec_diff_norm ( int n, double a[], double b[] ); double *r8vec_linspace_new ( int n, double a, double b ); double r8vec_max ( int n, double r8vec[] ); double r8vec_min ( int n, double r8vec[] ); void r8vec2_print ( int n, double a1[], double a2[], char *title ); void timestamp ( ); /******************************************************************************/ int main ( ) /******************************************************************************/ /* Purpose: pwl_interp_1d_test() tests pwl_interp_1d(). Licensing: This code is distributed under the MIT license. Modified: 01 July 2015 Author: John Burkardt */ { int prob; int prob_num; timestamp ( ); printf ( "\n" ); printf ( "pwl_interp_1d_test():\n" ); printf ( " C version\n" ); printf ( " Test pwl_interp_1d().\n" ); printf ( " The test needs the test_interp() library.\n" ); pwl_basis_1d_test ( ); pwl_value_1d_test ( ); prob_num = p00_prob_num ( ); for ( prob = 1; prob <= prob_num; prob++ ) { pwl_interp_1d_test01 ( prob ); } /* Terminate. */ printf ( "\n" ); printf ( "pwl_interp_1d_test():\n" ); printf ( " Normal end of execution.\n" ); printf ( "\n" ); timestamp ( ); return 0; } /******************************************************************************/ void pwl_basis_1d_test ( ) /******************************************************************************/ /* Purpose: pwl_basis_1d_test() tests pwl_basis_1d(). Licensing: This code is distributed under the MIT license. Modified: 01 July 2015 Author: John Burkardt */ { double *lb; int nd = 4; int ni = 21; double x_max; double x_min; double xd[4] = { 0.0, 2.0, 5.0, 10.0 }; double *xi; printf ( "\n" ); printf ( "pwl_basis_1d_test():\n" ); printf ( " pwl_basis_1d() evaluates the piecewise linear 1D basis\n" ); printf ( " functions.\n" ); x_min = 0.0; x_max = 10.0; xi = r8vec_linspace_new ( ni, x_min, x_max ); lb = pwl_basis_1d ( nd, xd, ni, xi ); r8mat_print ( ni, nd, lb, " The piecewise linear basis functions:" ); free ( lb ); free ( xi ); return; } /******************************************************************************/ void pwl_value_1d_test ( ) /******************************************************************************/ /* Purpose: pwl_value_1d_test() tests pwl_value_1d(). Discussion: f(x) = x^3 - 12 x^2 + 39 x - 28 = ( x - 1 ) * ( x - 4 ) * ( x - 7 ) Licensing: This code is distributed under the MIT license. Modified: 01 July 2015 Author: John Burkardt */ { int nd = 4; int ni = 21; double x_max; double x_min; double xd[4] = { 0.0, 2.0, 5.0, 10.0 }; double yd[4] = { -28.0, +10.0, -8.0, +162.0 }; double *xi; double *yi; printf ( "\n" ); printf ( "pwl_value_1d_test():\n" ); printf ( " pwl_value_1d() evaluates a piecewise linear 1D interpolant.\n" ); x_min = 0.0; x_max = 10.0; xi = r8vec_linspace_new ( ni, x_min, x_max ); yi = pwl_value_1d ( nd, xd, yd, ni, xi ); r8vec2_print ( ni, xi, yi, " Table of interpolant values:" ); free ( xi ); free ( yi ); return; } /******************************************************************************/ void pwl_interp_1d_test01 ( int prob ) /******************************************************************************/ /* Purpose: pwl_interp_1d_test01() tests pwl_interp_1d(). Licensing: This code is distributed under the MIT license. Modified: 31 May 2012 Author: John Burkardt Parameters: Input, int PROB, the problem index. */ { char command_filename[255]; FILE *command_unit; char data_filename[255]; FILE *data_unit; int i; double interp_error; char interp_filename[255]; FILE *interp_unit; int j; int nd; int ni; char output_filename[255]; double *xd; double *xi; double *xy; double xmax; double xmin; double *yd; double *yi; printf ( "\n" ); printf ( "pwl_interp_1d_test01():\n" ); printf ( " pwl_interp_1d() evaluates the piecewise linear interpolant.\n" ); printf ( " Interpolate data from test_interp() problem #%d\n", prob ); nd = p00_data_num ( prob ); printf ( " Number of data points = %d\n", nd ); xy = p00_data ( prob, 2, nd ); r8mat_transpose_print ( 2, nd, xy, " Data array:" ); xd = ( double * ) malloc ( nd * sizeof ( double ) ); yd = ( double * ) malloc ( nd * sizeof ( double ) ); for ( i = 0; i < nd; i++ ) { xd[i] = xy[0+2*i]; yd[i] = xy[1+2*i]; } /* Does interpolant match function at interpolation points? */ ni = nd; xi = ( double * ) malloc ( ni * sizeof ( double ) ); for ( i = 0; i < ni; i++ ) { xi[i] = xd[i]; } yi = pwl_value_1d ( nd, xd, yd, ni, xi ); interp_error = r8vec_diff_norm ( ni, yi, yd ) / ( double ) ( ni ); printf ( "\n" ); printf ( " L2 interpolation error averaged per interpolant node = %g\n", interp_error ); /* Create data file. */ sprintf ( data_filename, "data%02d.txt", prob ); data_unit = fopen ( data_filename, "wt" ); for ( j = 0; j < nd; j++ ) { fprintf ( data_unit, " %14g %14g\n", xd[j], yd[j] ); } fclose ( data_unit ); printf ( "\n" ); printf ( " Created graphics data file \"%s\".\n", data_filename ); /* Create interp file. */ free ( xi ); free ( yi ); ni = 501; xmin = r8vec_min ( nd, xd ); xmax = r8vec_max ( nd, xd ); xi = r8vec_linspace_new ( ni, xmin, xmax ); yi = pwl_value_1d ( nd, xd, yd, ni, xi ); sprintf ( interp_filename, "interp%02d.txt", prob ); interp_unit = fopen ( interp_filename, "wt" ); for ( j = 0; j < ni; j++ ) { fprintf ( interp_unit, " %g %g\n", xi[j], yi[j] ); } fclose ( interp_unit ); printf ( " Created graphics interp file \"%s\".\n", interp_filename ); /* Plot the data and the interpolant. */ sprintf ( command_filename, "commands%02d.txt", prob ); command_unit = fopen ( command_filename, "wt" ); sprintf ( output_filename, "plot%02d.png", prob ); fprintf ( command_unit, "# %s\n", command_filename ); fprintf ( command_unit, "#\n" ); fprintf ( command_unit, "# Usage:\n" ); fprintf ( command_unit, "# gnuplot < %s\n", command_filename ); fprintf ( command_unit, "#\n" ); fprintf ( command_unit, "set term png\n" ); fprintf ( command_unit, "set output '%s'\n", output_filename ); fprintf ( command_unit, "set xlabel '<---X--->'\n" ); fprintf ( command_unit, "set ylabel '<---Y--->'\n" ); fprintf ( command_unit, "set title 'Data versus piecewise linear interpolant'\n" ); fprintf ( command_unit, "set grid\n" ); fprintf ( command_unit, "set style data lines\n" ); fprintf ( command_unit, "plot '%s' using 1:2 with points pt 7 ps 2 lc rgb 'blue',\\\n", data_filename ); fprintf ( command_unit, " '%s' using 1:2 lw 3 linecolor rgb 'red'\n", interp_filename ); fclose ( command_unit ); printf ( " Created graphics command file \"%s\".\n", command_filename ); /* Free memory. */ free ( xd ); free ( xi ); free ( xy ); free ( yd ); free ( yi ); return; } /******************************************************************************/ void r8mat_print ( int m, int n, double a[], char *title ) /******************************************************************************/ /* Purpose: r8mat_print() prints an R8MAT. Discussion: An R8MAT is a doubly dimensioned array of R8 values, stored as a vector in column-major order. Entry A(I,J) is stored as A[I+J*M] Licensing: This code is distributed under the MIT license. Modified: 28 May 2008 Author: John Burkardt Input: int M, the number of rows in A. int N, the number of columns in A. double A[M*N], the M by N matrix. char *TITLE, a title. */ { r8mat_print_some ( m, n, a, 1, 1, m, n, title ); return; } /******************************************************************************/ void r8mat_print_some ( int m, int n, double a[], int ilo, int jlo, int ihi, int jhi, char *title ) /******************************************************************************/ /* Purpose: r8mat_print_some() prints some of an R8MAT. Discussion: An R8MAT is a doubly dimensioned array of R8 values, stored as a vector in column-major order. Licensing: This code is distributed under the MIT license. Modified: 26 June 2013 Author: John Burkardt Input: int M, the number of rows of the matrix. M must be positive. int N, the number of columns of the matrix. N must be positive. double A[M*N], the matrix. int ILO, JLO, IHI, JHI, designate the first row and column, and the last row and column to be printed. char *TITLE, a title. */ { # define INCX 5 int i; int i2hi; int i2lo; int j; int j2hi; int j2lo; fprintf ( stdout, "\n" ); fprintf ( stdout, "%s\n", title ); if ( m <= 0 || n <= 0 ) { fprintf ( stdout, "\n" ); fprintf ( stdout, " (None)\n" ); return; } /* Print the columns of the matrix, in strips of 5. */ for ( j2lo = jlo; j2lo <= jhi; j2lo = j2lo + INCX ) { j2hi = j2lo + INCX - 1; if ( n < j2hi ) { j2hi = n; } if ( jhi < j2hi ) { j2hi = jhi; } fprintf ( stdout, "\n" ); /* For each column J in the current range... Write the header. */ fprintf ( stdout, " Col: "); for ( j = j2lo; j <= j2hi; j++ ) { fprintf ( stdout, " %7d ", j - 1 ); } fprintf ( stdout, "\n" ); fprintf ( stdout, " Row\n" ); fprintf ( stdout, "\n" ); /* Determine the range of the rows in this strip. */ if ( 1 < ilo ) { i2lo = ilo; } else { i2lo = 1; } if ( m < ihi ) { i2hi = m; } else { i2hi = ihi; } for ( i = i2lo; i <= i2hi; i++ ) { /* Print out (up to) 5 entries in row I, that lie in the current strip. */ fprintf ( stdout, "%5d:", i - 1 ); for ( j = j2lo; j <= j2hi; j++ ) { fprintf ( stdout, " %14g", a[i-1+(j-1)*m] ); } fprintf ( stdout, "\n" ); } } return; # undef INCX } /******************************************************************************/ void r8mat_transpose_print ( int m, int n, double a[], char *title ) /******************************************************************************/ /* Purpose: r8mat_transpose_print() prints an R8MAT, transposed. Discussion: An R8MAT is a doubly dimensioned array of R8 values, stored as a vector in column-major order. Licensing: This code is distributed under the MIT license. Modified: 28 May 2008 Author: John Burkardt Parameters: Input, int M, N, the number of rows and columns. Input, double A[M*N], an M by N matrix to be printed. Input, char *TITLE, a title. */ { r8mat_transpose_print_some ( m, n, a, 1, 1, m, n, title ); return; } /******************************************************************************/ void r8mat_transpose_print_some ( int m, int n, double a[], int ilo, int jlo, int ihi, int jhi, char *title ) /******************************************************************************/ /* Purpose: r8mat_transpose_print_some() prints some of an R8MAT, transposed. Discussion: An R8MAT is a doubly dimensioned array of R8 values, stored as a vector in column-major order. Licensing: This code is distributed under the MIT license. Modified: 10 September 2013 Author: John Burkardt Parameters: Input, int M, N, the number of rows and columns. Input, double A[M*N], an M by N matrix to be printed. Input, int ILO, JLO, the first row and column to print. Input, int IHI, JHI, the last row and column to print. Input, char *TITLE, a title. */ { # define INCX 5 int i; int i2; int i2hi; int i2lo; int i2lo_hi; int i2lo_lo; int inc; int j; int j2hi; int j2lo; fprintf ( stdout, "\n" ); fprintf ( stdout, "%s\n", title ); if ( m <= 0 || n <= 0 ) { fprintf ( stdout, "\n" ); fprintf ( stdout, " (None)\n" ); return; } if ( ilo < 1 ) { i2lo_lo = 1; } else { i2lo_lo = ilo; } if ( ihi < m ) { i2lo_hi = m; } else { i2lo_hi = ihi; } for ( i2lo = i2lo_lo; i2lo <= i2lo_hi; i2lo = i2lo + INCX ) { i2hi = i2lo + INCX - 1; if ( m < i2hi ) { i2hi = m; } if ( ihi < i2hi ) { i2hi = ihi; } inc = i2hi + 1 - i2lo; fprintf ( stdout, "\n" ); fprintf ( stdout, " Row:" ); for ( i = i2lo; i <= i2hi; i++ ) { fprintf ( stdout, " %7d ", i - 1 ); } fprintf ( stdout, "\n" ); fprintf ( stdout, " Col\n" ); fprintf ( stdout, "\n" ); if ( jlo < 1 ) { j2lo = 1; } else { j2lo = jlo; } if ( n < jhi ) { j2hi = n; } else { j2hi = jhi; } for ( j = j2lo; j <= j2hi; j++ ) { fprintf ( stdout, "%5d:", j - 1 ); for ( i2 = 1; i2 <= inc; i2++ ) { i = i2lo - 1 + i2; fprintf ( stdout, " %14g", a[(i-1)+(j-1)*m] ); } fprintf ( stdout, "\n" ); } } return; # undef INCX } /******************************************************************************/ double r8vec_diff_norm ( int n, double a[], double b[] ) /******************************************************************************/ /* Purpose: r8vec_diff_norm() returns the L2 norm of the difference of R8VEC's. Discussion: An R8VEC is a vector of R8's. The vector L2 norm is defined as: R8VEC_NORM_L2 = sqrt ( sum ( 1 <= I <= N ) A(I)^2 ). Licensing: This code is distributed under the MIT license. Modified: 24 June 2011 Author: John Burkardt Parameters: Input, int N, the number of entries in A. Input, double A[N], B[N], the vectors. Output, double R8VEC_DIFF_NORM, the L2 norm of A - B. */ { int i; double value; value = 0.0; for ( i = 0; i < n; i++ ) { value = value + ( a[i] - b[i] ) * ( a[i] - b[i] ); } value = sqrt ( value ); return value; } /******************************************************************************/ double *r8vec_linspace_new ( int n, double a, double b ) /******************************************************************************/ /* 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 Parameters: Input, int N, the number of entries in the vector. Input, double A, B, the first and last entries. Output, double R8VEC_LINSPACE_NEW[N], a vector of linearly spaced data. */ { int i; double *x; x = ( double * ) malloc ( n * sizeof ( double ) ); if ( n == 1 ) { x[0] = ( a + b ) / 2.0; } else { for ( i = 0; i < n; i++ ) { x[i] = ( ( double ) ( n - 1 - i ) * a + ( double ) ( i ) * b ) / ( double ) ( n - 1 ); } } return x; } /******************************************************************************/ double r8vec_max ( int n, double r8vec[] ) /******************************************************************************/ /* Purpose: r8vec_max() returns the value of the maximum element in a R8VEC. Licensing: This code is distributed under the MIT license. Modified: 05 May 2006 Author: John Burkardt Parameters: Input, int N, the number of entries in the array. Input, 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; if ( n <= 0 ) { value = 0.0; return value; } value = r8vec[0]; for ( i = 1; i < n; i++ ) { if ( value < r8vec[i] ) { value = r8vec[i]; } } return value; } /******************************************************************************/ double r8vec_min ( int n, double r8vec[] ) /******************************************************************************/ /* Purpose: r8vec_min() returns the value of the minimum element in a R8VEC. Licensing: This code is distributed under the MIT license. Modified: 05 May 2006 Author: John Burkardt Parameters: Input, int N, the number of entries in the array. Input, 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; } /******************************************************************************/ void r8vec2_print ( int n, double a1[], double a2[], char *title ) /******************************************************************************/ /* 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: 26 March 2009 Author: John Burkardt Input: int N, the number of components of the vector. double A1[N], double A2[N], the vectors to be printed. char *TITLE, a title. */ { int i; fprintf ( stdout, "\n" ); fprintf ( stdout, "%s\n", title ); fprintf ( stdout, "\n" ); for ( i = 0; i < n; i++ ) { fprintf ( stdout, " %4d: %14g %14g\n", i, a1[i], a2[i] ); } return; } /******************************************************************************/ void timestamp ( ) /******************************************************************************/ /* Purpose: timestamp() prints the current YMDHMS date as a time stamp. Example: 17 June 2014 09:45:54 AM Licensing: This code is distributed under the MIT license. Modified: 01 May 2021 Author: John Burkardt */ { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; time_t now; now = time ( NULL ); tm = localtime ( &now ); strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); printf ( "%s\n", time_buffer ); return; # undef TIME_SIZE }