Example #1
0
        public static bool testratint(bool silent)
        {
            bool result = new bool();
            bool waserrors = new bool();
            bool bcerrors = new bool();
            bool nperrors = new bool();
            bool fiterrors = new bool();
            double threshold = 0;
            double lipschitztol = 0;
            int maxn = 0;
            int passcount = 0;
            ratint.barycentricinterpolant b1 = new ratint.barycentricinterpolant();
            ratint.barycentricinterpolant b2 = new ratint.barycentricinterpolant();
            double[] x = new double[0];
            double[] x2 = new double[0];
            double[] y = new double[0];
            double[] y2 = new double[0];
            double[] w = new double[0];
            double[] w2 = new double[0];
            double[] xc = new double[0];
            double[] yc = new double[0];
            int[] dc = new int[0];
            double h = 0;
            double s1 = 0;
            double s2 = 0;
            bool bsame = new bool();
            int n = 0;
            int m = 0;
            int n2 = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            int d = 0;
            int pass = 0;
            double err = 0;
            double maxerr = 0;
            double t = 0;
            double a = 0;
            double b = 0;
            double s = 0;
            double v = 0;
            double v0 = 0;
            double v1 = 0;
            double v2 = 0;
            double v3 = 0;
            double d0 = 0;
            double d1 = 0;
            double d2 = 0;
            int info = 0;
            int info2 = 0;
            double xmin = 0;
            double xmax = 0;
            double refrms = 0;
            double refavg = 0;
            double refavgrel = 0;
            double refmax = 0;
            double[] ra = new double[0];
            double[] ra2 = new double[0];
            int ralen = 0;
            ratint.barycentricfitreport rep = new ratint.barycentricfitreport();
            ratint.barycentricfitreport rep2 = new ratint.barycentricfitreport();
            ratint.barycentricinterpolant b3 = new ratint.barycentricinterpolant();
            ratint.barycentricinterpolant b4 = new ratint.barycentricinterpolant();

            nperrors = false;
            bcerrors = false;
            fiterrors = false;
            waserrors = false;
            
            //
            // PassCount        number of repeated passes
            // Threshold        error tolerance
            // LipschitzTol     Lipschitz constant increase allowed
            //                  when calculating constant on a twice denser grid
            //
            passcount = 5;
            maxn = 15;
            threshold = 1000000*math.machineepsilon;
            lipschitztol = 1.3;
            
            //
            // Basic barycentric functions
            //
            for(n=1; n<=10; n++)
            {
                
                //
                // randomized tests
                //
                for(pass=1; pass<=passcount; pass++)
                {
                    
                    //
                    // generate weights from polynomial interpolation
                    //
                    v0 = 1+0.4*math.randomreal()-0.2;
                    v1 = 2*math.randomreal()-1;
                    v2 = 2*math.randomreal()-1;
                    v3 = 2*math.randomreal()-1;
                    x = new double[n];
                    y = new double[n];
                    w = new double[n];
                    for(i=0; i<=n-1; i++)
                    {
                        if( n==1 )
                        {
                            x[i] = 0;
                        }
                        else
                        {
                            x[i] = v0*Math.Cos(i*Math.PI/(n-1));
                        }
                        y[i] = Math.Sin(v1*x[i])+Math.Cos(v2*x[i])+Math.Exp(v3*x[i]);
                    }
                    for(j=0; j<=n-1; j++)
                    {
                        w[j] = 1;
                        for(k=0; k<=n-1; k++)
                        {
                            if( k!=j )
                            {
                                w[j] = w[j]/(x[j]-x[k]);
                            }
                        }
                    }
                    ratint.barycentricbuildxyw(x, y, w, n, b1);
                    
                    //
                    // unpack, then pack again and compare
                    //
                    brcunset(b2);
                    ratint.barycentricunpack(b1, ref n2, ref x2, ref y2, ref w2);
                    bcerrors = bcerrors | n2!=n;
                    ratint.barycentricbuildxyw(x2, y2, w2, n2, b2);
                    t = 2*math.randomreal()-1;
                    bcerrors = bcerrors | (double)(Math.Abs(ratint.barycentriccalc(b1, t)-ratint.barycentriccalc(b2, t)))>(double)(threshold);
                    
                    //
                    // copy, compare
                    //
                    brcunset(b2);
                    ratint.barycentriccopy(b1, b2);
                    t = 2*math.randomreal()-1;
                    bcerrors = bcerrors | (double)(Math.Abs(ratint.barycentriccalc(b1, t)-ratint.barycentriccalc(b2, t)))>(double)(threshold);
                    
                    //
                    // test interpolation properties
                    //
                    for(i=0; i<=n-1; i++)
                    {
                        
                        //
                        // test interpolation at nodes
                        //
                        bcerrors = bcerrors | (double)(Math.Abs(ratint.barycentriccalc(b1, x[i])-y[i]))>(double)(threshold*Math.Abs(y[i]));
                        
                        //
                        // compare with polynomial interpolation
                        //
                        t = 2*math.randomreal()-1;
                        poldiff2(x, y, n, t, ref v0, ref v1, ref v2);
                        bcerrors = bcerrors | (double)(Math.Abs(ratint.barycentriccalc(b1, t)-v0))>(double)(threshold*Math.Max(Math.Abs(v0), 1));
                        
                        //
                        // test continuity between nodes
                        // calculate Lipschitz constant on two grids -
                        // dense and even more dense. If Lipschitz constant
                        // on a denser grid is significantly increased,
                        // continuity test is failed
                        //
                        t = 3.0;
                        k = 100;
                        s1 = 0;
                        for(j=0; j<=k-1; j++)
                        {
                            v1 = x[i]+(t-x[i])*j/k;
                            v2 = x[i]+(t-x[i])*(j+1)/k;
                            s1 = Math.Max(s1, Math.Abs(ratint.barycentriccalc(b1, v2)-ratint.barycentriccalc(b1, v1))/Math.Abs(v2-v1));
                        }
                        k = 2*k;
                        s2 = 0;
                        for(j=0; j<=k-1; j++)
                        {
                            v1 = x[i]+(t-x[i])*j/k;
                            v2 = x[i]+(t-x[i])*(j+1)/k;
                            s2 = Math.Max(s2, Math.Abs(ratint.barycentriccalc(b1, v2)-ratint.barycentriccalc(b1, v1))/Math.Abs(v2-v1));
                        }
                        bcerrors = bcerrors | ((double)(s2)>(double)(lipschitztol*s1) & (double)(s1)>(double)(threshold*k));
                    }
                    
                    //
                    // test differentiation properties
                    //
                    for(i=0; i<=n-1; i++)
                    {
                        t = 2*math.randomreal()-1;
                        poldiff2(x, y, n, t, ref v0, ref v1, ref v2);
                        d0 = 0;
                        d1 = 0;
                        d2 = 0;
                        ratint.barycentricdiff1(b1, t, ref d0, ref d1);
                        bcerrors = bcerrors | (double)(Math.Abs(v0-d0))>(double)(threshold*Math.Max(Math.Abs(v0), 1));
                        bcerrors = bcerrors | (double)(Math.Abs(v1-d1))>(double)(threshold*Math.Max(Math.Abs(v1), 1));
                        d0 = 0;
                        d1 = 0;
                        d2 = 0;
                        ratint.barycentricdiff2(b1, t, ref d0, ref d1, ref d2);
                        bcerrors = bcerrors | (double)(Math.Abs(v0-d0))>(double)(threshold*Math.Max(Math.Abs(v0), 1));
                        bcerrors = bcerrors | (double)(Math.Abs(v1-d1))>(double)(threshold*Math.Max(Math.Abs(v1), 1));
                        bcerrors = bcerrors | (double)(Math.Abs(v2-d2))>(double)(Math.Sqrt(threshold)*Math.Max(Math.Abs(v2), 1));
                    }
                    
                    //
                    // test linear translation
                    //
                    t = 2*math.randomreal()-1;
                    a = 2*math.randomreal()-1;
                    b = 2*math.randomreal()-1;
                    brcunset(b2);
                    ratint.barycentriccopy(b1, b2);
                    ratint.barycentriclintransx(b2, a, b);
                    bcerrors = bcerrors | (double)(Math.Abs(ratint.barycentriccalc(b1, a*t+b)-ratint.barycentriccalc(b2, t)))>(double)(threshold);
                    a = 0;
                    b = 2*math.randomreal()-1;
                    brcunset(b2);
                    ratint.barycentriccopy(b1, b2);
                    ratint.barycentriclintransx(b2, a, b);
                    bcerrors = bcerrors | (double)(Math.Abs(ratint.barycentriccalc(b1, a*t+b)-ratint.barycentriccalc(b2, t)))>(double)(threshold);
                    a = 2*math.randomreal()-1;
                    b = 2*math.randomreal()-1;
                    brcunset(b2);
                    ratint.barycentriccopy(b1, b2);
                    ratint.barycentriclintransy(b2, a, b);
                    bcerrors = bcerrors | (double)(Math.Abs(a*ratint.barycentriccalc(b1, t)+b-ratint.barycentriccalc(b2, t)))>(double)(threshold);
                }
            }
            for(pass=0; pass<=3; pass++)
            {
                
                //
                // Crash-test: small numbers, large numbers
                //
                x = new double[4];
                y = new double[4];
                w = new double[4];
                h = 1;
                if( pass%2==0 )
                {
                    h = 100*math.minrealnumber;
                }
                if( pass%2==1 )
                {
                    h = 0.01*math.maxrealnumber;
                }
                x[0] = 0*h;
                x[1] = 1*h;
                x[2] = 2*h;
                x[3] = 3*h;
                y[0] = 0*h;
                y[1] = 1*h;
                y[2] = 2*h;
                y[3] = 3*h;
                w[0] = -(1/(x[1]-x[0]));
                w[1] = 1*(1/(x[1]-x[0])+1/(x[2]-x[1]));
                w[2] = -(1*(1/(x[2]-x[1])+1/(x[3]-x[2])));
                w[3] = 1/(x[3]-x[2]);
                if( pass/2==0 )
                {
                    v0 = 0;
                }
                if( pass/2==1 )
                {
                    v0 = 0.6*h;
                }
                ratint.barycentricbuildxyw(x, y, w, 4, b1);
                t = ratint.barycentriccalc(b1, v0);
                d0 = 0;
                d1 = 0;
                d2 = 0;
                ratint.barycentricdiff1(b1, v0, ref d0, ref d1);
                bcerrors = bcerrors | (double)(Math.Abs(t-v0))>(double)(threshold*v0);
                bcerrors = bcerrors | (double)(Math.Abs(d0-v0))>(double)(threshold*v0);
                bcerrors = bcerrors | (double)(Math.Abs(d1-1))>(double)(1000*threshold);
            }
            
            //
            // crash test: large abscissas, small argument
            //
            // test for errors in D0 is not very strict
            // because renormalization used in Diff1()
            // destroys part of precision.
            //
            x = new double[4];
            y = new double[4];
            w = new double[4];
            h = 0.01*math.maxrealnumber;
            x[0] = 0*h;
            x[1] = 1*h;
            x[2] = 2*h;
            x[3] = 3*h;
            y[0] = 0*h;
            y[1] = 1*h;
            y[2] = 2*h;
            y[3] = 3*h;
            w[0] = -(1/(x[1]-x[0]));
            w[1] = 1*(1/(x[1]-x[0])+1/(x[2]-x[1]));
            w[2] = -(1*(1/(x[2]-x[1])+1/(x[3]-x[2])));
            w[3] = 1/(x[3]-x[2]);
            v0 = 100*math.minrealnumber;
            ratint.barycentricbuildxyw(x, y, w, 4, b1);
            t = ratint.barycentriccalc(b1, v0);
            d0 = 0;
            d1 = 0;
            d2 = 0;
            ratint.barycentricdiff1(b1, v0, ref d0, ref d1);
            bcerrors = bcerrors | (double)(Math.Abs(t))>(double)(v0*(1+threshold));
            bcerrors = bcerrors | (double)(Math.Abs(d0))>(double)(v0*(1+threshold));
            bcerrors = bcerrors | (double)(Math.Abs(d1-1))>(double)(1000*threshold);
            
            //
            // crash test: test safe barycentric formula
            //
            x = new double[4];
            y = new double[4];
            w = new double[4];
            h = 2*math.minrealnumber;
            x[0] = 0*h;
            x[1] = 1*h;
            x[2] = 2*h;
            x[3] = 3*h;
            y[0] = 0*h;
            y[1] = 1*h;
            y[2] = 2*h;
            y[3] = 3*h;
            w[0] = -(1/(x[1]-x[0]));
            w[1] = 1*(1/(x[1]-x[0])+1/(x[2]-x[1]));
            w[2] = -(1*(1/(x[2]-x[1])+1/(x[3]-x[2])));
            w[3] = 1/(x[3]-x[2]);
            v0 = math.minrealnumber;
            ratint.barycentricbuildxyw(x, y, w, 4, b1);
            t = ratint.barycentriccalc(b1, v0);
            bcerrors = bcerrors | (double)(Math.Abs(t-v0)/v0)>(double)(threshold);
            
            //
            // Testing "No Poles" interpolation
            //
            maxerr = 0;
            for(pass=1; pass<=passcount-1; pass++)
            {
                x = new double[1];
                y = new double[1];
                x[0] = 2*math.randomreal()-1;
                y[0] = 2*math.randomreal()-1;
                ratint.barycentricbuildfloaterhormann(x, y, 1, 1, b1);
                maxerr = Math.Max(maxerr, Math.Abs(ratint.barycentriccalc(b1, 2*math.randomreal()-1)-y[0]));
            }
            for(n=2; n<=10; n++)
            {
                
                //
                // compare interpolant built by subroutine
                // with interpolant built by hands
                //
                x = new double[n];
                y = new double[n];
                w = new double[n];
                w2 = new double[n];
                
                //
                // D=1, non-equidistant nodes
                //
                for(pass=1; pass<=passcount; pass++)
                {
                    
                    //
                    // Initialize X, Y, W
                    //
                    a = -1-1*math.randomreal();
                    b = 1+1*math.randomreal();
                    for(i=0; i<=n-1; i++)
                    {
                        x[i] = Math.Atan((b-a)*i/(n-1)+a);
                    }
                    for(i=0; i<=n-1; i++)
                    {
                        y[i] = 2*math.randomreal()-1;
                    }
                    w[0] = -(1/(x[1]-x[0]));
                    s = 1;
                    for(i=1; i<=n-2; i++)
                    {
                        w[i] = s*(1/(x[i]-x[i-1])+1/(x[i+1]-x[i]));
                        s = -s;
                    }
                    w[n-1] = s/(x[n-1]-x[n-2]);
                    for(i=0; i<=n-1; i++)
                    {
                        k = math.randominteger(n);
                        if( k!=i )
                        {
                            t = x[i];
                            x[i] = x[k];
                            x[k] = t;
                            t = y[i];
                            y[i] = y[k];
                            y[k] = t;
                            t = w[i];
                            w[i] = w[k];
                            w[k] = t;
                        }
                    }
                    
                    //
                    // Build and test
                    //
                    ratint.barycentricbuildfloaterhormann(x, y, n, 1, b1);
                    ratint.barycentricbuildxyw(x, y, w, n, b2);
                    for(i=1; i<=2*n; i++)
                    {
                        t = a+(b-a)*math.randomreal();
                        maxerr = Math.Max(maxerr, Math.Abs(ratint.barycentriccalc(b1, t)-ratint.barycentriccalc(b2, t)));
                    }
                }
                
                //
                // D = 0, 1, 2. Equidistant nodes.
                //
                for(d=0; d<=2; d++)
                {
                    for(pass=1; pass<=passcount; pass++)
                    {
                        
                        //
                        // Skip incorrect (N,D) pairs
                        //
                        if( n<2*d )
                        {
                            continue;
                        }
                        
                        //
                        // Initialize X, Y, W
                        //
                        a = -1-1*math.randomreal();
                        b = 1+1*math.randomreal();
                        for(i=0; i<=n-1; i++)
                        {
                            x[i] = (b-a)*i/(n-1)+a;
                        }
                        for(i=0; i<=n-1; i++)
                        {
                            y[i] = 2*math.randomreal()-1;
                        }
                        s = 1;
                        if( d==0 )
                        {
                            for(i=0; i<=n-1; i++)
                            {
                                w[i] = s;
                                s = -s;
                            }
                        }
                        if( d==1 )
                        {
                            w[0] = -s;
                            for(i=1; i<=n-2; i++)
                            {
                                w[i] = 2*s;
                                s = -s;
                            }
                            w[n-1] = s;
                        }
                        if( d==2 )
                        {
                            w[0] = s;
                            w[1] = -(3*s);
                            for(i=2; i<=n-3; i++)
                            {
                                w[i] = 4*s;
                                s = -s;
                            }
                            w[n-2] = 3*s;
                            w[n-1] = -s;
                        }
                        
                        //
                        // Mix
                        //
                        for(i=0; i<=n-1; i++)
                        {
                            k = math.randominteger(n);
                            if( k!=i )
                            {
                                t = x[i];
                                x[i] = x[k];
                                x[k] = t;
                                t = y[i];
                                y[i] = y[k];
                                y[k] = t;
                                t = w[i];
                                w[i] = w[k];
                                w[k] = t;
                            }
                        }
                        
                        //
                        // Build and test
                        //
                        ratint.barycentricbuildfloaterhormann(x, y, n, d, b1);
                        ratint.barycentricbuildxyw(x, y, w, n, b2);
                        for(i=1; i<=2*n; i++)
                        {
                            t = a+(b-a)*math.randomreal();
                            maxerr = Math.Max(maxerr, Math.Abs(ratint.barycentriccalc(b1, t)-ratint.barycentriccalc(b2, t)));
                        }
                    }
                }
            }
            if( (double)(maxerr)>(double)(threshold) )
            {
                nperrors = true;
            }
            
            //
            // Test rational fitting:
            //
            for(pass=1; pass<=passcount; pass++)
            {
                for(n=2; n<=maxn; n++)
                {
                    
                    //
                    // N=M+K fitting (i.e. interpolation)
                    //
                    for(k=0; k<=n-1; k++)
                    {
                        x = new double[n-k];
                        y = new double[n-k];
                        w = new double[n-k];
                        if( k>0 )
                        {
                            xc = new double[k];
                            yc = new double[k];
                            dc = new int[k];
                        }
                        for(i=0; i<=n-k-1; i++)
                        {
                            x[i] = (double)i/(double)(n-1);
                            y[i] = 2*math.randomreal()-1;
                            w[i] = 1+math.randomreal();
                        }
                        for(i=0; i<=k-1; i++)
                        {
                            xc[i] = (double)(n-k+i)/(double)(n-1);
                            yc[i] = 2*math.randomreal()-1;
                            dc[i] = 0;
                        }
                        ratint.barycentricfitfloaterhormannwc(x, y, w, n-k, xc, yc, dc, k, n, ref info, b1, rep);
                        if( info<=0 )
                        {
                            fiterrors = true;
                        }
                        else
                        {
                            for(i=0; i<=n-k-1; i++)
                            {
                                fiterrors = fiterrors | (double)(Math.Abs(ratint.barycentriccalc(b1, x[i])-y[i]))>(double)(threshold);
                            }
                            for(i=0; i<=k-1; i++)
                            {
                                fiterrors = fiterrors | (double)(Math.Abs(ratint.barycentriccalc(b1, xc[i])-yc[i]))>(double)(threshold);
                            }
                        }
                    }
                    
                    //
                    // Testing constraints on derivatives:
                    // * several M's are tried
                    // * several K's are tried - 1, 2.
                    // * constraints at the ends of the interval
                    //
                    for(m=3; m<=5; m++)
                    {
                        for(k=1; k<=2; k++)
                        {
                            x = new double[n];
                            y = new double[n];
                            w = new double[n];
                            xc = new double[2];
                            yc = new double[2];
                            dc = new int[2];
                            for(i=0; i<=n-1; i++)
                            {
                                x[i] = 2*math.randomreal()-1;
                                y[i] = 2*math.randomreal()-1;
                                w[i] = 1+math.randomreal();
                            }
                            xc[0] = -1;
                            yc[0] = 2*math.randomreal()-1;
                            dc[0] = 0;
                            xc[1] = 1;
                            yc[1] = 2*math.randomreal()-1;
                            dc[1] = 0;
                            ratint.barycentricfitfloaterhormannwc(x, y, w, n, xc, yc, dc, k, m, ref info, b1, rep);
                            if( info<=0 )
                            {
                                fiterrors = true;
                            }
                            else
                            {
                                for(i=0; i<=k-1; i++)
                                {
                                    ratint.barycentricdiff1(b1, xc[i], ref v0, ref v1);
                                    fiterrors = fiterrors | (double)(Math.Abs(v0-yc[i]))>(double)(threshold);
                                }
                            }
                        }
                    }
                }
            }
            for(m=2; m<=8; m++)
            {
                for(pass=1; pass<=passcount; pass++)
                {
                    
                    //
                    // General fitting
                    //
                    // interpolating function through M nodes should have
                    // greater RMS error than fitting it through the same M nodes
                    //
                    n = 100;
                    x2 = new double[n];
                    y2 = new double[n];
                    w2 = new double[n];
                    xmin = math.maxrealnumber;
                    xmax = -math.maxrealnumber;
                    for(i=0; i<=n-1; i++)
                    {
                        x2[i] = 2*Math.PI*math.randomreal();
                        y2[i] = Math.Sin(x2[i]);
                        w2[i] = 1;
                        xmin = Math.Min(xmin, x2[i]);
                        xmax = Math.Max(xmax, x2[i]);
                    }
                    x = new double[m];
                    y = new double[m];
                    for(i=0; i<=m-1; i++)
                    {
                        x[i] = xmin+(xmax-xmin)*i/(m-1);
                        y[i] = Math.Sin(x[i]);
                    }
                    ratint.barycentricbuildfloaterhormann(x, y, m, 3, b1);
                    ratint.barycentricfitfloaterhormannwc(x2, y2, w2, n, xc, yc, dc, 0, m, ref info, b2, rep);
                    if( info<=0 )
                    {
                        fiterrors = true;
                    }
                    else
                    {
                        
                        //
                        // calculate B1 (interpolant) RMS error, compare with B2 error
                        //
                        v1 = 0;
                        v2 = 0;
                        for(i=0; i<=n-1; i++)
                        {
                            v1 = v1+math.sqr(ratint.barycentriccalc(b1, x2[i])-y2[i]);
                            v2 = v2+math.sqr(ratint.barycentriccalc(b2, x2[i])-y2[i]);
                        }
                        v1 = Math.Sqrt(v1/n);
                        v2 = Math.Sqrt(v2/n);
                        fiterrors = fiterrors | (double)(v2)>(double)(v1);
                        fiterrors = fiterrors | (double)(Math.Abs(v2-rep.rmserror))>(double)(threshold);
                    }
                    
                    //
                    // compare weighted and non-weighted
                    //
                    n = 20;
                    x = new double[n];
                    y = new double[n];
                    w = new double[n];
                    for(i=0; i<=n-1; i++)
                    {
                        x[i] = 2*math.randomreal()-1;
                        y[i] = 2*math.randomreal()-1;
                        w[i] = 1;
                    }
                    ratint.barycentricfitfloaterhormannwc(x, y, w, n, xc, yc, dc, 0, m, ref info, b1, rep);
                    ratint.barycentricfitfloaterhormann(x, y, n, m, ref info2, b2, rep2);
                    if( info<=0 | info2<=0 )
                    {
                        fiterrors = true;
                    }
                    else
                    {
                        
                        //
                        // calculate B1 (interpolant), compare with B2
                        // compare RMS errors
                        //
                        t = 2*math.randomreal()-1;
                        v1 = ratint.barycentriccalc(b1, t);
                        v2 = ratint.barycentriccalc(b2, t);
                        fiterrors = fiterrors | (double)(v2)!=(double)(v1);
                        fiterrors = fiterrors | (double)(rep.rmserror)!=(double)(rep2.rmserror);
                        fiterrors = fiterrors | (double)(rep.avgerror)!=(double)(rep2.avgerror);
                        fiterrors = fiterrors | (double)(rep.avgrelerror)!=(double)(rep2.avgrelerror);
                        fiterrors = fiterrors | (double)(rep.maxerror)!=(double)(rep2.maxerror);
                    }
                }
            }
            for(pass=1; pass<=passcount; pass++)
            {
                ap.assert(passcount>=2, "PassCount should be 2 or greater!");
                
                //
                // solve simple task (all X[] are the same, Y[] are specially
                // calculated to ensure simple form of all types of errors)
                // and check correctness of the errors calculated by subroutines
                //
                // First pass is done with zero Y[], other passes - with random Y[].
                // It should test both ability to correctly calculate errors and
                // ability to not fail while working with zeros :)
                //
                n = 4;
                if( pass==1 )
                {
                    v1 = 0;
                    v2 = 0;
                    v = 0;
                }
                else
                {
                    v1 = math.randomreal();
                    v2 = math.randomreal();
                    v = 1+math.randomreal();
                }
                x = new double[4];
                y = new double[4];
                w = new double[4];
                x[0] = 0;
                y[0] = v-v2;
                w[0] = 1;
                x[1] = 0;
                y[1] = v-v1;
                w[1] = 1;
                x[2] = 0;
                y[2] = v+v1;
                w[2] = 1;
                x[3] = 0;
                y[3] = v+v2;
                w[3] = 1;
                refrms = Math.Sqrt((math.sqr(v1)+math.sqr(v2))/2);
                refavg = (Math.Abs(v1)+Math.Abs(v2))/2;
                if( pass==1 )
                {
                    refavgrel = 0;
                }
                else
                {
                    refavgrel = 0.25*(Math.Abs(v2)/Math.Abs(v-v2)+Math.Abs(v1)/Math.Abs(v-v1)+Math.Abs(v1)/Math.Abs(v+v1)+Math.Abs(v2)/Math.Abs(v+v2));
                }
                refmax = Math.Max(v1, v2);
                
                //
                // Test errors correctness
                //
                ratint.barycentricfitfloaterhormann(x, y, 4, 2, ref info, b1, rep);
                if( info<=0 )
                {
                    fiterrors = true;
                }
                else
                {
                    s = ratint.barycentriccalc(b1, 0);
                    fiterrors = fiterrors | (double)(Math.Abs(s-v))>(double)(threshold);
                    fiterrors = fiterrors | (double)(Math.Abs(rep.rmserror-refrms))>(double)(threshold);
                    fiterrors = fiterrors | (double)(Math.Abs(rep.avgerror-refavg))>(double)(threshold);
                    fiterrors = fiterrors | (double)(Math.Abs(rep.avgrelerror-refavgrel))>(double)(threshold);
                    fiterrors = fiterrors | (double)(Math.Abs(rep.maxerror-refmax))>(double)(threshold);
                }
            }
            
            //
            // report
            //
            waserrors = (bcerrors | nperrors) | fiterrors;
            if( !silent )
            {
                System.Console.Write("TESTING RATIONAL INTERPOLATION");
                System.Console.WriteLine();
                System.Console.Write("BASIC BARYCENTRIC FUNCTIONS:             ");
                if( bcerrors )
                {
                    System.Console.Write("FAILED");
                    System.Console.WriteLine();
                }
                else
                {
                    System.Console.Write("OK");
                    System.Console.WriteLine();
                }
                System.Console.Write("FLOATER-HORMANN:                         ");
                if( nperrors )
                {
                    System.Console.Write("FAILED");
                    System.Console.WriteLine();
                }
                else
                {
                    System.Console.Write("OK");
                    System.Console.WriteLine();
                }
                System.Console.Write("RATIONAL FITTING:                        ");
                if( fiterrors )
                {
                    System.Console.Write("FAILED");
                    System.Console.WriteLine();
                }
                else
                {
                    System.Console.Write("OK");
                    System.Console.WriteLine();
                }
                if( waserrors )
                {
                    System.Console.Write("TEST FAILED");
                    System.Console.WriteLine();
                }
                else
                {
                    System.Console.Write("TEST PASSED");
                    System.Console.WriteLine();
                }
                System.Console.WriteLine();
                System.Console.WriteLine();
            }
            
            //
            // end
            //
            result = !waserrors;
            return result;
        }
Example #2
0
    public static int Main(string[] args)
    {
        int m = 0;
        int n = 0;
        int d = 0;

        double[] x  = new double[0];
        double[] y  = new double[0];
        double[] w  = new double[0];
        double[] xc = new double[0];
        double[] yc = new double[0];
        int[]    dc = new int[0];
        ratint.barycentricfitreport rep = new ratint.barycentricfitreport();
        int info = 0;

        ratint.barycentricinterpolant r = new ratint.barycentricinterpolant();
        int    i  = 0;
        int    j  = 0;
        double a  = 0;
        double b  = 0;
        double v  = 0;
        double dv = 0;

        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.Write("Fitting exp(2*x) at [-1,+1] by:");
        System.Console.WriteLine();
        System.Console.Write("1. constrained/unconstrained Floater-Hormann functions");
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.Write("Fit type                rms.err max.err    p(0)   dp(0)  DBest");
        System.Console.WriteLine();

        //
        // Prepare points
        //
        m = 5;
        a = -1;
        b = +1;
        n = 10000;
        x = new double[n];
        y = new double[n];
        w = new double[n];
        for (i = 0; i <= n - 1; i++)
        {
            x[i] = a + (b - a) * i / (n - 1);
            y[i] = Math.Exp(2 * x[i]);
            w[i] = 1.0;
        }

        //
        // Fitting:
        // a) f(x)=exp(2*x) at [-1,+1]
        // b) by 5 Floater-Hormann functions
        // c) without constraints
        //
        ratint.barycentricfitfloaterhormann(ref x, ref y, n, m, ref info, ref r, ref rep);
        ratint.barycentricdiff1(ref r, 0.0, ref v, ref dv);
        System.Console.Write("Unconstrained FH        ");
        System.Console.Write("{0,7:F4}", rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", v);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", dv);
        System.Console.Write("      ");
        System.Console.Write("{0,0:d}", rep.dbest);
        System.Console.WriteLine();

        //
        // Fitting:
        // a) f(x)=exp(2*x) at [-1,+1]
        // b) by 5 Floater-Hormann functions
        // c) constrained: p(0)=1
        //
        xc    = new double[1];
        yc    = new double[1];
        dc    = new int[1];
        xc[0] = 0;
        yc[0] = 1;
        dc[0] = 0;
        ratint.barycentricfitfloaterhormannwc(ref x, ref y, ref w, n, ref xc, ref yc, ref dc, 1, m, ref info, ref r, ref rep);
        ratint.barycentricdiff1(ref r, 0.0, ref v, ref dv);
        System.Console.Write("Constrained FH, p(0)=1  ");
        System.Console.Write("{0,7:F4}", rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", v);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", dv);
        System.Console.Write("      ");
        System.Console.Write("{0,0:d}", rep.dbest);
        System.Console.WriteLine();

        //
        // Fitting:
        // a) f(x)=exp(2*x) at [-1,+1]
        // b) by 5 Floater-Hormann functions
        // c) constrained: dp(0)=2
        //
        xc    = new double[1];
        yc    = new double[1];
        dc    = new int[1];
        xc[0] = 0;
        yc[0] = 2;
        dc[0] = 1;
        ratint.barycentricfitfloaterhormannwc(ref x, ref y, ref w, n, ref xc, ref yc, ref dc, 1, m, ref info, ref r, ref rep);
        ratint.barycentricdiff1(ref r, 0.0, ref v, ref dv);
        System.Console.Write("Constrained FH, dp(0)=2 ");
        System.Console.Write("{0,7:F4}", rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", v);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", dv);
        System.Console.Write("      ");
        System.Console.Write("{0,0:d}", rep.dbest);
        System.Console.WriteLine();

        //
        // Fitting:
        // a) f(x)=exp(2*x) at [-1,+1]
        // b) by 5 Floater-Hormann functions
        // c) constrained: p(0)=1, dp(0)=2
        //
        xc    = new double[2];
        yc    = new double[2];
        dc    = new int[2];
        xc[0] = 0;
        yc[0] = 1;
        dc[0] = 0;
        xc[1] = 0;
        yc[1] = 2;
        dc[1] = 1;
        ratint.barycentricfitfloaterhormannwc(ref x, ref y, ref w, n, ref xc, ref yc, ref dc, 2, m, ref info, ref r, ref rep);
        ratint.barycentricdiff1(ref r, 0.0, ref v, ref dv);
        System.Console.Write("Constrained FH, both    ");
        System.Console.Write("{0,7:F4}", rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", v);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", dv);
        System.Console.Write("      ");
        System.Console.Write("{0,0:d}", rep.dbest);
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.WriteLine();
        return(0);
    }
 public barycentricfitreport(ratint.barycentricfitreport obj)
 {
     _innerobj = obj;
 }
    public static int Main(string[] args)
    {
        int m = 0;
        int n = 0;
        int d = 0;
        double[] x = new double[0];
        double[] y = new double[0];
        double[] w = new double[0];
        double[] xc = new double[0];
        double[] yc = new double[0];
        int[] dc = new int[0];
        ratint.barycentricfitreport rep = new ratint.barycentricfitreport();
        int info = 0;
        ratint.barycentricinterpolant r = new ratint.barycentricinterpolant();
        int i = 0;
        int j = 0;
        double a = 0;
        double b = 0;
        double v = 0;
        double dv = 0;

        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.Write("Fitting exp(2*x) at [-1,+1] by:");
        System.Console.WriteLine();
        System.Console.Write("1. constrained/unconstrained Floater-Hormann functions");
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.Write("Fit type                rms.err max.err    p(0)   dp(0)  DBest");
        System.Console.WriteLine();
        
        //
        // Prepare points
        //
        m = 5;
        a = -1;
        b = +1;
        n = 10000;
        x = new double[n];
        y = new double[n];
        w = new double[n];
        for(i=0; i<=n-1; i++)
        {
            x[i] = a+(b-a)*i/(n-1);
            y[i] = Math.Exp(2*x[i]);
            w[i] = 1.0;
        }
        
        //
        // Fitting:
        // a) f(x)=exp(2*x) at [-1,+1]
        // b) by 5 Floater-Hormann functions
        // c) without constraints
        //
        ratint.barycentricfitfloaterhormann(ref x, ref y, n, m, ref info, ref r, ref rep);
        ratint.barycentricdiff1(ref r, 0.0, ref v, ref dv);
        System.Console.Write("Unconstrained FH        ");
        System.Console.Write("{0,7:F4}",rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",v);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",dv);
        System.Console.Write("      ");
        System.Console.Write("{0,0:d}",rep.dbest);
        System.Console.WriteLine();
        
        //
        // Fitting:
        // a) f(x)=exp(2*x) at [-1,+1]
        // b) by 5 Floater-Hormann functions
        // c) constrained: p(0)=1
        //
        xc = new double[1];
        yc = new double[1];
        dc = new int[1];
        xc[0] = 0;
        yc[0] = 1;
        dc[0] = 0;
        ratint.barycentricfitfloaterhormannwc(ref x, ref y, ref w, n, ref xc, ref yc, ref dc, 1, m, ref info, ref r, ref rep);
        ratint.barycentricdiff1(ref r, 0.0, ref v, ref dv);
        System.Console.Write("Constrained FH, p(0)=1  ");
        System.Console.Write("{0,7:F4}",rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",v);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",dv);
        System.Console.Write("      ");
        System.Console.Write("{0,0:d}",rep.dbest);
        System.Console.WriteLine();
        
        //
        // Fitting:
        // a) f(x)=exp(2*x) at [-1,+1]
        // b) by 5 Floater-Hormann functions
        // c) constrained: dp(0)=2
        //
        xc = new double[1];
        yc = new double[1];
        dc = new int[1];
        xc[0] = 0;
        yc[0] = 2;
        dc[0] = 1;
        ratint.barycentricfitfloaterhormannwc(ref x, ref y, ref w, n, ref xc, ref yc, ref dc, 1, m, ref info, ref r, ref rep);
        ratint.barycentricdiff1(ref r, 0.0, ref v, ref dv);
        System.Console.Write("Constrained FH, dp(0)=2 ");
        System.Console.Write("{0,7:F4}",rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",v);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",dv);
        System.Console.Write("      ");
        System.Console.Write("{0,0:d}",rep.dbest);
        System.Console.WriteLine();
        
        //
        // Fitting:
        // a) f(x)=exp(2*x) at [-1,+1]
        // b) by 5 Floater-Hormann functions
        // c) constrained: p(0)=1, dp(0)=2
        //
        xc = new double[2];
        yc = new double[2];
        dc = new int[2];
        xc[0] = 0;
        yc[0] = 1;
        dc[0] = 0;
        xc[1] = 0;
        yc[1] = 2;
        dc[1] = 1;
        ratint.barycentricfitfloaterhormannwc(ref x, ref y, ref w, n, ref xc, ref yc, ref dc, 2, m, ref info, ref r, ref rep);
        ratint.barycentricdiff1(ref r, 0.0, ref v, ref dv);
        System.Console.Write("Constrained FH, both    ");
        System.Console.Write("{0,7:F4}",rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",v);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",dv);
        System.Console.Write("      ");
        System.Console.Write("{0,0:d}",rep.dbest);
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.WriteLine();
        return 0;
    }
 public barycentricfitreport()
 {
     _innerobj = new ratint.barycentricfitreport();
 }