Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/3.15.0/ALGLIB-3.15.0/diffequations.cs @ 17228

Last change on this file since 17228 was 16684, checked in by gkronber, 6 years ago

#2435: added 3.15.0 version of alglib as external library (build from source)

File size: 36.7 KB
Line 
1/*************************************************************************
2ALGLIB 3.15.0 (source code generated 2019-02-20)
3Copyright (c) Sergey Bochkanov (ALGLIB project).
4
5>>> SOURCE LICENSE >>>
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation (www.fsf.org); either version 2 of the
9License, or (at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16A copy of the GNU General Public License is available at
17http://www.fsf.org/licensing/licenses
18>>> END OF LICENSE >>>
19*************************************************************************/
20#pragma warning disable 162
21#pragma warning disable 164
22#pragma warning disable 219
23using System;
24
25public partial class alglib
26{
27
28
29    /*************************************************************************
30
31    *************************************************************************/
32    public class odesolverstate : alglibobject
33    {
34        //
35        // Public declarations
36        //
37        public bool needdy { get { return _innerobj.needdy; } set { _innerobj.needdy = value; } }
38        public double[] y { get { return _innerobj.y; } }
39        public double[] dy { get { return _innerobj.dy; } }
40        public double x { get { return _innerobj.x; } set { _innerobj.x = value; } }
41   
42        public odesolverstate()
43        {
44            _innerobj = new odesolver.odesolverstate();
45        }
46       
47        public override alglib.alglibobject make_copy()
48        {
49            return new odesolverstate((odesolver.odesolverstate)_innerobj.make_copy());
50        }
51   
52        //
53        // Although some of declarations below are public, you should not use them
54        // They are intended for internal use only
55        //
56        private odesolver.odesolverstate _innerobj;
57        public odesolver.odesolverstate innerobj { get { return _innerobj; } }
58        public odesolverstate(odesolver.odesolverstate obj)
59        {
60            _innerobj = obj;
61        }
62    }
63
64
65    /*************************************************************************
66
67    *************************************************************************/
68    public class odesolverreport : alglibobject
69    {
70        //
71        // Public declarations
72        //
73        public int nfev { get { return _innerobj.nfev; } set { _innerobj.nfev = value; } }
74        public int terminationtype { get { return _innerobj.terminationtype; } set { _innerobj.terminationtype = value; } }
75   
76        public odesolverreport()
77        {
78            _innerobj = new odesolver.odesolverreport();
79        }
80       
81        public override alglib.alglibobject make_copy()
82        {
83            return new odesolverreport((odesolver.odesolverreport)_innerobj.make_copy());
84        }
85   
86        //
87        // Although some of declarations below are public, you should not use them
88        // They are intended for internal use only
89        //
90        private odesolver.odesolverreport _innerobj;
91        public odesolver.odesolverreport innerobj { get { return _innerobj; } }
92        public odesolverreport(odesolver.odesolverreport obj)
93        {
94            _innerobj = obj;
95        }
96    }
97   
98    /*************************************************************************
99    Cash-Karp adaptive ODE solver.
100
101    This subroutine solves ODE  Y'=f(Y,x)  with  initial  conditions  Y(xs)=Ys
102    (here Y may be single variable or vector of N variables).
103
104    INPUT PARAMETERS:
105        Y       -   initial conditions, array[0..N-1].
106                    contains values of Y[] at X[0]
107        N       -   system size
108        X       -   points at which Y should be tabulated, array[0..M-1]
109                    integrations starts at X[0], ends at X[M-1],  intermediate
110                    values at X[i] are returned too.
111                    SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!
112        M       -   number of intermediate points + first point + last point:
113                    * M>2 means that you need both Y(X[M-1]) and M-2 values at
114                      intermediate points
115                    * M=2 means that you want just to integrate from  X[0]  to
116                      X[1] and don't interested in intermediate values.
117                    * M=1 means that you don't want to integrate :)
118                      it is degenerate case, but it will be handled correctly.
119                    * M<1 means error
120        Eps     -   tolerance (absolute/relative error on each  step  will  be
121                    less than Eps). When passing:
122                    * Eps>0, it means desired ABSOLUTE error
123                    * Eps<0, it means desired RELATIVE error.  Relative errors
124                      are calculated with respect to maximum values of  Y seen
125                      so far. Be careful to use this criterion  when  starting
126                      from Y[] that are close to zero.
127        H       -   initial  step  lenth,  it  will  be adjusted automatically
128                    after the first  step.  If  H=0,  step  will  be  selected
129                    automatically  (usualy  it  will  be  equal  to  0.001  of
130                    min(x[i]-x[j])).
131
132    OUTPUT PARAMETERS
133        State   -   structure which stores algorithm state between  subsequent
134                    calls of OdeSolverIteration. Used for reverse communication.
135                    This structure should be passed  to the OdeSolverIteration
136                    subroutine.
137
138    SEE ALSO
139        AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.
140
141
142      -- ALGLIB --
143         Copyright 01.09.2009 by Bochkanov Sergey
144    *************************************************************************/
145    public static void odesolverrkck(double[] y, int n, double[] x, int m, double eps, double h, out odesolverstate state)
146    {
147        state = new odesolverstate();
148        odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj, null);
149    }
150   
151    public static void odesolverrkck(double[] y, int n, double[] x, int m, double eps, double h, out odesolverstate state, alglib.xparams _params)
152    {
153        state = new odesolverstate();
154        odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj, _params);
155    }
156           
157    public static void odesolverrkck(double[] y, double[] x, double eps, double h, out odesolverstate state)
158    {
159        int n;
160        int m;
161   
162        state = new odesolverstate();
163        n = ap.len(y);
164        m = ap.len(x);
165        odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj, null);
166   
167        return;
168    }
169           
170    public static void odesolverrkck(double[] y, double[] x, double eps, double h, out odesolverstate state, alglib.xparams _params)
171    {
172        int n;
173        int m;
174   
175        state = new odesolverstate();
176        n = ap.len(y);
177        m = ap.len(x);
178        odesolver.odesolverrkck(y, n, x, m, eps, h, state.innerobj, _params);
179   
180        return;
181    }
182   
183    /*************************************************************************
184    This function provides reverse communication interface
185    Reverse communication interface is not documented or recommended to use.
186    See below for functions which provide better documented API
187    *************************************************************************/
188    public static bool odesolveriteration(odesolverstate state)
189    {
190   
191        return odesolver.odesolveriteration(state.innerobj, null);
192    }
193   
194    public static bool odesolveriteration(odesolverstate state, alglib.xparams _params)
195    {
196   
197        return odesolver.odesolveriteration(state.innerobj, _params);
198    }
199    /*************************************************************************
200    This function is used to launcn iterations of ODE solver
201
202    It accepts following parameters:
203        diff    -   callback which calculates dy/dx for given y and x
204        obj     -   optional object which is passed to diff; can be NULL
205
206
207      -- ALGLIB --
208         Copyright 01.09.2009 by Bochkanov Sergey
209
210    *************************************************************************/
211    public static void odesolversolve(odesolverstate state, ndimensional_ode_rp diff, object obj)
212    {
213        odesolversolve(state, diff, obj, null);
214    }
215   
216    public static void odesolversolve(odesolverstate state, ndimensional_ode_rp diff, object obj, alglib.xparams _params)
217    {
218        if( diff==null )
219            throw new alglibexception("ALGLIB: error in 'odesolversolve()' (diff is null)");
220        while( alglib.odesolveriteration(state, _params) )
221        {
222            if( state.needdy )
223            {
224                diff(state.innerobj.y, state.innerobj.x, state.innerobj.dy, obj);
225                continue;
226            }
227            throw new alglibexception("ALGLIB: unexpected error in 'odesolversolve'");
228        }
229    }
230
231
232   
233    /*************************************************************************
234    ODE solver results
235
236    Called after OdeSolverIteration returned False.
237
238    INPUT PARAMETERS:
239        State   -   algorithm state (used by OdeSolverIteration).
240
241    OUTPUT PARAMETERS:
242        M       -   number of tabulated values, M>=1
243        XTbl    -   array[0..M-1], values of X
244        YTbl    -   array[0..M-1,0..N-1], values of Y in X[i]
245        Rep     -   solver report:
246                    * Rep.TerminationType completetion code:
247                        * -2    X is not ordered  by  ascending/descending  or
248                                there are non-distinct X[],  i.e.  X[i]=X[i+1]
249                        * -1    incorrect parameters were specified
250                        *  1    task has been solved
251                    * Rep.NFEV contains number of function calculations
252
253      -- ALGLIB --
254         Copyright 01.09.2009 by Bochkanov Sergey
255    *************************************************************************/
256    public static void odesolverresults(odesolverstate state, out int m, out double[] xtbl, out double[,] ytbl, out odesolverreport rep)
257    {
258        m = 0;
259        xtbl = new double[0];
260        ytbl = new double[0,0];
261        rep = new odesolverreport();
262        odesolver.odesolverresults(state.innerobj, ref m, ref xtbl, ref ytbl, rep.innerobj, null);
263    }
264   
265    public static void odesolverresults(odesolverstate state, out int m, out double[] xtbl, out double[,] ytbl, out odesolverreport rep, alglib.xparams _params)
266    {
267        m = 0;
268        xtbl = new double[0];
269        ytbl = new double[0,0];
270        rep = new odesolverreport();
271        odesolver.odesolverresults(state.innerobj, ref m, ref xtbl, ref ytbl, rep.innerobj, _params);
272    }
273
274}
275public partial class alglib
276{
277    public class odesolver
278    {
279        public class odesolverstate : apobject
280        {
281            public int n;
282            public int m;
283            public double xscale;
284            public double h;
285            public double eps;
286            public bool fraceps;
287            public double[] yc;
288            public double[] escale;
289            public double[] xg;
290            public int solvertype;
291            public bool needdy;
292            public double x;
293            public double[] y;
294            public double[] dy;
295            public double[,] ytbl;
296            public int repterminationtype;
297            public int repnfev;
298            public double[] yn;
299            public double[] yns;
300            public double[] rka;
301            public double[] rkc;
302            public double[] rkcs;
303            public double[,] rkb;
304            public double[,] rkk;
305            public rcommstate rstate;
306            public odesolverstate()
307            {
308                init();
309            }
310            public override void init()
311            {
312                yc = new double[0];
313                escale = new double[0];
314                xg = new double[0];
315                y = new double[0];
316                dy = new double[0];
317                ytbl = new double[0,0];
318                yn = new double[0];
319                yns = new double[0];
320                rka = new double[0];
321                rkc = new double[0];
322                rkcs = new double[0];
323                rkb = new double[0,0];
324                rkk = new double[0,0];
325                rstate = new rcommstate();
326            }
327            public override alglib.apobject make_copy()
328            {
329                odesolverstate _result = new odesolverstate();
330                _result.n = n;
331                _result.m = m;
332                _result.xscale = xscale;
333                _result.h = h;
334                _result.eps = eps;
335                _result.fraceps = fraceps;
336                _result.yc = (double[])yc.Clone();
337                _result.escale = (double[])escale.Clone();
338                _result.xg = (double[])xg.Clone();
339                _result.solvertype = solvertype;
340                _result.needdy = needdy;
341                _result.x = x;
342                _result.y = (double[])y.Clone();
343                _result.dy = (double[])dy.Clone();
344                _result.ytbl = (double[,])ytbl.Clone();
345                _result.repterminationtype = repterminationtype;
346                _result.repnfev = repnfev;
347                _result.yn = (double[])yn.Clone();
348                _result.yns = (double[])yns.Clone();
349                _result.rka = (double[])rka.Clone();
350                _result.rkc = (double[])rkc.Clone();
351                _result.rkcs = (double[])rkcs.Clone();
352                _result.rkb = (double[,])rkb.Clone();
353                _result.rkk = (double[,])rkk.Clone();
354                _result.rstate = (rcommstate)rstate.make_copy();
355                return _result;
356            }
357        };
358
359
360        public class odesolverreport : apobject
361        {
362            public int nfev;
363            public int terminationtype;
364            public odesolverreport()
365            {
366                init();
367            }
368            public override void init()
369            {
370            }
371            public override alglib.apobject make_copy()
372            {
373                odesolverreport _result = new odesolverreport();
374                _result.nfev = nfev;
375                _result.terminationtype = terminationtype;
376                return _result;
377            }
378        };
379
380
381
382
383        public const double odesolvermaxgrow = 3.0;
384        public const double odesolvermaxshrink = 10.0;
385
386
387        /*************************************************************************
388        Cash-Karp adaptive ODE solver.
389
390        This subroutine solves ODE  Y'=f(Y,x)  with  initial  conditions  Y(xs)=Ys
391        (here Y may be single variable or vector of N variables).
392
393        INPUT PARAMETERS:
394            Y       -   initial conditions, array[0..N-1].
395                        contains values of Y[] at X[0]
396            N       -   system size
397            X       -   points at which Y should be tabulated, array[0..M-1]
398                        integrations starts at X[0], ends at X[M-1],  intermediate
399                        values at X[i] are returned too.
400                        SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!
401            M       -   number of intermediate points + first point + last point:
402                        * M>2 means that you need both Y(X[M-1]) and M-2 values at
403                          intermediate points
404                        * M=2 means that you want just to integrate from  X[0]  to
405                          X[1] and don't interested in intermediate values.
406                        * M=1 means that you don't want to integrate :)
407                          it is degenerate case, but it will be handled correctly.
408                        * M<1 means error
409            Eps     -   tolerance (absolute/relative error on each  step  will  be
410                        less than Eps). When passing:
411                        * Eps>0, it means desired ABSOLUTE error
412                        * Eps<0, it means desired RELATIVE error.  Relative errors
413                          are calculated with respect to maximum values of  Y seen
414                          so far. Be careful to use this criterion  when  starting
415                          from Y[] that are close to zero.
416            H       -   initial  step  lenth,  it  will  be adjusted automatically
417                        after the first  step.  If  H=0,  step  will  be  selected
418                        automatically  (usualy  it  will  be  equal  to  0.001  of
419                        min(x[i]-x[j])).
420
421        OUTPUT PARAMETERS
422            State   -   structure which stores algorithm state between  subsequent
423                        calls of OdeSolverIteration. Used for reverse communication.
424                        This structure should be passed  to the OdeSolverIteration
425                        subroutine.
426
427        SEE ALSO
428            AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.
429
430
431          -- ALGLIB --
432             Copyright 01.09.2009 by Bochkanov Sergey
433        *************************************************************************/
434        public static void odesolverrkck(double[] y,
435            int n,
436            double[] x,
437            int m,
438            double eps,
439            double h,
440            odesolverstate state,
441            alglib.xparams _params)
442        {
443            alglib.ap.assert(n>=1, "ODESolverRKCK: N<1!");
444            alglib.ap.assert(m>=1, "ODESolverRKCK: M<1!");
445            alglib.ap.assert(alglib.ap.len(y)>=n, "ODESolverRKCK: Length(Y)<N!");
446            alglib.ap.assert(alglib.ap.len(x)>=m, "ODESolverRKCK: Length(X)<M!");
447            alglib.ap.assert(apserv.isfinitevector(y, n, _params), "ODESolverRKCK: Y contains infinite or NaN values!");
448            alglib.ap.assert(apserv.isfinitevector(x, m, _params), "ODESolverRKCK: Y contains infinite or NaN values!");
449            alglib.ap.assert(math.isfinite(eps), "ODESolverRKCK: Eps is not finite!");
450            alglib.ap.assert((double)(eps)!=(double)(0), "ODESolverRKCK: Eps is zero!");
451            alglib.ap.assert(math.isfinite(h), "ODESolverRKCK: H is not finite!");
452            odesolverinit(0, y, n, x, m, eps, h, state, _params);
453        }
454
455
456        /*************************************************************************
457
458          -- ALGLIB --
459             Copyright 01.09.2009 by Bochkanov Sergey
460        *************************************************************************/
461        public static bool odesolveriteration(odesolverstate state,
462            alglib.xparams _params)
463        {
464            bool result = new bool();
465            int n = 0;
466            int m = 0;
467            int i = 0;
468            int j = 0;
469            int k = 0;
470            double xc = 0;
471            double v = 0;
472            double h = 0;
473            double h2 = 0;
474            bool gridpoint = new bool();
475            double err = 0;
476            double maxgrowpow = 0;
477            int klimit = 0;
478            int i_ = 0;
479
480           
481            //
482            // Reverse communication preparations
483            // I know it looks ugly, but it works the same way
484            // anywhere from C++ to Python.
485            //
486            // This code initializes locals by:
487            // * random values determined during code
488            //   generation - on first subroutine call
489            // * values from previous call - on subsequent calls
490            //
491            if( state.rstate.stage>=0 )
492            {
493                n = state.rstate.ia[0];
494                m = state.rstate.ia[1];
495                i = state.rstate.ia[2];
496                j = state.rstate.ia[3];
497                k = state.rstate.ia[4];
498                klimit = state.rstate.ia[5];
499                gridpoint = state.rstate.ba[0];
500                xc = state.rstate.ra[0];
501                v = state.rstate.ra[1];
502                h = state.rstate.ra[2];
503                h2 = state.rstate.ra[3];
504                err = state.rstate.ra[4];
505                maxgrowpow = state.rstate.ra[5];
506            }
507            else
508            {
509                n = 359;
510                m = -58;
511                i = -919;
512                j = -909;
513                k = 81;
514                klimit = 255;
515                gridpoint = false;
516                xc = -788;
517                v = 809;
518                h = 205;
519                h2 = -838;
520                err = 939;
521                maxgrowpow = -526;
522            }
523            if( state.rstate.stage==0 )
524            {
525                goto lbl_0;
526            }
527           
528            //
529            // Routine body
530            //
531           
532            //
533            // prepare
534            //
535            if( state.repterminationtype!=0 )
536            {
537                result = false;
538                return result;
539            }
540            n = state.n;
541            m = state.m;
542            h = state.h;
543            maxgrowpow = Math.Pow(odesolvermaxgrow, 5);
544            state.repnfev = 0;
545           
546            //
547            // some preliminary checks for internal errors
548            // after this we assume that H>0 and M>1
549            //
550            alglib.ap.assert((double)(state.h)>(double)(0), "ODESolver: internal error");
551            alglib.ap.assert(m>1, "ODESolverIteration: internal error");
552           
553            //
554            // choose solver
555            //
556            if( state.solvertype!=0 )
557            {
558                goto lbl_1;
559            }
560           
561            //
562            // Cask-Karp solver
563            // Prepare coefficients table.
564            // Check it for errors
565            //
566            state.rka = new double[6];
567            state.rka[0] = 0;
568            state.rka[1] = (double)1/(double)5;
569            state.rka[2] = (double)3/(double)10;
570            state.rka[3] = (double)3/(double)5;
571            state.rka[4] = 1;
572            state.rka[5] = (double)7/(double)8;
573            state.rkb = new double[6, 5];
574            state.rkb[1,0] = (double)1/(double)5;
575            state.rkb[2,0] = (double)3/(double)40;
576            state.rkb[2,1] = (double)9/(double)40;
577            state.rkb[3,0] = (double)3/(double)10;
578            state.rkb[3,1] = -((double)9/(double)10);
579            state.rkb[3,2] = (double)6/(double)5;
580            state.rkb[4,0] = -((double)11/(double)54);
581            state.rkb[4,1] = (double)5/(double)2;
582            state.rkb[4,2] = -((double)70/(double)27);
583            state.rkb[4,3] = (double)35/(double)27;
584            state.rkb[5,0] = (double)1631/(double)55296;
585            state.rkb[5,1] = (double)175/(double)512;
586            state.rkb[5,2] = (double)575/(double)13824;
587            state.rkb[5,3] = (double)44275/(double)110592;
588            state.rkb[5,4] = (double)253/(double)4096;
589            state.rkc = new double[6];
590            state.rkc[0] = (double)37/(double)378;
591            state.rkc[1] = 0;
592            state.rkc[2] = (double)250/(double)621;
593            state.rkc[3] = (double)125/(double)594;
594            state.rkc[4] = 0;
595            state.rkc[5] = (double)512/(double)1771;
596            state.rkcs = new double[6];
597            state.rkcs[0] = (double)2825/(double)27648;
598            state.rkcs[1] = 0;
599            state.rkcs[2] = (double)18575/(double)48384;
600            state.rkcs[3] = (double)13525/(double)55296;
601            state.rkcs[4] = (double)277/(double)14336;
602            state.rkcs[5] = (double)1/(double)4;
603            state.rkk = new double[6, n];
604           
605            //
606            // Main cycle consists of two iterations:
607            // * outer where we travel from X[i-1] to X[i]
608            // * inner where we travel inside [X[i-1],X[i]]
609            //
610            state.ytbl = new double[m, n];
611            state.escale = new double[n];
612            state.yn = new double[n];
613            state.yns = new double[n];
614            xc = state.xg[0];
615            for(i_=0; i_<=n-1;i_++)
616            {
617                state.ytbl[0,i_] = state.yc[i_];
618            }
619            for(j=0; j<=n-1; j++)
620            {
621                state.escale[j] = 0;
622            }
623            i = 1;
624        lbl_3:
625            if( i>m-1 )
626            {
627                goto lbl_5;
628            }
629           
630            //
631            // begin inner iteration
632            //
633        lbl_6:
634            if( false )
635            {
636                goto lbl_7;
637            }
638           
639            //
640            // truncate step if needed (beyond right boundary).
641            // determine should we store X or not
642            //
643            if( (double)(xc+h)>=(double)(state.xg[i]) )
644            {
645                h = state.xg[i]-xc;
646                gridpoint = true;
647            }
648            else
649            {
650                gridpoint = false;
651            }
652           
653            //
654            // Update error scale maximums
655            //
656            // These maximums are initialized by zeros,
657            // then updated every iterations.
658            //
659            for(j=0; j<=n-1; j++)
660            {
661                state.escale[j] = Math.Max(state.escale[j], Math.Abs(state.yc[j]));
662            }
663           
664            //
665            // make one step:
666            // 1. calculate all info needed to do step
667            // 2. update errors scale maximums using values/derivatives
668            //    obtained during (1)
669            //
670            // Take into account that we use scaling of X to reduce task
671            // to the form where x[0] < x[1] < ... < x[n-1]. So X is
672            // replaced by x=xscale*t, and dy/dx=f(y,x) is replaced
673            // by dy/dt=xscale*f(y,xscale*t).
674            //
675            for(i_=0; i_<=n-1;i_++)
676            {
677                state.yn[i_] = state.yc[i_];
678            }
679            for(i_=0; i_<=n-1;i_++)
680            {
681                state.yns[i_] = state.yc[i_];
682            }
683            k = 0;
684        lbl_8:
685            if( k>5 )
686            {
687                goto lbl_10;
688            }
689           
690            //
691            // prepare data for the next update of YN/YNS
692            //
693            state.x = state.xscale*(xc+state.rka[k]*h);
694            for(i_=0; i_<=n-1;i_++)
695            {
696                state.y[i_] = state.yc[i_];
697            }
698            for(j=0; j<=k-1; j++)
699            {
700                v = state.rkb[k,j];
701                for(i_=0; i_<=n-1;i_++)
702                {
703                    state.y[i_] = state.y[i_] + v*state.rkk[j,i_];
704                }
705            }
706            state.needdy = true;
707            state.rstate.stage = 0;
708            goto lbl_rcomm;
709        lbl_0:
710            state.needdy = false;
711            state.repnfev = state.repnfev+1;
712            v = h*state.xscale;
713            for(i_=0; i_<=n-1;i_++)
714            {
715                state.rkk[k,i_] = v*state.dy[i_];
716            }
717           
718            //
719            // update YN/YNS
720            //
721            v = state.rkc[k];
722            for(i_=0; i_<=n-1;i_++)
723            {
724                state.yn[i_] = state.yn[i_] + v*state.rkk[k,i_];
725            }
726            v = state.rkcs[k];
727            for(i_=0; i_<=n-1;i_++)
728            {
729                state.yns[i_] = state.yns[i_] + v*state.rkk[k,i_];
730            }
731            k = k+1;
732            goto lbl_8;
733        lbl_10:
734           
735            //
736            // estimate error
737            //
738            err = 0;
739            for(j=0; j<=n-1; j++)
740            {
741                if( !state.fraceps )
742                {
743                   
744                    //
745                    // absolute error is estimated
746                    //
747                    err = Math.Max(err, Math.Abs(state.yn[j]-state.yns[j]));
748                }
749                else
750                {
751                   
752                    //
753                    // Relative error is estimated
754                    //
755                    v = state.escale[j];
756                    if( (double)(v)==(double)(0) )
757                    {
758                        v = 1;
759                    }
760                    err = Math.Max(err, Math.Abs(state.yn[j]-state.yns[j])/v);
761                }
762            }
763           
764            //
765            // calculate new step, restart if necessary
766            //
767            if( (double)(maxgrowpow*err)<=(double)(state.eps) )
768            {
769                h2 = odesolvermaxgrow*h;
770            }
771            else
772            {
773                h2 = h*Math.Pow(state.eps/err, 0.2);
774            }
775            if( (double)(h2)<(double)(h/odesolvermaxshrink) )
776            {
777                h2 = h/odesolvermaxshrink;
778            }
779            if( (double)(err)>(double)(state.eps) )
780            {
781                h = h2;
782                goto lbl_6;
783            }
784           
785            //
786            // advance position
787            //
788            xc = xc+h;
789            for(i_=0; i_<=n-1;i_++)
790            {
791                state.yc[i_] = state.yn[i_];
792            }
793           
794            //
795            // update H
796            //
797            h = h2;
798           
799            //
800            // break on grid point
801            //
802            if( gridpoint )
803            {
804                goto lbl_7;
805            }
806            goto lbl_6;
807        lbl_7:
808           
809            //
810            // save result
811            //
812            for(i_=0; i_<=n-1;i_++)
813            {
814                state.ytbl[i,i_] = state.yc[i_];
815            }
816            i = i+1;
817            goto lbl_3;
818        lbl_5:
819            state.repterminationtype = 1;
820            result = false;
821            return result;
822        lbl_1:
823            result = false;
824            return result;
825           
826            //
827            // Saving state
828            //
829        lbl_rcomm:
830            result = true;
831            state.rstate.ia[0] = n;
832            state.rstate.ia[1] = m;
833            state.rstate.ia[2] = i;
834            state.rstate.ia[3] = j;
835            state.rstate.ia[4] = k;
836            state.rstate.ia[5] = klimit;
837            state.rstate.ba[0] = gridpoint;
838            state.rstate.ra[0] = xc;
839            state.rstate.ra[1] = v;
840            state.rstate.ra[2] = h;
841            state.rstate.ra[3] = h2;
842            state.rstate.ra[4] = err;
843            state.rstate.ra[5] = maxgrowpow;
844            return result;
845        }
846
847
848        /*************************************************************************
849        ODE solver results
850
851        Called after OdeSolverIteration returned False.
852
853        INPUT PARAMETERS:
854            State   -   algorithm state (used by OdeSolverIteration).
855
856        OUTPUT PARAMETERS:
857            M       -   number of tabulated values, M>=1
858            XTbl    -   array[0..M-1], values of X
859            YTbl    -   array[0..M-1,0..N-1], values of Y in X[i]
860            Rep     -   solver report:
861                        * Rep.TerminationType completetion code:
862                            * -2    X is not ordered  by  ascending/descending  or
863                                    there are non-distinct X[],  i.e.  X[i]=X[i+1]
864                            * -1    incorrect parameters were specified
865                            *  1    task has been solved
866                        * Rep.NFEV contains number of function calculations
867
868          -- ALGLIB --
869             Copyright 01.09.2009 by Bochkanov Sergey
870        *************************************************************************/
871        public static void odesolverresults(odesolverstate state,
872            ref int m,
873            ref double[] xtbl,
874            ref double[,] ytbl,
875            odesolverreport rep,
876            alglib.xparams _params)
877        {
878            double v = 0;
879            int i = 0;
880            int i_ = 0;
881
882            m = 0;
883            xtbl = new double[0];
884            ytbl = new double[0,0];
885
886            rep.terminationtype = state.repterminationtype;
887            if( rep.terminationtype>0 )
888            {
889                m = state.m;
890                rep.nfev = state.repnfev;
891                xtbl = new double[state.m];
892                v = state.xscale;
893                for(i_=0; i_<=state.m-1;i_++)
894                {
895                    xtbl[i_] = v*state.xg[i_];
896                }
897                ytbl = new double[state.m, state.n];
898                for(i=0; i<=state.m-1; i++)
899                {
900                    for(i_=0; i_<=state.n-1;i_++)
901                    {
902                        ytbl[i,i_] = state.ytbl[i,i_];
903                    }
904                }
905            }
906            else
907            {
908                rep.nfev = 0;
909            }
910        }
911
912
913        /*************************************************************************
914        Internal initialization subroutine
915        *************************************************************************/
916        private static void odesolverinit(int solvertype,
917            double[] y,
918            int n,
919            double[] x,
920            int m,
921            double eps,
922            double h,
923            odesolverstate state,
924            alglib.xparams _params)
925        {
926            int i = 0;
927            double v = 0;
928            int i_ = 0;
929
930           
931            //
932            // Prepare RComm
933            //
934            state.rstate.ia = new int[5+1];
935            state.rstate.ba = new bool[0+1];
936            state.rstate.ra = new double[5+1];
937            state.rstate.stage = -1;
938            state.needdy = false;
939           
940            //
941            // check parameters.
942            //
943            if( (n<=0 || m<1) || (double)(eps)==(double)(0) )
944            {
945                state.repterminationtype = -1;
946                return;
947            }
948            if( (double)(h)<(double)(0) )
949            {
950                h = -h;
951            }
952           
953            //
954            // quick exit if necessary.
955            // after this block we assume that M>1
956            //
957            if( m==1 )
958            {
959                state.repnfev = 0;
960                state.repterminationtype = 1;
961                state.ytbl = new double[1, n];
962                for(i_=0; i_<=n-1;i_++)
963                {
964                    state.ytbl[0,i_] = y[i_];
965                }
966                state.xg = new double[m];
967                for(i_=0; i_<=m-1;i_++)
968                {
969                    state.xg[i_] = x[i_];
970                }
971                return;
972            }
973           
974            //
975            // check again: correct order of X[]
976            //
977            if( (double)(x[1])==(double)(x[0]) )
978            {
979                state.repterminationtype = -2;
980                return;
981            }
982            for(i=1; i<=m-1; i++)
983            {
984                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])) )
985                {
986                    state.repterminationtype = -2;
987                    return;
988                }
989            }
990           
991            //
992            // auto-select H if necessary
993            //
994            if( (double)(h)==(double)(0) )
995            {
996                v = Math.Abs(x[1]-x[0]);
997                for(i=2; i<=m-1; i++)
998                {
999                    v = Math.Min(v, Math.Abs(x[i]-x[i-1]));
1000                }
1001                h = 0.001*v;
1002            }
1003           
1004            //
1005            // store parameters
1006            //
1007            state.n = n;
1008            state.m = m;
1009            state.h = h;
1010            state.eps = Math.Abs(eps);
1011            state.fraceps = (double)(eps)<(double)(0);
1012            state.xg = new double[m];
1013            for(i_=0; i_<=m-1;i_++)
1014            {
1015                state.xg[i_] = x[i_];
1016            }
1017            if( (double)(x[1])>(double)(x[0]) )
1018            {
1019                state.xscale = 1;
1020            }
1021            else
1022            {
1023                state.xscale = -1;
1024                for(i_=0; i_<=m-1;i_++)
1025                {
1026                    state.xg[i_] = -1*state.xg[i_];
1027                }
1028            }
1029            state.yc = new double[n];
1030            for(i_=0; i_<=n-1;i_++)
1031            {
1032                state.yc[i_] = y[i_];
1033            }
1034            state.solvertype = solvertype;
1035            state.repterminationtype = 0;
1036           
1037            //
1038            // Allocate arrays
1039            //
1040            state.y = new double[n];
1041            state.dy = new double[n];
1042        }
1043
1044
1045    }
1046}
1047
Note: See TracBrowser for help on using the repository browser.