private static void test01(int prob, int m) //****************************************************************************80 // // Purpose: // // TEST01 tests VANDERMONDE_APPROX_1D_MATRIX. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 10 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int PROB, the problem number. // // Input, int M, the polynomial degree. // { const bool debug = false; int i; Console.WriteLine(""); Console.WriteLine("TEST01:"); Console.WriteLine(" Approximate data from TEST_INTERP problem #" + prob + ""); int nd = TestInterp.p00_data_num(prob); Console.WriteLine(" Number of data points = " + nd + ""); double[] xy = TestInterp.p00_data(prob, 2, nd); switch (debug) { case true: typeMethods.r8mat_transpose_print(2, nd, xy, " Data array:"); break; } double[] xd = new double[nd]; double[] yd = new double[nd]; for (i = 0; i < nd; i++) { xd[i] = xy[0 + i * 2]; yd[i] = xy[1 + i * 2]; } // // Compute the Vandermonde matrix. // Console.WriteLine(" Using polynomial approximant of degree " + m + ""); double[] a = VandermondeMatrix.vandermonde_approx_1d_matrix(nd, m, xd); // // Solve linear system. // double[] c = QRSolve.qr_solve(nd, m + 1, a, yd); // // #1: Does approximant match function at data points? // int ni = nd; double[] xi = typeMethods.r8vec_copy_new(ni, xd); double[] yi = Polynomial.r8poly_values(m, c, ni, xi); double app_error = typeMethods.r8vec_norm_affine(ni, yi, yd) / ni; Console.WriteLine(""); Console.WriteLine(" L2 data approximation error = " + app_error + ""); // // #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). // double xmin = typeMethods.r8vec_min(nd, xd); double xmax = typeMethods.r8vec_max(nd, xd); double ymin = typeMethods.r8vec_min(nd, yd); double ymax = typeMethods.r8vec_max(nd, yd); ni = 501; xi = typeMethods.r8vec_linspace_new(ni, xmin, xmax); yi = Polynomial.r8poly_values(m, c, ni, xi); double ld = 0.0; for (i = 0; i < nd - 1; i++) { ld += Math.Sqrt(Math.Pow((xd[i + 1] - xd[i]) / (xmax - xmin), 2) + Math.Pow((yd[i + 1] - yd[i]) / (ymax - ymin), 2)); } double li = 0.0; for (i = 0; i < ni - 1; i++) { li += Math.Sqrt(Math.Pow((xi[i + 1] - xi[i]) / (xmax - xmin), 2) + Math.Pow((yi[i + 1] - yi[i]) / (ymax - ymin), 2)); } Console.WriteLine(""); Console.WriteLine(" Normalized length of piecewise linear interpolant = " + ld + ""); Console.WriteLine(" Normalized length of polynomial interpolant = " + li + ""); }
public static double[] vandermonde_approx_1d_coef(int n, int m, double[] x, double[] y) //****************************************************************************80 // // Purpose: // // VANDERMONDE_APPROX_1D_COEF computes a 1D polynomial approximant. // // Discussion: // // We assume the approximating function has the form // // p(x) = c0 + c1 * x + c2 * x^2 + ... + cm * x^m. // // We have n data values (x(i),y(i)) which must be approximated: // // p(x(i)) = c0 + c1 * x(i) + c2 * x(i)^2 + ... + cm * x(i)^m = y(i) // // This can be cast as an Nx(M+1) linear system for the polynomial // coefficients: // // [ 1 x1 x1^2 ... x1^m ] [ c0 ] = [ y1 ] // [ 1 x2 x2^2 ... x2^m ] [ c1 ] = [ y2 ] // [ .................. ] [ ... ] = [ ... ] // [ 1 xn xn^2 ... xn^m ] [ cm ] = [ yn ] // // In the typical case, N is greater than M+1 (we have more data and equations // than degrees of freedom) and so a least squares solution is appropriate, // in which case the computed polynomial will be a least squares approximant // to the data. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 10 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int N, the number of data points. // // Input, int M, the degree of the polynomial. // // Input, double X[N], Y[N], the data values. // // Output, double VANDERMONDE_APPROX_1D_COEF[M+1], the coefficients of // the approximating polynomial. C(0) is the constant term, and C(M) // multiplies X^M. // { double[] a = VandermondeMatrix.vandermonde_approx_1d_matrix(n, m, x); double[] c = QRSolve.qr_solve(n, m + 1, a, y); return(c); }