Exemple #1
0
        /*************************************************************************
        *  ODE solver results
        *
        *  Called after OdeSolverIteration returned False.
        *
        *  INPUT PARAMETERS:
        *   State   -   algorithm state (used by OdeSolverIteration).
        *
        *  OUTPUT PARAMETERS:
        *   M       -   number of tabulated values, M>=1
        *   XTbl    -   array[0..M-1], values of X
        *   YTbl    -   array[0..M-1,0..N-1], values of Y in X[i]
        *   Rep     -   solver report:
        * Rep.TerminationType completetion code:
        * -2    X is not ordered  by  ascending/descending  or
        *                           there are non-distinct X[],  i.e.  X[i]=X[i+1]
        * -1    incorrect parameters were specified
        *  1    task has been solved
        * Rep.NFEV contains number of function calculations
        *
        *  -- ALGLIB --
        *    Copyright 01.09.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void odesolverresults(ref odesolverstate state,
                                            ref int m,
                                            ref double[] xtbl,
                                            ref double[,] ytbl,
                                            ref odesolverreport rep)
        {
            double v  = 0;
            int    i  = 0;
            int    i_ = 0;

            rep.terminationtype = state.repterminationtype;
            if (rep.terminationtype > 0)
            {
                m        = state.m;
                rep.nfev = state.repnfev;
                xtbl     = new double[state.m];
                v        = state.xscale;
                for (i_ = 0; i_ <= state.m - 1; i_++)
                {
                    xtbl[i_] = v * state.xg[i_];
                }
                ytbl = new double[state.m, state.n];
                for (i = 0; i <= state.m - 1; i++)
                {
                    for (i_ = 0; i_ <= state.n - 1; i_++)
                    {
                        ytbl[i, i_] = state.ytbl[i, i_];
                    }
                }
            }
            else
            {
                rep.nfev = 0;
            }
        }
            public override alglib.apobject make_copy()
            {
                odesolverstate _result = new odesolverstate();

                _result.n                  = n;
                _result.m                  = m;
                _result.xscale             = xscale;
                _result.h                  = h;
                _result.eps                = eps;
                _result.fraceps            = fraceps;
                _result.yc                 = (double[])yc.Clone();
                _result.escale             = (double[])escale.Clone();
                _result.xg                 = (double[])xg.Clone();
                _result.solvertype         = solvertype;
                _result.needdy             = needdy;
                _result.x                  = x;
                _result.y                  = (double[])y.Clone();
                _result.dy                 = (double[])dy.Clone();
                _result.ytbl               = (double[, ])ytbl.Clone();
                _result.repterminationtype = repterminationtype;
                _result.repnfev            = repnfev;
                _result.yn                 = (double[])yn.Clone();
                _result.yns                = (double[])yns.Clone();
                _result.rka                = (double[])rka.Clone();
                _result.rkc                = (double[])rkc.Clone();
                _result.rkcs               = (double[])rkcs.Clone();
                _result.rkb                = (double[, ])rkb.Clone();
                _result.rkk                = (double[, ])rkk.Clone();
                _result.rstate             = (rcommstate)rstate.make_copy();
                return(_result);
            }
Exemple #3
0
 public static void odesolverresults(odesolverstate state, out int m, out double[] xtbl, out double[,] ytbl, out odesolverreport rep, alglib.xparams _params)
 {
     m    = 0;
     xtbl = new double[0];
     ytbl = new double[0, 0];
     rep  = new odesolverreport();
     odesolver.odesolverresults(state.innerobj, ref m, ref xtbl, ref ytbl, rep.innerobj, _params);
 }
 /*************************************************************************
 *  ODE solver results
 *
 *  Called after OdeSolverIteration returned False.
 *
 *  INPUT PARAMETERS:
 *   State   -   algorithm state (used by OdeSolverIteration).
 *
 *  OUTPUT PARAMETERS:
 *   M       -   number of tabulated values, M>=1
 *   XTbl    -   array[0..M-1], values of X
 *   YTbl    -   array[0..M-1,0..N-1], values of Y in X[i]
 *   Rep     -   solver report:
 * Rep.TerminationType completetion code:
 * -2    X is not ordered  by  ascending/descending  or
 *                           there are non-distinct X[],  i.e.  X[i]=X[i+1]
 * -1    incorrect parameters were specified
 *  1    task has been solved
 * Rep.NFEV contains number of function calculations
 *
 *  -- ALGLIB --
 *    Copyright 01.09.2009 by Bochkanov Sergey
 *************************************************************************/
 public static void odesolverresults(odesolverstate state, out int m, out double[] xtbl, out double[,] ytbl, out odesolverreport rep)
 {
     m    = 0;
     xtbl = new double[0];
     ytbl = new double[0, 0];
     rep  = new odesolverreport();
     odesolver.odesolverresults(state.innerobj, ref m, ref xtbl, ref ytbl, rep.innerobj);
     return;
 }
Exemple #5
0
 /*************************************************************************
 *  Cash-Karp adaptive ODE solver.
 *
 *  This subroutine solves ODE  Y'=f(Y,x)  with  initial  conditions  Y(xs)=Ys
 *  (here Y may be single variable or vector of N variables).
 *
 *  INPUT PARAMETERS:
 *   Y       -   initial conditions, array[0..N-1].
 *               contains values of Y[] at X[0]
 *   N       -   system size
 *   X       -   points at which Y should be tabulated, array[0..M-1]
 *               integrations starts at X[0], ends at X[M-1],  intermediate
 *               values at X[i] are returned too.
 *               SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!!!!
 *   M       -   number of intermediate points + first point + last point:
 * M>2 means that you need both Y(X[M-1]) and M-2 values at
 *                 intermediate points
 * M=2 means that you want just to integrate from  X[0]  to
 *                 X[1] and don't interested in intermediate values.
 * M=1 means that you don't want to integrate :)
 *                 it is degenerate case, but it will be handled correctly.
 * M<1 means error
 *   Eps     -   tolerance (absolute/relative error on each  step  will  be
 *               less than Eps). When passing:
 * Eps>0, it means desired ABSOLUTE error
 * Eps<0, it means desired RELATIVE error.  Relative errors
 *                 are calculated with respect to maximum values of  Y seen
 *                 so far. Be careful to use this criterion  when  starting
 *                 from Y[] that are close to zero.
 *   H       -   initial  step  lenth,  it  will  be adjusted automatically
 *               after the first  step.  If  H=0,  step  will  be  selected
 *               automatically  (usualy  it  will  be  equal  to  0.001  of
 *               min(x[i]-x[j])).
 *
 *  OUTPUT PARAMETERS
 *   State   -   structure which stores algorithm state between  subsequent
 *               calls of OdeSolverIteration. Used for reverse communication.
 *               This structure should be passed  to the OdeSolverIteration
 *               subroutine.
 *
 *  SEE ALSO
 *   AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.
 *
 *
 *  -- ALGLIB --
 *    Copyright 01.09.2009 by Bochkanov Sergey
 *************************************************************************/
 public static void odesolverrkck(ref double[] y,
                                  int n,
                                  ref double[] x,
                                  int m,
                                  double eps,
                                  double h,
                                  ref odesolverstate state)
 {
     odesolverinit(0, ref y, n, ref x, m, eps, h, ref state);
 }
    public static void odesolverrkck(double[] y, double[] x, double eps, double h, out odesolverstate state)
    {
        int n;
        int m;

        state = new odesolverstate();
        n     = ap.len(y);
        m     = ap.len(x);
        odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj);

        return;
    }
 /*************************************************************************
 *  This function is used to launcn iterations of ODE solver
 *
 *  It accepts following parameters:
 *   diff    -   callback which calculates dy/dx for given y and x
 *   obj     -   optional object which is passed to diff; can be NULL
 *
 *
 *  -- ALGLIB --
 *    Copyright 01.09.2009 by Bochkanov Sergey
 *
 *************************************************************************/
 public static void odesolversolve(odesolverstate state, ndimensional_ode_rp diff, object obj)
 {
     if (diff == null)
     {
         throw new alglibexception("ALGLIB: error in 'odesolversolve()' (diff is null)");
     }
     while (alglib.odesolveriteration(state))
     {
         if (state.needdy)
         {
             diff(state.innerobj.y, state.innerobj.x, state.innerobj.dy, obj);
             continue;
         }
         throw new alglibexception("ALGLIB: unexpected error in 'odesolversolve'");
     }
 }
 /*************************************************************************
 *  Cash-Karp adaptive ODE solver.
 *
 *  This subroutine solves ODE  Y'=f(Y,x)  with  initial  conditions  Y(xs)=Ys
 *  (here Y may be single variable or vector of N variables).
 *
 *  INPUT PARAMETERS:
 *   Y       -   initial conditions, array[0..N-1].
 *               contains values of Y[] at X[0]
 *   N       -   system size
 *   X       -   points at which Y should be tabulated, array[0..M-1]
 *               integrations starts at X[0], ends at X[M-1],  intermediate
 *               values at X[i] are returned too.
 *               SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!
 *   M       -   number of intermediate points + first point + last point:
 * M>2 means that you need both Y(X[M-1]) and M-2 values at
 *                 intermediate points
 * M=2 means that you want just to integrate from  X[0]  to
 *                 X[1] and don't interested in intermediate values.
 * M=1 means that you don't want to integrate :)
 *                 it is degenerate case, but it will be handled correctly.
 * M<1 means error
 *   Eps     -   tolerance (absolute/relative error on each  step  will  be
 *               less than Eps). When passing:
 * Eps>0, it means desired ABSOLUTE error
 * Eps<0, it means desired RELATIVE error.  Relative errors
 *                 are calculated with respect to maximum values of  Y seen
 *                 so far. Be careful to use this criterion  when  starting
 *                 from Y[] that are close to zero.
 *   H       -   initial  step  lenth,  it  will  be adjusted automatically
 *               after the first  step.  If  H=0,  step  will  be  selected
 *               automatically  (usualy  it  will  be  equal  to  0.001  of
 *               min(x[i]-x[j])).
 *
 *  OUTPUT PARAMETERS
 *   State   -   structure which stores algorithm state between  subsequent
 *               calls of OdeSolverIteration. Used for reverse communication.
 *               This structure should be passed  to the OdeSolverIteration
 *               subroutine.
 *
 *  SEE ALSO
 *   AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.
 *
 *
 *  -- ALGLIB --
 *    Copyright 01.09.2009 by Bochkanov Sergey
 *************************************************************************/
 public static void odesolverrkck(double[] y,
                                  int n,
                                  double[] x,
                                  int m,
                                  double eps,
                                  double h,
                                  odesolverstate state)
 {
     alglib.ap.assert(n >= 1, "ODESolverRKCK: N<1!");
     alglib.ap.assert(m >= 1, "ODESolverRKCK: M<1!");
     alglib.ap.assert(alglib.ap.len(y) >= n, "ODESolverRKCK: Length(Y)<N!");
     alglib.ap.assert(alglib.ap.len(x) >= m, "ODESolverRKCK: Length(X)<M!");
     alglib.ap.assert(apserv.isfinitevector(y, n), "ODESolverRKCK: Y contains infinite or NaN values!");
     alglib.ap.assert(apserv.isfinitevector(x, m), "ODESolverRKCK: Y contains infinite or NaN values!");
     alglib.ap.assert(math.isfinite(eps), "ODESolverRKCK: Eps is not finite!");
     alglib.ap.assert((double)(eps) != (double)(0), "ODESolverRKCK: Eps is zero!");
     alglib.ap.assert(math.isfinite(h), "ODESolverRKCK: H is not finite!");
     odesolverinit(0, y, n, x, m, eps, h, state);
 }
    /*************************************************************************
    This function is used to launcn iterations of ODE solver

    It accepts following parameters:
        diff    -   callback which calculates dy/dx for given y and x
        obj     -   optional object which is passed to diff; can be NULL


      -- ALGLIB --
         Copyright 01.09.2009 by Bochkanov Sergey

    *************************************************************************/
    public static void odesolversolve(odesolverstate state, ndimensional_ode_rp diff, object obj)
    {
        if( diff==null )
            throw new alglibexception("ALGLIB: error in 'odesolversolve()' (diff is null)");
        while( alglib.odesolveriteration(state) )
        {
            if( state.needdy )
            {
                diff(state.innerobj.y, state.innerobj.x, state.innerobj.dy, obj);
                continue;
            }
            throw new alglibexception("ALGLIB: unexpected error in 'odesolversolve'");
        }
    }
    /*************************************************************************
    ODE solver results

    Called after OdeSolverIteration returned False.

    INPUT PARAMETERS:
        State   -   algorithm state (used by OdeSolverIteration).

    OUTPUT PARAMETERS:
        M       -   number of tabulated values, M>=1
        XTbl    -   array[0..M-1], values of X
        YTbl    -   array[0..M-1,0..N-1], values of Y in X[i]
        Rep     -   solver report:
                    * Rep.TerminationType completetion code:
                        * -2    X is not ordered  by  ascending/descending  or
                                there are non-distinct X[],  i.e.  X[i]=X[i+1]
                        * -1    incorrect parameters were specified
                        *  1    task has been solved
                    * Rep.NFEV contains number of function calculations

      -- ALGLIB --
         Copyright 01.09.2009 by Bochkanov Sergey
    *************************************************************************/
    public static void odesolverresults(odesolverstate state, out int m, out double[] xtbl, out double[,] ytbl, out odesolverreport rep)
    {
        m = 0;
        xtbl = new double[0];
        ytbl = new double[0,0];
        rep = new odesolverreport();
        odesolver.odesolverresults(state.innerobj, ref m, ref xtbl, ref ytbl, rep.innerobj);
        return;
    }
    public static void odesolverrkck(double[] y, double[] x, double eps, double h, out odesolverstate state)
    {
        int n;
        int m;

        state = new odesolverstate();
        n = ap.len(y);
        m = ap.len(x);
        odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj);

        return;
    }
    /*************************************************************************
    This function provides reverse communication interface
    Reverse communication interface is not documented or recommended to use.
    See below for functions which provide better documented API
    *************************************************************************/
    public static bool odesolveriteration(odesolverstate state)
    {

        bool result = odesolver.odesolveriteration(state.innerobj);
        return result;
    }
Exemple #13
0
 public override alglib.apobject make_copy()
 {
     odesolverstate _result = new odesolverstate();
     _result.n = n;
     _result.m = m;
     _result.xscale = xscale;
     _result.h = h;
     _result.eps = eps;
     _result.fraceps = fraceps;
     _result.yc = (double[])yc.Clone();
     _result.escale = (double[])escale.Clone();
     _result.xg = (double[])xg.Clone();
     _result.solvertype = solvertype;
     _result.needdy = needdy;
     _result.x = x;
     _result.y = (double[])y.Clone();
     _result.dy = (double[])dy.Clone();
     _result.ytbl = (double[,])ytbl.Clone();
     _result.repterminationtype = repterminationtype;
     _result.repnfev = repnfev;
     _result.yn = (double[])yn.Clone();
     _result.yns = (double[])yns.Clone();
     _result.rka = (double[])rka.Clone();
     _result.rkc = (double[])rkc.Clone();
     _result.rkcs = (double[])rkcs.Clone();
     _result.rkb = (double[,])rkb.Clone();
     _result.rkk = (double[,])rkk.Clone();
     _result.rstate = (rcommstate)rstate.make_copy();
     return _result;
 }
    /*************************************************************************
    Cash-Karp adaptive ODE solver.

    This subroutine solves ODE  Y'=f(Y,x)  with  initial  conditions  Y(xs)=Ys
    (here Y may be single variable or vector of N variables).

    INPUT PARAMETERS:
        Y       -   initial conditions, array[0..N-1].
                    contains values of Y[] at X[0]
        N       -   system size
        X       -   points at which Y should be tabulated, array[0..M-1]
                    integrations starts at X[0], ends at X[M-1],  intermediate
                    values at X[i] are returned too.
                    SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!!!!
        M       -   number of intermediate points + first point + last point:
                    * M>2 means that you need both Y(X[M-1]) and M-2 values at
                      intermediate points
                    * M=2 means that you want just to integrate from  X[0]  to
                      X[1] and don't interested in intermediate values.
                    * M=1 means that you don't want to integrate :)
                      it is degenerate case, but it will be handled correctly.
                    * M<1 means error
        Eps     -   tolerance (absolute/relative error on each  step  will  be
                    less than Eps). When passing:
                    * Eps>0, it means desired ABSOLUTE error
                    * Eps<0, it means desired RELATIVE error.  Relative errors
                      are calculated with respect to maximum values of  Y seen
                      so far. Be careful to use this criterion  when  starting
                      from Y[] that are close to zero.
        H       -   initial  step  lenth,  it  will  be adjusted automatically
                    after the first  step.  If  H=0,  step  will  be  selected
                    automatically  (usualy  it  will  be  equal  to  0.001  of
                    min(x[i]-x[j])).

    OUTPUT PARAMETERS
        State   -   structure which stores algorithm state between  subsequent
                    calls of OdeSolverIteration. Used for reverse communication.
                    This structure should be passed  to the OdeSolverIteration
                    subroutine.

    SEE ALSO
        AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.


      -- ALGLIB --
         Copyright 01.09.2009 by Bochkanov Sergey
    *************************************************************************/
    public static void odesolverrkck(double[] y, int n, double[] x, int m, double eps, double h, out odesolverstate state)
    {
        state = new odesolverstate();
        odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj);
        return;
    }
        /*************************************************************************
        *
        *  -- ALGLIB --
        *    Copyright 01.09.2009 by Bochkanov Sergey
        *************************************************************************/
        public static bool odesolveriteration(odesolverstate state)
        {
            bool   result     = new bool();
            int    n          = 0;
            int    m          = 0;
            int    i          = 0;
            int    j          = 0;
            int    k          = 0;
            double xc         = 0;
            double v          = 0;
            double h          = 0;
            double h2         = 0;
            bool   gridpoint  = new bool();
            double err        = 0;
            double maxgrowpow = 0;
            int    klimit     = 0;
            int    i_         = 0;


            //
            // Reverse communication preparations
            // I know it looks ugly, but it works the same way
            // anywhere from C++ to Python.
            //
            // This code initializes locals by:
            // * random values determined during code
            //   generation - on first subroutine call
            // * values from previous call - on subsequent calls
            //
            if (state.rstate.stage >= 0)
            {
                n          = state.rstate.ia[0];
                m          = state.rstate.ia[1];
                i          = state.rstate.ia[2];
                j          = state.rstate.ia[3];
                k          = state.rstate.ia[4];
                klimit     = state.rstate.ia[5];
                gridpoint  = state.rstate.ba[0];
                xc         = state.rstate.ra[0];
                v          = state.rstate.ra[1];
                h          = state.rstate.ra[2];
                h2         = state.rstate.ra[3];
                err        = state.rstate.ra[4];
                maxgrowpow = state.rstate.ra[5];
            }
            else
            {
                n          = -983;
                m          = -989;
                i          = -834;
                j          = 900;
                k          = -287;
                klimit     = 364;
                gridpoint  = false;
                xc         = -338;
                v          = -686;
                h          = 912;
                h2         = 585;
                err        = 497;
                maxgrowpow = -271;
            }
            if (state.rstate.stage == 0)
            {
                goto lbl_0;
            }

            //
            // Routine body
            //

            //
            // prepare
            //
            if (state.repterminationtype != 0)
            {
                result = false;
                return(result);
            }
            n             = state.n;
            m             = state.m;
            h             = state.h;
            maxgrowpow    = Math.Pow(odesolvermaxgrow, 5);
            state.repnfev = 0;

            //
            // some preliminary checks for internal errors
            // after this we assume that H>0 and M>1
            //
            alglib.ap.assert((double)(state.h) > (double)(0), "ODESolver: internal error");
            alglib.ap.assert(m > 1, "ODESolverIteration: internal error");

            //
            // choose solver
            //
            if (state.solvertype != 0)
            {
                goto lbl_1;
            }

            //
            // Cask-Karp solver
            // Prepare coefficients table.
            // Check it for errors
            //
            state.rka       = new double[6];
            state.rka[0]    = 0;
            state.rka[1]    = (double)1 / (double)5;
            state.rka[2]    = (double)3 / (double)10;
            state.rka[3]    = (double)3 / (double)5;
            state.rka[4]    = 1;
            state.rka[5]    = (double)7 / (double)8;
            state.rkb       = new double[6, 5];
            state.rkb[1, 0] = (double)1 / (double)5;
            state.rkb[2, 0] = (double)3 / (double)40;
            state.rkb[2, 1] = (double)9 / (double)40;
            state.rkb[3, 0] = (double)3 / (double)10;
            state.rkb[3, 1] = -((double)9 / (double)10);
            state.rkb[3, 2] = (double)6 / (double)5;
            state.rkb[4, 0] = -((double)11 / (double)54);
            state.rkb[4, 1] = (double)5 / (double)2;
            state.rkb[4, 2] = -((double)70 / (double)27);
            state.rkb[4, 3] = (double)35 / (double)27;
            state.rkb[5, 0] = (double)1631 / (double)55296;
            state.rkb[5, 1] = (double)175 / (double)512;
            state.rkb[5, 2] = (double)575 / (double)13824;
            state.rkb[5, 3] = (double)44275 / (double)110592;
            state.rkb[5, 4] = (double)253 / (double)4096;
            state.rkc       = new double[6];
            state.rkc[0]    = (double)37 / (double)378;
            state.rkc[1]    = 0;
            state.rkc[2]    = (double)250 / (double)621;
            state.rkc[3]    = (double)125 / (double)594;
            state.rkc[4]    = 0;
            state.rkc[5]    = (double)512 / (double)1771;
            state.rkcs      = new double[6];
            state.rkcs[0]   = (double)2825 / (double)27648;
            state.rkcs[1]   = 0;
            state.rkcs[2]   = (double)18575 / (double)48384;
            state.rkcs[3]   = (double)13525 / (double)55296;
            state.rkcs[4]   = (double)277 / (double)14336;
            state.rkcs[5]   = (double)1 / (double)4;
            state.rkk       = new double[6, n];

            //
            // Main cycle consists of two iterations:
            // * outer where we travel from X[i-1] to X[i]
            // * inner where we travel inside [X[i-1],X[i]]
            //
            state.ytbl   = new double[m, n];
            state.escale = new double[n];
            state.yn     = new double[n];
            state.yns    = new double[n];
            xc           = state.xg[0];
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.ytbl[0, i_] = state.yc[i_];
            }
            for (j = 0; j <= n - 1; j++)
            {
                state.escale[j] = 0;
            }
            i = 1;
