Esempio n. 1
0
    public static void triangle()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for TRIANGLE.
    //
    //  Discussion:
    //
    //    This driver computes the interpolation of the Franke function
    //    on the triangle T(U,V,W) with vertices U=(U1,U2)=(0,0),
    //    V=(V1,V2)=(1,0) and W=(W1,W2)=(0,1) (unit triangle)
    //    at the first family of Padua points.
    //
    //    The degree of interpolation is DEG = 60 and the number of target
    //    points is NTG = NTG1 ** 2 - NTG1 + 1, NTG1 = 100.
    //
    //    The maps from the reference square [-1,1]^2 to the triangle
    //    are SIGMA1 and SIGMA2 with inverses ISIGM1 and ISIGM2.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    16 February 2014
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Marco Caliari, Stefano De Marchi,
    //    Marco Vianello.
    //    This C version by John Burkardt.
    //
    //  Reference:
    //
    //    Marco Caliari, Stefano de Marchi, Marco Vianello,
    //    Algorithm 886:
    //    Padua2D: Lagrange Interpolation at Padua Points on Bivariate Domains,
    //    ACM Transactions on Mathematical Software,
    //    Volume 35, Number 3, October 2008, Article 21, 11 pages.
    //
    //  Parameters:
    //
    //    Local, int DEGMAX, the maximum degree of interpolation.
    //
    //    Local, int NPDMAX, the maximum number of Padua points
    //    = (DEGMAX + 1) * (DEGMAX + 2) / 2.
    //
    //    Local, int NTG1MX, the maximum value of the parameter determining
    //    the number of target points.
    //
    //    Local, int NTGMAX, the maximum number of target points,
    //    dependent on NTG1MX.
    //
    //    Local, int DEG, the degree of interpolation.
    //
    //    Local, int NTG1, the parameter determining the number
    //   of target points.
    //
    //    Local, int NPD, the number of Padua points = (DEG + 1) * (DEG + 2) / 2.
    //
    //    Local, int NTG, the number of target points, dependent on NTG1.
    //
    //    Local, double PD1(NPDMAX), the first coordinates of
    //    the Padua points.
    //
    //    Local, double PD2(NPDMAX), the second coordinates of the
    //    Padua points.
    //
    //    Local, double WPD(NPDMAX), the weights.
    //
    //    Local, double FPD(NPDMAX), the function at the Padua points.
    //
    //    Workspace, double RAUX1(DEGMAX+1)*(DEGMAX+2)).
    //
    //    Workspace, double RAUX2(DEGMAX+1)*(DEGMAX+2)).
    //
    //    Local, double C0(0:DEGMAX+1,0:DEGMAX+1), the coefficient matrix.
    //
    //    Local, double TG1(NTGMAX), the first coordinates of the
    //    target points.
    //
    //    Local, double TG2(NTGMAX), the second coordinates of the
    //    target points.
    //
    //    Local, double INTFTG(NTGMAX), the values of the
    //    interpolated function.
    //
    //    Local, double MAXERR, the maximum norm of the error at target
    //    points.
    //
    //    Local, double ESTERR, the estimated error.
    //
    {
        const int DEGMAX = 60;
        const int NTG1MX = 100;
        const int NPDMAX = (DEGMAX + 1) * (DEGMAX + 2) / 2;
        const int NTGMAX = NTG1MX * NTG1MX - NTG1MX + 1;

        double[] c0     = new double[(DEGMAX + 2) * (DEGMAX + 2)];
        double   esterr = 0;

        double[] fpd = new double[NPDMAX];
        int      i;

        double[]      intftg = new double[NTGMAX];
        double        maxdev;
        int           npd    = 0;
        int           ntg    = 0;
        List <string> output = new();

        double[] pd1   = new double[NPDMAX];
        double[] pd2   = new double[NPDMAX];
        double[] raux1 = new double[(DEGMAX + 1) * (DEGMAX + 2)];
        double[] raux2 = new double[(DEGMAX + 1) * (DEGMAX + 2)];
        double[] tg1   = new double[NTGMAX];
        double[] tg2   = new double[NTGMAX];
        double[] wpd   = new double[NPDMAX];
        double   x;
        double   y;

        const double u1   = 0.0;
        const double u2   = 0.0;
        const double v1   = 1.0;
        const double v2   = 0.0;
        const double w1   = 0.0;
        const double w2   = 1.0;
        const int    deg  = 60;
        const int    ntg1 = 100;

        Console.WriteLine("");
        Console.WriteLine("TRIANGLE:");
        Console.WriteLine("  Interpolation of the Franke function");
        Console.WriteLine("  on the unit triangle T((0,0),(1,0),(0,1))");
        Console.WriteLine("  at degree = " + deg + "");

        //
        //  Build the first family of Padua points in the square [-1,1]^2
        //
        Padua.pdpts(deg, ref pd1, ref pd2, ref wpd, ref npd);
        //
        //  Compute the Franke function at Padua points mapped to T(U,V,W).
        //
        for (i = 0; i < npd; i++)
        {
            x      = sigma1(pd1[i], pd2[i], u1, u2, v1, v2, w1, w2);
            y      = sigma2(pd1[i], pd2[i], u1, u2, v1, v2, w1, w2);
            fpd[i] = Franke.franke(x, y);
        }

        //
        //  Write X, Y, F(X,Y) to a file.
        //
        string filename = "triangle_fpd.txt";

        for (i = 0; i < npd; i++)
        {
            x = sigma1(pd1[i], pd2[i], u1, u2, v1, v2, w1, w2);
            y = sigma2(pd1[i], pd2[i], u1, u2, v1, v2, w1, w2);
            output.Add(x
                       + "  " + y
                       + "  " + fpd[i] + "");
        }

        File.WriteAllLines(filename, output);
        Console.WriteLine("");
        Console.WriteLine("  Wrote F(x,y) at Padua points in '" + filename + "'");
        //
        //  Compute the matrix C0 of the coefficients in the bivariate
        //  orthonormal Chebyshev basis
        //
        Padua.padua2(deg, DEGMAX, npd, wpd, fpd, raux1, raux2, ref c0, ref esterr);
        //
        //  Build the set of target points on T(U,V,W)
        //
        target(u1, u2, v1, v2, w1, w2, ntg1, NTGMAX, ref tg1, ref tg2, ref ntg);
        //
        //  Evaluate the interpolant at the target points.
        //
        for (i = 0; i < ntg; i++)
        {
            x         = isigm1(tg1[i], tg2[i], u1, u2, v1, v2, w1, w2);
            y         = isigm2(tg1[i], tg2[i], u1, u2, v1, v2, w1, w2);
            intftg[i] = Padua.pd2val(deg, DEGMAX, c0, x, y);
        }

        //
        //  Write the function value at target points to a file.
        //
        filename = "triangle_ftg.txt";
        for (i = 0; i < ntg; i++)
        {
            output.Add(tg1[i]
                       + "  " + tg2[i]
                       + "  " + Franke.franke(tg1[i], tg2[i]) + "");
        }

        File.WriteAllLines(filename, output);
        Console.WriteLine("  Wrote F(x,y) at target points in '" + filename + "'");
        //
        //  Write the interpolated function value at target points to a file.
        //
        filename = "triangle_itg.txt";
        for (i = 0; i < ntg; i++)
        {
            output.Add(tg1[i]
                       + "  " + tg2[i]
                       + "  " + intftg[i] + "");
        }

        File.WriteAllLines(filename, output);
        Console.WriteLine("  Wrote I(F)(x,y) at target points in '" + filename + "'");
        //
        //  Compute the error relative to the max deviation from the mean.
        //
        double maxerr = 0.0;
        double mean   = 0.0;
        double fmax   = -typeMethods.r8_huge();
        double fmin   = +typeMethods.r8_huge();

        for (i = 0; i < ntg; i++)
        {
            double fxy = Franke.franke(tg1[i], tg2[i]);
            double ixy = intftg[i];
            maxerr = Math.Max(maxerr, Math.Abs(fxy - ixy));
            mean  += fxy;
            fmax   = Math.Max(fmax, fxy);
            fmin   = Math.Min(fmin, fxy);
        }

        if (Math.Abs(fmax - fmin) <= double.Epsilon)
        {
            maxdev = 1.0;
        }
        else
        {
            mean  /= ntg;
            maxdev = Math.Max(fmax - mean, mean - fmin);
        }

        //
        //  Print error ratios.
        //
        Console.WriteLine("");
        Console.WriteLine("  Estimated error:  " + esterr / maxdev + "");
        Console.WriteLine("  Actual error:     " + maxerr / maxdev + "");
        Console.WriteLine("  Expected error:   " + 0.1226E-09 + "");
        //
        //  Terminate.
        //
        Console.WriteLine("");
        Console.WriteLine("TRIANGLE:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
Esempio n. 2
0
    public static void ellipse()
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for ELLIPSE.
    //
    //  Discussion:
    //
    //    This driver computes the interpolation of the Franke function
    //    on the ellipse E((C1,C2),ALPHA,BETA) = E((0.5,0.5),0.5,0.5)
    //    at the first family of Padua points.
    //
    //    The ellipse has the equation:
    //
    //      ( ( X - C1 ) / ALPHA )^2 + ( ( Y - C2 ) / BETA )^2 = 1
    //
    //    The degree of interpolation DEG = 60 and the number of target
    //    points is NTG = NTG1 ^ 2 - 2 * NTG1 + 2, NTG1 = 100.
    //
    //    The maps from the reference square [-1,1]^2 to the current domain
    //    are SIGMA1 and SIGMA2 with inverses ISIGM1 and ISIGM2.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    16 February 2014
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Marco Caliari, Stefano De Marchi,
    //    Marco Vianello.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Marco Caliari, Stefano de Marchi, Marco Vianello,
    //    Algorithm 886:
    //    Padua2D: Lagrange Interpolation at Padua Points on Bivariate Domains,
    //    ACM Transactions on Mathematical Software,
    //    Volume 35, Number 3, October 2008, Article 21, 11 pages.
    //
    //  Local Parameters:
    //
    //    Local, int DEGMAX, the maximum degree of interpolation.
    //
    //    Local, int NPDMAX, the maximum number of Padua points
    //    = (DEGMAX + 1) * (DEGMAX + 2) / 2.
    //
    //    Local, int NTG1MX, the maximum value of the parameter determining
    //    the number of target points.
    //
    //    Local, int NTGMAX, the maximum number of target points,
    //    dependent on NTG1MX.
    //
    //    Local, int DEG, the degree of interpolation.
    //
    //    Local, int NTG1, the parameter determining the number of target points.
    //
    //    Local, int NPD, the number of Padua points = (DEG + 1) * (DEG + 2) / 2.
    //
    //    Local, int NTG, the number of target points, dependent on NTG1.
    //
    //    Local, double PD1[NPDMAX], the first coordinates of
    //    the Padua points.
    //
    //    Local, double PD2[NPDMAX], the second coordinates of the
    //    Padua points.
    //
    //    Local, double WPD[NPDMAX], the weights.
    //
    //    Local, double FPD[NPDMAX], the function at the Padua points.
    //
    //    Workspace, double RAUX1[(DEGMAX+1)*(DEGMAX+2)].
    //
    //    Workspace, double RAUX2[(DEGMAX+1)*(DEGMAX+2)].
    //
    //    Local, double C0[(0:DEGMAX+1)*(0:DEGMAX+1)], the coefficient matrix.
    //
    //    Local, double TG1[NTGMAX], the first coordinates of the
    //    target points.
    //
    //    Local, double TG2[NTGMAX], the second coordinates of the
    //    target points.
    //
    //    Local, double INTFTG[NTGMAX], the values of the
    //    interpolated function.
    //
    //    Local, double MAXERR, the maximum norm of the error at target
    //    points.
    //
    //    Local, double ESTERR, the estimated error.
    //
    {
        const int DEGMAX = 60;
        const int NTG1MX = 100;
        const int NPDMAX = (DEGMAX + 1) * (DEGMAX + 2) / 2;
        const int NTGMAX = NTG1MX * NTG1MX - 2 * NTG1MX + 2;

        double[] c0     = new double[(DEGMAX + 2) * (DEGMAX + 2)];
        double   esterr = 0;

        double[] fpd = new double[NPDMAX];
        int      i;

        double[]      intftg = new double[NTGMAX];
        double        maxdev;
        int           npd    = 0;
        int           ntg    = 0;
        List <string> output = new();

        double[] pd1   = new double[NPDMAX];
        double[] pd2   = new double[NPDMAX];
        double[] raux1 = new double[(DEGMAX + 1) * (DEGMAX + 2)];
        double[] raux2 = new double[(DEGMAX + 1) * (DEGMAX + 2)];
        double[] tg1   = new double[NTGMAX];
        double[] tg2   = new double[NTGMAX];
        double[] wpd   = new double[NPDMAX];
        double   x;
        double   y;

        const double alpha = 0.5;
        const double beta  = 0.5;
        const double c1    = 0.5;
        const double c2    = 0.5;
        const int    deg   = 60;
        const int    ntg1  = 100;

        Console.WriteLine("");
        Console.WriteLine("ELLIPSE:");
        Console.WriteLine("  Interpolation of the Franke function");
        Console.WriteLine("  on the disk with center = (0.5,0.5) and radius = 0.5");
        Console.WriteLine("  of degree = " + deg + "");

        //
        //  Build the first family of Padua points in the square [-1,1]^2.
        //
        Padua.pdpts(deg, ref pd1, ref pd2, ref wpd, ref npd);
        //
        //  Compute the Franke function at Padua points mapped to the region.
        //
        for (i = 0; i < npd; i++)
        {
            x      = sigma1(pd1[i], pd2[i], c1, c2, alpha, beta);
            y      = sigma2(pd1[i], pd2[i], c1, c2, alpha, beta);
            fpd[i] = Franke.franke(x, y);
        }

        //
        //  Write X, Y, F(X,Y) to a file.
        //
        string filename = "ellipse_fpd.txt";

        for (i = 0; i < npd; i++)
        {
            x = sigma1(pd1[i], pd2[i], c1, c2, alpha, beta);
            y = sigma2(pd1[i], pd2[i], c1, c2, alpha, beta);
            output.Add(x
                       + "  " + y
                       + "  " + fpd[i] + "");
        }

        File.WriteAllLines(filename, output);
        Console.WriteLine("");
        Console.WriteLine("  Wrote F(x,y) at Padua points in '" + filename + "'");
        //
        //  Compute the matrix C0 of the coefficients in the bivariate
        //  orthonormal Chebyshev basis.
        //
        Padua.padua2(deg, DEGMAX, npd, wpd, fpd, raux1, raux2, ref c0, ref esterr);
        //
        //  Evaluate the target points in the region.
        //
        target(c1, c2, alpha, beta, ntg1, NTGMAX, ref tg1, ref tg2, ref ntg);
        //
        //  Evaluate the interpolant at the target points.
        //
        for (i = 0; i < ntg; i++)
        {
            x         = isigm1(tg1[i], tg2[i], c1, c2, alpha, beta);
            y         = isigm2(tg1[i], tg2[i], c1, c2, alpha, beta);
            intftg[i] = Padua.pd2val(deg, DEGMAX, c0, x, y);
        }

        //
        //  Write the function value at target points to a file.
        //
        output.Clear();
        filename = "ellipse_ftg.txt";
        for (i = 0; i < ntg; i++)
        {
            output.Add(tg1[i]
                       + "  " + tg2[i]
                       + "  " + Franke.franke(tg1[i], tg2[i]) + "");
        }

        File.WriteAllLines(filename, output);
        Console.WriteLine("  Wrote F(x,y) at target points in '" + filename + "'");
        //
        //  Write the interpolated function value at target points to a file.
        //
        output.Clear();
        filename = "ellipse_itg.txt";
        for (i = 0; i < ntg; i++)
        {
            output.Add(tg1[i]
                       + "  " + tg2[i]
                       + "  " + intftg[i] + "");
        }

        File.WriteAllLines(filename, output);
        Console.WriteLine("  Wrote I(F)(x,y) at target points in '" + filename + "'");
        //
        //  Compute the error relative to the max deviation from the mean.
        //
        double maxerr = 0.0;
        double mean   = 0.0;
        double fmax   = -typeMethods.r8_huge();
        double fmin   = +typeMethods.r8_huge();

        for (i = 0; i < ntg; i++)
        {
            double fxy = Franke.franke(tg1[i], tg2[i]);
            double ixy = intftg[i];
            maxerr = Math.Max(maxerr, Math.Abs(fxy - ixy));
            mean  += fxy;
            fmax   = Math.Max(fmax, fxy);
            fmin   = Math.Min(fmin, fxy);
        }

        if (Math.Abs(fmax - fmin) <= double.Epsilon)
        {
            maxdev = 1.0;
        }
        else
        {
            mean  /= ntg;
            maxdev = Math.Max(fmax - mean, mean - fmin);
        }

        //
        //  Print error ratios.
        //
        Console.WriteLine("");
        Console.WriteLine("  Estimated error:  " + esterr / maxdev + "");
        Console.WriteLine("  Actual error:     " + maxerr / maxdev + "");
        Console.WriteLine("  Expected error:   " + 0.1769E-09 + "");
        //
        //  Terminate.
        //
        Console.WriteLine("");
        Console.WriteLine("ELLIPSE:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }