예제 #1
0
    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 + "");
    }
예제 #2
0
    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);
    }