lbl_3:
            if (i > m - 1)
            {
                goto lbl_5;
            }

            //
            // begin inner iteration
            //
lbl_6:
            if (false)
            {
                goto lbl_7;
            }

            //
            // truncate step if needed (beyond right boundary).
            // determine should we store X or not
            //
            if ((double)(xc + h) >= (double)(state.xg[i]))
            {
                h         = state.xg[i] - xc;
                gridpoint = true;
            }
            else
            {
                gridpoint = false;
            }

            //
            // Update error scale maximums
            //
            // These maximums are initialized by zeros,
            // then updated every iterations.
            //
            for (j = 0; j <= n - 1; j++)
            {
                state.escale[j] = Math.Max(state.escale[j], Math.Abs(state.yc[j]));
            }

            //
            // make one step:
            // 1. calculate all info needed to do step
            // 2. update errors scale maximums using values/derivatives
            //    obtained during (1)
            //
            // Take into account that we use scaling of X to reduce task
            // to the form where x[0] < x[1] < ... < x[n-1]. So X is
            // replaced by x=xscale*t, and dy/dx=f(y,x) is replaced
            // by dy/dt=xscale*f(y,xscale*t).
            //
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.yn[i_] = state.yc[i_];
            }
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.yns[i_] = state.yc[i_];
            }
            k = 0;
lbl_8:
            if (k > 5)
            {
                goto lbl_10;
            }

            //
            // prepare data for the next update of YN/YNS
            //
            state.x = state.xscale * (xc + state.rka[k] * h);
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.y[i_] = state.yc[i_];
            }
            for (j = 0; j <= k - 1; j++)
            {
                v = state.rkb[k, j];
                for (i_ = 0; i_ <= n - 1; i_++)
                {
                    state.y[i_] = state.y[i_] + v * state.rkk[j, i_];
                }
            }
            state.needdy       = true;
            state.rstate.stage = 0;
            goto lbl_rcomm;
lbl_0:
            state.needdy  = false;
            state.repnfev = state.repnfev + 1;
            v             = h * state.xscale;
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.rkk[k, i_] = v * state.dy[i_];
            }

            //
            // update YN/YNS
            //
            v = state.rkc[k];
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.yn[i_] = state.yn[i_] + v * state.rkk[k, i_];
            }
            v = state.rkcs[k];
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.yns[i_] = state.yns[i_] + v * state.rkk[k, i_];
            }
            k = k + 1;
            goto lbl_8;
lbl_10:

            //
            // estimate error
            //
            err = 0;
            for (j = 0; j <= n - 1; j++)
            {
                if (!state.fraceps)
                {
                    //
                    // absolute error is estimated
                    //
                    err = Math.Max(err, Math.Abs(state.yn[j] - state.yns[j]));
                }
                else
                {
                    //
                    // Relative error is estimated
                    //
                    v = state.escale[j];
                    if ((double)(v) == (double)(0))
                    {
                        v = 1;
                    }
                    err = Math.Max(err, Math.Abs(state.yn[j] - state.yns[j]) / v);
                }
            }

            //
            // calculate new step, restart if necessary
            //
            if ((double)(maxgrowpow * err) <= (double)(state.eps))
            {
                h2 = odesolvermaxgrow * h;
            }
            else
            {
                h2 = h * Math.Pow(state.eps / err, 0.2);
            }
            if ((double)(h2) < (double)(h / odesolvermaxshrink))
            {
                h2 = h / odesolvermaxshrink;
            }
            if ((double)(err) > (double)(state.eps))
            {
                h = h2;
                goto lbl_6;
            }

            //
            // advance position
            //
            xc = xc + h;
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.yc[i_] = state.yn[i_];
            }

            //
            // update H
            //
            h = h2;

            //
            // break on grid point
            //
            if (gridpoint)
            {
                goto lbl_7;
            }
            goto lbl_6;
lbl_7:

            //
            // save result
            //
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.ytbl[i, i_] = state.yc[i_];
            }
            i = i + 1;
            goto lbl_3;
lbl_5:
            state.repterminationtype = 1;
            result = false;
            return(result);

lbl_1:
            result = false;
            return(result);

            //
            // Saving state
            //
