Free cookie consent management tool by TermsFeed Policy Generator

source: branches/MathNetNumerics-Exploration-2789/HeuristicLab.Algorithms.DataAnalysis.Experimental/csharp/src/diffequations.cs @ 15529

Last change on this file since 15529 was 15311, checked in by gkronber, 7 years ago

#2789 exploration of alglib solver for non-linear optimization with non-linear constraints

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