Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/3.9.0/ALGLIB-3.9.0/diffequations.cs @ 12792

Last change on this file since 12792 was 12790, checked in by gkronber, 9 years ago

#2435: updated alglib to version 3.9.0

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