lbl_rcomm:
            result             = true;
            state.rstate.ia[0] = n;
            state.rstate.ia[1] = m;
            state.rstate.ia[2] = i;
            state.rstate.ia[3] = j;
            state.rstate.ia[4] = k;
            state.rstate.ia[5] = klimit;
            state.rstate.ba[0] = gridpoint;
            state.rstate.ra[0] = xc;
            state.rstate.ra[1] = v;
            state.rstate.ra[2] = h;
            state.rstate.ra[3] = h2;
            state.rstate.ra[4] = err;
            state.rstate.ra[5] = maxgrowpow;
            return(result);
        }
        /*************************************************************************
        *  Internal initialization subroutine
        *************************************************************************/
        private static void odesolverinit(int solvertype,
                                          double[] y,
                                          int n,
                                          double[] x,
                                          int m,
                                          double eps,
                                          double h,
                                          odesolverstate state)
        {
            int    i  = 0;
            double v  = 0;
            int    i_ = 0;


            //
            // Prepare RComm
            //
            state.rstate.ia    = new int[5 + 1];
            state.rstate.ba    = new bool[0 + 1];
            state.rstate.ra    = new double[5 + 1];
            state.rstate.stage = -1;
            state.needdy       = false;

            //
            // check parameters.
            //
            if ((n <= 0 || m < 1) || (double)(eps) == (double)(0))
            {
                state.repterminationtype = -1;
                return;
            }
            if ((double)(h) < (double)(0))
            {
                h = -h;
            }

            //
            // quick exit if necessary.
            // after this block we assume that M>1
            //
            if (m == 1)
            {
                state.repnfev            = 0;
                state.repterminationtype = 1;
                state.ytbl = new double[1, n];
                for (i_ = 0; i_ <= n - 1; i_++)
                {
                    state.ytbl[0, i_] = y[i_];
                }
                state.xg = new double[m];
                for (i_ = 0; i_ <= m - 1; i_++)
                {
                    state.xg[i_] = x[i_];
                }
                return;
            }

            //
            // check again: correct order of X[]
            //
            if ((double)(x[1]) == (double)(x[0]))
            {
                state.repterminationtype = -2;
                return;
            }
            for (i = 1; i <= m - 1; i++)
            {
                if (((double)(x[1]) > (double)(x[0]) && (double)(x[i]) <= (double)(x[i - 1])) || ((double)(x[1]) < (double)(x[0]) && (double)(x[i]) >= (double)(x[i - 1])))
                {
                    state.repterminationtype = -2;
                    return;
                }
            }

            //
            // auto-select H if necessary
            //
            if ((double)(h) == (double)(0))
            {
                v = Math.Abs(x[1] - x[0]);
                for (i = 2; i <= m - 1; i++)
                {
                    v = Math.Min(v, Math.Abs(x[i] - x[i - 1]));
                }
                h = 0.001 * v;
            }

            //
            // store parameters
            //
            state.n       = n;
            state.m       = m;
            state.h       = h;
            state.eps     = Math.Abs(eps);
            state.fraceps = (double)(eps) < (double)(0);
            state.xg      = new double[m];
            for (i_ = 0; i_ <= m - 1; i_++)
            {
                state.xg[i_] = x[i_];
            }
            if ((double)(x[1]) > (double)(x[0]))
            {
                state.xscale = 1;
            }
            else
            {
                state.xscale = -1;
                for (i_ = 0; i_ <= m - 1; i_++)
                {
                    state.xg[i_] = -1 * state.xg[i_];
                }
            }
            state.yc = new double[n];
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                state.yc[i_] = y[i_];
            }
            state.solvertype         = solvertype;
            state.repterminationtype = 0;

            //
            // Allocate arrays
            //
            state.y  = new double[n];
            state.dy = new double[n];
        }
        /*************************************************************************
        Cash-Karp adaptive ODE solver.

        This subroutine solves ODE  Y'=f(Y,x)  with  initial  conditions  Y(xs)=Ys
        (here Y may be single variable or vector of N variables).

        INPUT PARAMETERS:
            Y       -   initial conditions, array[0..N-1].
                        contains values of Y[] at X[0]
            N       -   system size
            X       -   points at which Y should be tabulated, array[0..M-1]
                        integrations starts at X[0], ends at X[M-1],  intermediate
                        values at X[i] are returned too.
                        SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!!!!
            M       -   number of intermediate points + first point + last point:
                        * M>2 means that you need both Y(X[M-1]) and M-2 values at
                          intermediate points
                        * M=2 means that you want just to integrate from  X[0]  to
                          X[1] and don't interested in intermediate values.
                        * M=1 means that you don't want to integrate :)
                          it is degenerate case, but it will be handled correctly.
                        * M<1 means error
            Eps     -   tolerance (absolute/relative error on each  step  will  be
                        less than Eps). When passing:
                        * Eps>0, it means desired ABSOLUTE error
                        * Eps<0, it means desired RELATIVE error.  Relative errors
                          are calculated with respect to maximum values of  Y seen
                          so far. Be careful to use this criterion  when  starting
                          from Y[] that are close to zero.
            H       -   initial  step  lenth,  it  will  be adjusted automatically
                        after the first  step.  If  H=0,  step  will  be  selected
                        automatically  (usualy  it  will  be  equal  to  0.001  of
                        min(x[i]-x[j])).

        OUTPUT PARAMETERS
            State   -   structure which stores algorithm state between  subsequent
                        calls of OdeSolverIteration. Used for reverse communication.
                        This structure should be passed  to the OdeSolverIteration
                        subroutine.

        SEE ALSO
            AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.


          -- ALGLIB --
             Copyright 01.09.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void odesolverrkck(double[] y,
            int n,
            double[] x,
            int m,
            double eps,
            double h,
            odesolverstate state)
        {
            alglib.ap.assert(n>=1, "ODESolverRKCK: N<1!");
            alglib.ap.assert(m>=1, "ODESolverRKCK: M<1!");
            alglib.ap.assert(alglib.ap.len(y)>=n, "ODESolverRKCK: Length(Y)<N!");
            alglib.ap.assert(alglib.ap.len(x)>=m, "ODESolverRKCK: Length(X)<M!");
            alglib.ap.assert(apserv.isfinitevector(y, n), "ODESolverRKCK: Y contains infinite or NaN values!");
            alglib.ap.assert(apserv.isfinitevector(x, m), "ODESolverRKCK: Y contains infinite or NaN values!");
            alglib.ap.assert(math.isfinite(eps), "ODESolverRKCK: Eps is not finite!");
            alglib.ap.assert((double)(eps)!=(double)(0), "ODESolverRKCK: Eps is zero!");
            alglib.ap.assert(math.isfinite(h), "ODESolverRKCK: H is not finite!");
            odesolverinit(0, y, n, x, m, eps, h, state);
        }
Exemple #18
0
 public static bool odesolveriteration(odesolverstate state, alglib.xparams _params)
 {
     return(odesolver.odesolveriteration(state.innerobj, _params));
 }
        /*************************************************************************
        ODE solver results

        Called after OdeSolverIteration returned False.

        INPUT PARAMETERS:
            State   -   algorithm state (used by OdeSolverIteration).

        OUTPUT PARAMETERS:
            M       -   number of tabulated values, M>=1
            XTbl    -   array[0..M-1], values of X
            YTbl    -   array[0..M-1,0..N-1], values of Y in X[i]
            Rep     -   solver report:
                        * Rep.TerminationType completetion code:
                            * -2    X is not ordered  by  ascending/descending  or
                                    there are non-distinct X[],  i.e.  X[i]=X[i+1]
                            * -1    incorrect parameters were specified
                            *  1    task has been solved
                        * Rep.NFEV contains number of function calculations

          -- ALGLIB --
             Copyright 01.09.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void odesolverresults(odesolverstate state,
            ref int m,
            ref double[] xtbl,
            ref double[,] ytbl,
            odesolverreport rep)
        {
            double v = 0;
            int i = 0;
            int i_ = 0;

            m = 0;
            xtbl = new double[0];
            ytbl = new double[0,0];

            rep.terminationtype = state.repterminationtype;
            if( rep.terminationtype>0 )
            {
                m = state.m;
                rep.nfev = state.repnfev;
                xtbl = new double[state.m];
                v = state.xscale;
                for(i_=0; i_<=state.m-1;i_++)
                {
                    xtbl[i_] = v*state.xg[i_];
                }
                ytbl = new double[state.m, state.n];
                for(i=0; i<=state.m-1; i++)
                {
                    for(i_=0; i_<=state.n-1;i_++)
                    {
                        ytbl[i,i_] = state.ytbl[i,i_];
                    }
                }
            }
            else
            {
                rep.nfev = 0;
            }
        }
Exemple #20
0
 /*************************************************************************
 *  This function is used to launcn iterations of ODE solver
 *
 *  It accepts following parameters:
 *   diff    -   callback which calculates dy/dx for given y and x
 *   obj     -   optional object which is passed to diff; can be NULL
 *
 *
 *  -- ALGLIB --
 *    Copyright 01.09.2009 by Bochkanov Sergey
 *
 *************************************************************************/
 public static void odesolversolve(odesolverstate state, ndimensional_ode_rp diff, object obj)
 {
     odesolversolve(state, diff, obj, null);
 }
    /*************************************************************************
    *  This function provides reverse communication interface
    *  Reverse communication interface is not documented or recommended to use.
    *  See below for functions which provide better documented API
    *************************************************************************/
    public static bool odesolveriteration(odesolverstate state)
    {
        bool result = odesolver.odesolveriteration(state.innerobj);

        return(result);
    }
