Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/3.1.0/ALGLIB-3.1.0/diffequations.cs @ 5447

Last change on this file since 5447 was 4977, checked in by gkronber, 14 years ago

Added new alglib classes (version 3.1.0) #875

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