/*************************************************************************
        Test
        *************************************************************************/
        public static bool testodesolver(bool silent)
        {
            bool result = new bool();
            int passcount = 0;
            bool curerrors = new bool();
            bool rkckerrors = new bool();
            bool waserrors = new bool();
            double[] xtbl = new double[0];
            double[,] ytbl = new double[0,0];
            odesolver.odesolverreport rep = new odesolver.odesolverreport();
            double[] xg = new double[0];
            double[] y = new double[0];
            double h = 0;
            double eps = 0;
            int solver = 0;
            int pass = 0;
            int mynfev = 0;
            double v = 0;
            int n = 0;
            int m = 0;
            int m2 = 0;
            int i = 0;
            double err = 0;
            odesolver.odesolverstate state = new odesolver.odesolverstate();
            int i_ = 0;

            rkckerrors = false;
            waserrors = false;
            passcount = 10;
            
            //
            // simple test: just A*sin(x)+B*cos(x)
            //
            System.Diagnostics.Debug.Assert(passcount>=2);
            for(pass=0; pass<=passcount-1; pass++)
            {
                for(solver=0; solver<=0; solver++)
                {
                    
                    //
                    // prepare
                    //
                    h = 1.0E-2;
                    eps = 1.0E-5;
                    if( pass%2==0 )
                    {
                        eps = -eps;
                    }
                    y = new double[2];
                    for(i=0; i<=1; i++)
                    {
                        y[i] = 2*AP.Math.RandomReal()-1;
                    }
                    m = 2+AP.Math.RandomInteger(10);
                    xg = new double[m];
                    xg[0] = (m-1)*AP.Math.RandomReal();
                    for(i=1; i<=m-1; i++)
                    {
                        xg[i] = xg[i-1]+AP.Math.RandomReal();
                    }
                    v = 2*Math.PI/(xg[m-1]-xg[0]);
                    for(i_=0; i_<=m-1;i_++)
                    {
                        xg[i_] = v*xg[i_];
                    }
                    if( (double)(AP.Math.RandomReal())>(double)(0.5) )
                    {
                        for(i_=0; i_<=m-1;i_++)
                        {
                            xg[i_] = -1*xg[i_];
                        }
                    }
                    mynfev = 0;
                    
                    //
                    // choose solver
                    //
                    if( solver==0 )
                    {
                        odesolver.odesolverrkck(ref y, 2, ref xg, m, eps, h, ref state);
                    }
                    
                    //
                    // solve
                    //
                    while( odesolver.odesolveriteration(ref state) )
                    {
                        state.dy[0] = state.y[1];
                        state.dy[1] = -state.y[0];
                        mynfev = mynfev+1;
                    }
                    odesolver.odesolverresults(ref state, ref m2, ref xtbl, ref ytbl, ref rep);
                    
                    //
                    // check results
                    //
                    curerrors = false;
                    if( rep.terminationtype<=0 )
                    {
                        curerrors = true;
                    }
                    else
                    {
                        curerrors = curerrors | m2!=m;
                        err = 0;
                        for(i=0; i<=m-1; i++)
                        {
                            err = Math.Max(err, Math.Abs(ytbl[i,0]-(+(y[0]*Math.Cos(xtbl[i]-xtbl[0]))+y[1]*Math.Sin(xtbl[i]-xtbl[0]))));
                            err = Math.Max(err, Math.Abs(ytbl[i,1]-(-(y[0]*Math.Sin(xtbl[i]-xtbl[0]))+y[1]*Math.Cos(xtbl[i]-xtbl[0]))));
                        }
                        curerrors = curerrors | (double)(err)>(double)(10*Math.Abs(eps));
                        curerrors = curerrors | mynfev!=rep.nfev;
                    }
                    if( solver==0 )
                    {
                        rkckerrors = rkckerrors | curerrors;
                    }
                }
            }
            
            //
            // another test:
            //
            //     y(0)   = 0
            //     dy/dx  = f(x,y)
            //     f(x,y) = 0,   x<1
            //              x-1, x>=1
            //
            // with BOTH absolute and fractional tolerances.
            // Starting from zero will be real challenge for
            // fractional tolerance.
            //
            System.Diagnostics.Debug.Assert(passcount>=2);
            for(pass=0; pass<=passcount-1; pass++)
            {
                h = 1.0E-4;
                eps = 1.0E-4;
                if( pass%2==0 )
                {
                    eps = -eps;
                }
                y = new double[1];
                y[0] = 0;
                m = 21;
                xg = new double[m];
                for(i=0; i<=m-1; i++)
                {
                    xg[i] = (double)(2*i)/((double)(m-1));
                }
                mynfev = 0;
                odesolver.odesolverrkck(ref y, 1, ref xg, m, eps, h, ref state);
                while( odesolver.odesolveriteration(ref state) )
                {
                    state.dy[0] = Math.Max(state.x-1, 0);
                    mynfev = mynfev+1;
                }
                odesolver.odesolverresults(ref state, ref m2, ref xtbl, ref ytbl, ref rep);
                if( rep.terminationtype<=0 )
                {
                    rkckerrors = true;
                }
                else
                {
                    rkckerrors = rkckerrors | m2!=m;
                    err = 0;
                    for(i=0; i<=m-1; i++)
                    {
                        err = Math.Max(err, Math.Abs(ytbl[i,0]-AP.Math.Sqr(Math.Max(xg[i]-1, 0))/2));
                    }
                    rkckerrors = rkckerrors | (double)(err)>(double)(Math.Abs(eps));
                    rkckerrors = rkckerrors | mynfev!=rep.nfev;
                }
            }
            
            //
            // end
            //
            waserrors = rkckerrors;
            if( !silent )
            {
                System.Console.Write("TESTING ODE SOLVER");
                System.Console.WriteLine();
                System.Console.Write("* RK CASH-KARP:                           ");
                if( rkckerrors )
                {
                    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();
                }
            }
            result = !waserrors;
            return result;
        }
Example #2
0
        /*************************************************************************
        *  Test
        *************************************************************************/
        public static bool testodesolver(bool silent)
        {
            bool result     = new bool();
            int  passcount  = 0;
            bool curerrors  = new bool();
            bool rkckerrors = new bool();
            bool waserrors  = new bool();

            double[] xtbl = new double[0];
            double[,] ytbl = new double[0, 0];
            odesolver.odesolverreport rep = new odesolver.odesolverreport();
            double[] xg     = new double[0];
            double[] y      = new double[0];
            double   h      = 0;
            double   eps    = 0;
            int      solver = 0;
            int      pass   = 0;
            int      mynfev = 0;
            double   v      = 0;
            int      n      = 0;
            int      m      = 0;
            int      m2     = 0;
            int      i      = 0;
            double   err    = 0;

            odesolver.odesolverstate state = new odesolver.odesolverstate();
            int i_ = 0;

            rkckerrors = false;
            waserrors  = false;
            passcount  = 10;

            //
            // simple test: just A*sin(x)+B*cos(x)
            //
            System.Diagnostics.Debug.Assert(passcount >= 2);
            for (pass = 0; pass <= passcount - 1; pass++)
            {
                for (solver = 0; solver <= 0; solver++)
                {
                    //
                    // prepare
                    //
                    h   = 1.0E-2;
                    eps = 1.0E-5;
                    if (pass % 2 == 0)
                    {
                        eps = -eps;
                    }
                    y = new double[2];
                    for (i = 0; i <= 1; i++)
                    {
                        y[i] = 2 * AP.Math.RandomReal() - 1;
                    }
                    m     = 2 + AP.Math.RandomInteger(10);
                    xg    = new double[m];
                    xg[0] = (m - 1) * AP.Math.RandomReal();
                    for (i = 1; i <= m - 1; i++)
                    {
                        xg[i] = xg[i - 1] + AP.Math.RandomReal();
                    }
                    v = 2 * Math.PI / (xg[m - 1] - xg[0]);
                    for (i_ = 0; i_ <= m - 1; i_++)
                    {
                        xg[i_] = v * xg[i_];
                    }
                    if ((double)(AP.Math.RandomReal()) > (double)(0.5))
                    {
                        for (i_ = 0; i_ <= m - 1; i_++)
                        {
                            xg[i_] = -1 * xg[i_];
                        }
                    }
                    mynfev = 0;

                    //
                    // choose solver
                    //
                    if (solver == 0)
                    {
                        odesolver.odesolverrkck(ref y, 2, ref xg, m, eps, h, ref state);
                    }

                    //
                    // solve
                    //
                    while (odesolver.odesolveriteration(ref state))
                    {
                        state.dy[0] = state.y[1];
                        state.dy[1] = -state.y[0];
                        mynfev      = mynfev + 1;
                    }
                    odesolver.odesolverresults(ref state, ref m2, ref xtbl, ref ytbl, ref rep);

                    //
                    // check results
                    //
                    curerrors = false;
                    if (rep.terminationtype <= 0)
                    {
                        curerrors = true;
                    }
                    else
                    {
                        curerrors = curerrors | m2 != m;
                        err       = 0;
                        for (i = 0; i <= m - 1; i++)
                        {
                            err = Math.Max(err, Math.Abs(ytbl[i, 0] - (+(y[0] * Math.Cos(xtbl[i] - xtbl[0])) + y[1] * Math.Sin(xtbl[i] - xtbl[0]))));
                            err = Math.Max(err, Math.Abs(ytbl[i, 1] - (-(y[0] * Math.Sin(xtbl[i] - xtbl[0])) + y[1] * Math.Cos(xtbl[i] - xtbl[0]))));
                        }
                        curerrors = curerrors | (double)(err) > (double)(10 * Math.Abs(eps));
                        curerrors = curerrors | mynfev != rep.nfev;
                    }
                    if (solver == 0)
                    {
                        rkckerrors = rkckerrors | curerrors;
                    }
                }
            }

            //
            // another test:
            //
            //     y(0)   = 0
            //     dy/dx  = f(x,y)
            //     f(x,y) = 0,   x<1
            //              x-1, x>=1
            //
            // with BOTH absolute and fractional tolerances.
            // Starting from zero will be real challenge for
            // fractional tolerance.
            //
            System.Diagnostics.Debug.Assert(passcount >= 2);
            for (pass = 0; pass <= passcount - 1; pass++)
            {
                h   = 1.0E-4;
                eps = 1.0E-4;
                if (pass % 2 == 0)
                {
                    eps = -eps;
                }
                y    = new double[1];
                y[0] = 0;
                m    = 21;
                xg   = new double[m];
                for (i = 0; i <= m - 1; i++)
                {
                    xg[i] = (double)(2 * i) / ((double)(m - 1));
                }
                mynfev = 0;
                odesolver.odesolverrkck(ref y, 1, ref xg, m, eps, h, ref state);
                while (odesolver.odesolveriteration(ref state))
                {
                    state.dy[0] = Math.Max(state.x - 1, 0);
                    mynfev      = mynfev + 1;
                }
                odesolver.odesolverresults(ref state, ref m2, ref xtbl, ref ytbl, ref rep);
                if (rep.terminationtype <= 0)
                {
                    rkckerrors = true;
                }
                else
                {
                    rkckerrors = rkckerrors | m2 != m;
                    err        = 0;
                    for (i = 0; i <= m - 1; i++)
                    {
                        err = Math.Max(err, Math.Abs(ytbl[i, 0] - AP.Math.Sqr(Math.Max(xg[i] - 1, 0)) / 2));
                    }
                    rkckerrors = rkckerrors | (double)(err) > (double)(Math.Abs(eps));
                    rkckerrors = rkckerrors | mynfev != rep.nfev;
                }
            }

            //
            // end
            //
            waserrors = rkckerrors;
            if (!silent)
            {
                System.Console.Write("TESTING ODE SOLVER");
                System.Console.WriteLine();
                System.Console.Write("* RK CASH-KARP:                           ");
                if (rkckerrors)
                {
                    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();
                }
            }
            result = !waserrors;
            return(result);
        }