Exemple #22
0
 public static void odesolverrkck(double[] y, int n, double[] x, int m, double eps, double h, out odesolverstate state, alglib.xparams _params)
 {
     state = new odesolverstate();
     odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj, _params);
 }
 /*************************************************************************
 *  Cash-Karp adaptive ODE solver.
 *
 *  This subroutine solves ODE  Y'=f(Y,x)  with  initial  conditions  Y(xs)=Ys
 *  (here Y may be single variable or vector of N variables).
 *
 *  INPUT PARAMETERS:
 *   Y       -   initial conditions, array[0..N-1].
 *               contains values of Y[] at X[0]
 *   N       -   system size
 *   X       -   points at which Y should be tabulated, array[0..M-1]
 *               integrations starts at X[0], ends at X[M-1],  intermediate
 *               values at X[i] are returned too.
 *               SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!
 *   M       -   number of intermediate points + first point + last point:
 * M>2 means that you need both Y(X[M-1]) and M-2 values at
 *                 intermediate points
 * M=2 means that you want just to integrate from  X[0]  to
 *                 X[1] and don't interested in intermediate values.
 * M=1 means that you don't want to integrate :)
 *                 it is degenerate case, but it will be handled correctly.
 * M<1 means error
 *   Eps     -   tolerance (absolute/relative error on each  step  will  be
 *               less than Eps). When passing:
 * Eps>0, it means desired ABSOLUTE error
 * Eps<0, it means desired RELATIVE error.  Relative errors
 *                 are calculated with respect to maximum values of  Y seen
 *                 so far. Be careful to use this criterion  when  starting
 *                 from Y[] that are close to zero.
 *   H       -   initial  step  lenth,  it  will  be adjusted automatically
 *               after the first  step.  If  H=0,  step  will  be  selected
 *               automatically  (usualy  it  will  be  equal  to  0.001  of
 *               min(x[i]-x[j])).
 *
 *  OUTPUT PARAMETERS
 *   State   -   structure which stores algorithm state between  subsequent
 *               calls of OdeSolverIteration. Used for reverse communication.
 *               This structure should be passed  to the OdeSolverIteration
 *               subroutine.
 *
 *  SEE ALSO
 *   AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.
 *
 *
 *  -- ALGLIB --
 *    Copyright 01.09.2009 by Bochkanov Sergey
 *************************************************************************/
 public static void odesolverrkck(double[] y, int n, double[] x, int m, double eps, double h, out odesolverstate state)
 {
     state = new odesolverstate();
     odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj);
     return;
 }
        /*************************************************************************

          -- ALGLIB --
             Copyright 01.09.2009 by Bochkanov Sergey
        *************************************************************************/
        public static bool odesolveriteration(odesolverstate state)
        {
            bool result = new bool();
            int n = 0;
            int m = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            double xc = 0;
            double v = 0;
            double h = 0;
            double h2 = 0;
            bool gridpoint = new bool();
            double err = 0;
            double maxgrowpow = 0;
            int klimit = 0;
            int i_ = 0;

            
            //
            // Reverse communication preparations
            // I know it looks ugly, but it works the same way
            // anywhere from C++ to Python.
            //
            // This code initializes locals by:
            // * random values determined during code
            //   generation - on first subroutine call
            // * values from previous call - on subsequent calls
            //
            if( state.rstate.stage>=0 )
            {
                n = state.rstate.ia[0];
                m = state.rstate.ia[1];
                i = state.rstate.ia[2];
                j = state.rstate.ia[3];
                k = state.rstate.ia[4];
                klimit = state.rstate.ia[5];
                gridpoint = state.rstate.ba[0];
                xc = state.rstate.ra[0];
                v = state.rstate.ra[1];
                h = state.rstate.ra[2];
                h2 = state.rstate.ra[3];
                err = state.rstate.ra[4];
                maxgrowpow = state.rstate.ra[5];
            }
            else
            {
                n = -983;
                m = -989;
                i = -834;
                j = 900;
                k = -287;
                klimit = 364;
                gridpoint = false;
                xc = -338;
                v = -686;
                h = 912;
                h2 = 585;
                err = 497;
                maxgrowpow = -271;
            }
            if( state.rstate.stage==0 )
            {
                goto lbl_0;
            }
            
            //
            // Routine body
            //
            
            //
            // prepare
            //
            if( state.repterminationtype!=0 )
            {
                result = false;
                return result;
            }
            n = state.n;
            m = state.m;
            h = state.h;
            maxgrowpow = Math.Pow(odesolvermaxgrow, 5);
            state.repnfev = 0;
            
            //
            // some preliminary checks for internal errors
            // after this we assume that H>0 and M>1
            //
            alglib.ap.assert((double)(state.h)>(double)(0), "ODESolver: internal error");
            alglib.ap.assert(m>1, "ODESolverIteration: internal error");
            
            //
            // choose solver
            //
            if( state.solvertype!=0 )
            {
                goto lbl_1;
            }
            
            //
            // Cask-Karp solver
            // Prepare coefficients table.
            // Check it for errors
            //
            state.rka = new double[6];
            state.rka[0] = 0;
            state.rka[1] = (double)1/(double)5;
            state.rka[2] = (double)3/(double)10;
            state.rka[3] = (double)3/(double)5;
            state.rka[4] = 1;
            state.rka[5] = (double)7/(double)8;
            state.rkb = new double[6, 5];
            state.rkb[1,0] = (double)1/(double)5;
            state.rkb[2,0] = (double)3/(double)40;
            state.rkb[2,1] = (double)9/(double)40;
            state.rkb[3,0] = (double)3/(double)10;
            state.rkb[3,1] = -((double)9/(double)10);
            state.rkb[3,2] = (double)6/(double)5;
            state.rkb[4,0] = -((double)11/(double)54);
            state.rkb[4,1] = (double)5/(double)2;
            state.rkb[4,2] = -((double)70/(double)27);
            state.rkb[4,3] = (double)35/(double)27;
            state.rkb[5,0] = (double)1631/(double)55296;
            state.rkb[5,1] = (double)175/(double)512;
            state.rkb[5,2] = (double)575/(double)13824;
            state.rkb[5,3] = (double)44275/(double)110592;
            state.rkb[5,4] = (double)253/(double)4096;
            state.rkc = new double[6];
            state.rkc[0] = (double)37/(double)378;
            state.rkc[1] = 0;
            state.rkc[2] = (double)250/(double)621;
            state.rkc[3] = (double)125/(double)594;
            state.rkc[4] = 0;
            state.rkc[5] = (double)512/(double)1771;
            state.rkcs = new double[6];
            state.rkcs[0] = (double)2825/(double)27648;
            state.rkcs[1] = 0;
            state.rkcs[2] = (double)18575/(double)48384;
            state.rkcs[3] = (double)13525/(double)55296;
            state.rkcs[4] = (double)277/(double)14336;
            state.rkcs[5] = (double)1/(double)4;
            state.rkk = new double[6, n];
            
            //
            // Main cycle consists of two iterations:
            // * outer where we travel from X[i-1] to X[i]
            // * inner where we travel inside [X[i-1],X[i]]
            //
            state.ytbl = new double[m, n];
            state.escale = new double[n];
            state.yn = new double[n];
            state.yns = new double[n];
            xc = state.xg[0];
            for(i_=0; i_<=n-1;i_++)
            {
                state.ytbl[0,i_] = state.yc[i_];
            }
            for(j=0; j<=n-1; j++)
            {
                state.escale[j] = 0;
            }
            i = 1;
        lbl_3:
            if( i>m-1 )
            {
                goto lbl_5;
            }
            
            //
            // begin inner iteration
            //
        lbl_6:
            if( false )
            {
                goto lbl_7;
            }
            
            //
            // truncate step if needed (beyond right boundary).
            // determine should we store X or not
            //
            if( (double)(xc+h)>=(double)(state.xg[i]) )
            {
                h = state.xg[i]-xc;
                gridpoint = true;
            }
            else
            {
                gridpoint = false;
            }
            
            //
            // Update error scale maximums
            //
            // These maximums are initialized by zeros,
            // then updated every iterations.
            //
            for(j=0; j<=n-1; j++)
            {
                state.escale[j] = Math.Max(state.escale[j], Math.Abs(state.yc[j]));
            }
            
            //
            // make one step:
            // 1. calculate all info needed to do step
            // 2. update errors scale maximums using values/derivatives
            //    obtained during (1)
            //
            // Take into account that we use scaling of X to reduce task
            // to the form where x[0] < x[1] < ... < x[n-1]. So X is
            // replaced by x=xscale*t, and dy/dx=f(y,x) is replaced
            // by dy/dt=xscale*f(y,xscale*t).
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.yn[i_] = state.yc[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.yns[i_] = state.yc[i_];
            }
            k = 0;
        lbl_8:
            if( k>5 )
            {
                goto lbl_10;
            }
            
            //
            // prepare data for the next update of YN/YNS
            //
            state.x = state.xscale*(xc+state.rka[k]*h);
            for(i_=0; i_<=n-1;i_++)
            {
                state.y[i_] = state.yc[i_];
            }
            for(j=0; j<=k-1; j++)
            {
                v = state.rkb[k,j];
                for(i_=0; i_<=n-1;i_++)
                {
                    state.y[i_] = state.y[i_] + v*state.rkk[j,i_];
                }
            }
            state.needdy = true;
            state.rstate.stage = 0;
            goto lbl_rcomm;
        lbl_0:
            state.needdy = false;
            state.repnfev = state.repnfev+1;
            v = h*state.xscale;
            for(i_=0; i_<=n-1;i_++)
            {
                state.rkk[k,i_] = v*state.dy[i_];
            }
            
            //
            // update YN/YNS
            //
            v = state.rkc[k];
            for(i_=0; i_<=n-1;i_++)
            {
                state.yn[i_] = state.yn[i_] + v*state.rkk[k,i_];
            }
            v = state.rkcs[k];
            for(i_=0; i_<=n-1;i_++)
            {
                state.yns[i_] = state.yns[i_] + v*state.rkk[k,i_];
            }
            k = k+1;
            goto lbl_8;
        lbl_10:
            
            //
            // estimate error
            //
            err = 0;
            for(j=0; j<=n-1; j++)
            {
                if( !state.fraceps )
                {
                    
                    //
                    // absolute error is estimated
                    //
                    err = Math.Max(err, Math.Abs(state.yn[j]-state.yns[j]));
                }
                else
                {
                    
                    //
                    // Relative error is estimated
                    //
                    v = state.escale[j];
                    if( (double)(v)==(double)(0) )
                    {
                        v = 1;
                    }
                    err = Math.Max(err, Math.Abs(state.yn[j]-state.yns[j])/v);
                }
            }
            
            //
            // calculate new step, restart if necessary
            //
            if( (double)(maxgrowpow*err)<=(double)(state.eps) )
            {
                h2 = odesolvermaxgrow*h;
            }
            else
            {
                h2 = h*Math.Pow(state.eps/err, 0.2);
            }
            if( (double)(h2)<(double)(h/odesolvermaxshrink) )
            {
                h2 = h/odesolvermaxshrink;
            }
            if( (double)(err)>(double)(state.eps) )
            {
                h = h2;
                goto lbl_6;
            }
            
            //
            // advance position
            //
            xc = xc+h;
            for(i_=0; i_<=n-1;i_++)
            {
                state.yc[i_] = state.yn[i_];
            }
            
            //
            // update H
            //
            h = h2;
            
            //
            // break on grid point
            //
            if( gridpoint )
            {
                goto lbl_7;
            }
            goto lbl_6;
        lbl_7:
            
            //
            // save result
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.ytbl[i,i_] = state.yc[i_];
            }
            i = i+1;
            goto lbl_3;
        lbl_5:
            state.repterminationtype = 1;
            result = false;
            return result;
        lbl_1:
            result = false;
            return result;
            
            //
            // Saving state
            //
        lbl_rcomm:
            result = true;
            state.rstate.ia[0] = n;
            state.rstate.ia[1] = m;
            state.rstate.ia[2] = i;
            state.rstate.ia[3] = j;
            state.rstate.ia[4] = k;
            state.rstate.ia[5] = klimit;
            state.rstate.ba[0] = gridpoint;
            state.rstate.ra[0] = xc;
            state.rstate.ra[1] = v;
            state.rstate.ra[2] = h;
            state.rstate.ra[3] = h2;
            state.rstate.ra[4] = err;
            state.rstate.ra[5] = maxgrowpow;
            return result;
        }
Exemple #25
0
 /*************************************************************************
 *  This function provides reverse communication interface
 *  Reverse communication interface is not documented or recommended to use.
 *  See below for functions which provide better documented API
 *************************************************************************/
 public static bool odesolveriteration(odesolverstate state)
 {
     return(odesolver.odesolveriteration(state.innerobj, null));
 }
        /*************************************************************************
        Internal initialization subroutine
        *************************************************************************/
        private static void odesolverinit(int solvertype,
            double[] y,
            int n,
            double[] x,
            int m,
            double eps,
            double h,
            odesolverstate state)
        {
            int i = 0;
            double v = 0;
            int i_ = 0;

            
            //
            // Prepare RComm
            //
            state.rstate.ia = new int[5+1];
            state.rstate.ba = new bool[0+1];
            state.rstate.ra = new double[5+1];
            state.rstate.stage = -1;
            state.needdy = false;
            
            //
            // check parameters.
            //
            if( (n<=0 || m<1) || (double)(eps)==(double)(0) )
            {
                state.repterminationtype = -1;
                return;
            }
            if( (double)(h)<(double)(0) )
            {
                h = -h;
            }
            
            //
            // quick exit if necessary.
            // after this block we assume that M>1
            //
            if( m==1 )
            {
                state.repnfev = 0;
                state.repterminationtype = 1;
                state.ytbl = new double[1, n];
                for(i_=0; i_<=n-1;i_++)
                {
                    state.ytbl[0,i_] = y[i_];
                }
                state.xg = new double[m];
                for(i_=0; i_<=m-1;i_++)
                {
                    state.xg[i_] = x[i_];
                }
                return;
            }
            
            //
            // check again: correct order of X[]
            //
            if( (double)(x[1])==(double)(x[0]) )
            {
                state.repterminationtype = -2;
                return;
            }
            for(i=1; i<=m-1; i++)
            {
                if( ((double)(x[1])>(double)(x[0]) && (double)(x[i])<=(double)(x[i-1])) || ((double)(x[1])<(double)(x[0]) && (double)(x[i])>=(double)(x[i-1])) )
                {
                    state.repterminationtype = -2;
                    return;
                }
            }
            
            //
            // auto-select H if necessary
            //
            if( (double)(h)==(double)(0) )
            {
                v = Math.Abs(x[1]-x[0]);
                for(i=2; i<=m-1; i++)
                {
                    v = Math.Min(v, Math.Abs(x[i]-x[i-1]));
                }
                h = 0.001*v;
            }
            
            //
            // store parameters
            //
            state.n = n;
            state.m = m;
            state.h = h;
            state.eps = Math.Abs(eps);
            state.fraceps = (double)(eps)<(double)(0);
            state.xg = new double[m];
            for(i_=0; i_<=m-1;i_++)
            {
                state.xg[i_] = x[i_];
            }
            if( (double)(x[1])>(double)(x[0]) )
            {
                state.xscale = 1;
            }
            else
            {
                state.xscale = -1;
                for(i_=0; i_<=m-1;i_++)
                {
                    state.xg[i_] = -1*state.xg[i_];
                }
            }
            state.yc = new double[n];
            for(i_=0; i_<=n-1;i_++)
            {
                state.yc[i_] = y[i_];
            }
            state.solvertype = solvertype;
            state.repterminationtype = 0;
            
            //
            // Allocate arrays
            //
            state.y = new double[n];
            state.dy = new double[n];
        }
        /*************************************************************************
        Cash-Karp adaptive ODE solver.

        This subroutine solves ODE  Y'=f(Y,x)  with  initial  conditions  Y(xs)=Ys
        (here Y may be single variable or vector of N variables).

        INPUT PARAMETERS:
            Y       -   initial conditions, array[0..N-1].
                        contains values of Y[] at X[0]
            N       -   system size
            X       -   points at which Y should be tabulated, array[0..M-1]
                        integrations starts at X[0], ends at X[M-1],  intermediate
                        values at X[i] are returned too.
                        SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!!!!
            M       -   number of intermediate points + first point + last point:
                        * M>2 means that you need both Y(X[M-1]) and M-2 values at
                          intermediate points
                        * M=2 means that you want just to integrate from  X[0]  to
                          X[1] and don't interested in intermediate values.
                        * M=1 means that you don't want to integrate :)
                          it is degenerate case, but it will be handled correctly.
                        * M<1 means error
            Eps     -   tolerance (absolute/relative error on each  step  will  be
                        less than Eps). When passing:
                        * Eps>0, it means desired ABSOLUTE error
                        * Eps<0, it means desired RELATIVE error.  Relative errors
                          are calculated with respect to maximum values of  Y seen
                          so far. Be careful to use this criterion  when  starting
                          from Y[] that are close to zero.
            H       -   initial  step  lenth,  it  will  be adjusted automatically
                        after the first  step.  If  H=0,  step  will  be  selected
                        automatically  (usualy  it  will  be  equal  to  0.001  of
                        min(x[i]-x[j])).

        OUTPUT PARAMETERS
            State   -   structure which stores algorithm state between  subsequent
                        calls of OdeSolverIteration. Used for reverse communication.
                        This structure should be passed  to the OdeSolverIteration
                        subroutine.

        SEE ALSO
            AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.


          -- ALGLIB --
             Copyright 01.09.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void odesolverrkck(ref double[] y,
            int n,
            ref double[] x,
            int m,
            double eps,
            double h,
            ref odesolverstate state)
        {
            odesolverinit(0, ref y, n, ref x, m, eps, h, ref state);
        }