Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.ALGLIB-2.5.0/ALGLIB-2.5.0/minasa.cs @ 5192

Last change on this file since 5192 was 3839, checked in by mkommend, 14 years ago

implemented first version of LR (ticket #1012)

File size: 52.9 KB
Line 
1/*************************************************************************
2Copyright (c) 2010, 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
18>>> END OF LICENSE >>>
19*************************************************************************/
20
21using System;
22
23namespace alglib
24{
25    public class minasa
26    {
27        public struct minasastate
28        {
29            public int n;
30            public double epsg;
31            public double epsf;
32            public double epsx;
33            public int maxits;
34            public bool xrep;
35            public double stpmax;
36            public int cgtype;
37            public int k;
38            public int nfev;
39            public int mcstage;
40            public double[] bndl;
41            public double[] bndu;
42            public int curalgo;
43            public int acount;
44            public double mu;
45            public double finit;
46            public double dginit;
47            public double[] ak;
48            public double[] xk;
49            public double[] dk;
50            public double[] an;
51            public double[] xn;
52            public double[] dn;
53            public double[] d;
54            public double fold;
55            public double stp;
56            public double[] work;
57            public double[] yk;
58            public double[] gc;
59            public double[] x;
60            public double f;
61            public double[] g;
62            public bool needfg;
63            public bool xupdated;
64            public AP.rcommstate rstate;
65            public int repiterationscount;
66            public int repnfev;
67            public int repterminationtype;
68            public int debugrestartscount;
69            public linmin.linminstate lstate;
70            public double betahs;
71            public double betady;
72        };
73
74
75        public struct minasareport
76        {
77            public int iterationscount;
78            public int nfev;
79            public int terminationtype;
80            public int activeconstraints;
81        };
82
83
84
85
86        public const int n1 = 2;
87        public const int n2 = 2;
88        public const double stpmin = 1.0E-300;
89        public const double gpaftol = 0.0001;
90        public const double gpadecay = 0.5;
91        public const double asarho = 0.5;
92
93
94        /*************************************************************************
95                      NONLINEAR BOUND CONSTRAINED OPTIMIZATION USING
96                                       MODIFIED
97                           WILLIAM W. HAGER AND HONGCHAO ZHANG
98                                 ACTIVE SET ALGORITHM
99
100        The  subroutine  minimizes  function  F(x)  of  N  arguments  with   bound
101        constraints: BndL[i] <= x[i] <= BndU[i]
102
103        This method is  globally  convergent  as  long  as  grad(f)  is  Lipschitz
104        continuous on a level set: L = { x : f(x)<=f(x0) }.
105
106        INPUT PARAMETERS:
107            N       -   problem dimension. N>0
108            X       -   initial solution approximation, array[0..N-1].
109            BndL    -   lower bounds, array[0..N-1].
110                        all elements MUST be specified,  i.e.  all  variables  are
111                        bounded. However, if some (all) variables  are  unbounded,
112                        you may specify very small number as bound: -1000,  -1.0E6
113                        or -1.0E300, or something like that.
114            BndU    -   upper bounds, array[0..N-1].
115                        all elements MUST be specified,  i.e.  all  variables  are
116                        bounded. However, if some (all) variables  are  unbounded,
117                        you may specify very large number as bound: +1000,  +1.0E6
118                        or +1.0E300, or something like that.
119            EpsG    -   positive number which  defines  a  precision  of  search.  The
120                        subroutine finishes its work if the condition ||G|| < EpsG  is
121                        satisfied, where ||.|| means Euclidian norm, G - gradient, X -
122                        current approximation.
123            EpsF    -   positive number which  defines  a  precision  of  search.  The
124                        subroutine finishes its work if on iteration  number  k+1  the
125                        condition |F(k+1)-F(k)| <= EpsF*max{|F(k)|, |F(k+1)|, 1}    is
126                        satisfied.
127            EpsX    -   positive number which  defines  a  precision  of  search.  The
128                        subroutine finishes its work if on iteration number k+1    the
129                        condition |X(k+1)-X(k)| <= EpsX is fulfilled.
130            MaxIts  -   maximum number of iterations. If MaxIts=0, the number of
131                        iterations is unlimited.
132
133        OUTPUT PARAMETERS:
134            State - structure used for reverse communication.
135
136        This function  initializes  State   structure  with  default  optimization
137        parameters (stopping conditions, step size, etc.).  Use  MinASASet??????()
138        functions to tune optimization parameters.
139
140        After   all   optimization   parameters   are   tuned,   you   should  use
141        MinASAIteration() function to advance algorithm iterations.
142
143        NOTES:
144
145        1. you may tune stopping conditions with MinASASetCond() function
146        2. if target function contains exp() or other fast growing functions,  and
147           optimization algorithm makes too large steps which leads  to  overflow,
148           use MinASASetStpMax() function to bound algorithm's steps.
149
150          -- ALGLIB --
151             Copyright 25.03.2010 by Bochkanov Sergey
152        *************************************************************************/
153        public static void minasacreate(int n,
154            ref double[] x,
155            ref double[] bndl,
156            ref double[] bndu,
157            ref minasastate state)
158        {
159            int i = 0;
160            int i_ = 0;
161
162            System.Diagnostics.Debug.Assert(n>=1, "MinASA: N too small!");
163            for(i=0; i<=n-1; i++)
164            {
165                System.Diagnostics.Debug.Assert((double)(bndl[i])<=(double)(bndu[i]), "MinASA: inconsistent bounds!");
166                System.Diagnostics.Debug.Assert((double)(bndl[i])<=(double)(x[i]), "MinASA: infeasible X!");
167                System.Diagnostics.Debug.Assert((double)(x[i])<=(double)(bndu[i]), "MinASA: infeasible X!");
168            }
169           
170            //
171            // Initialize
172            //
173            state.n = n;
174            minasasetcond(ref state, 0, 0, 0, 0);
175            minasasetxrep(ref state, false);
176            minasasetstpmax(ref state, 0);
177            minasasetalgorithm(ref state, -1);
178            state.bndl = new double[n];
179            state.bndu = new double[n];
180            state.ak = new double[n];
181            state.xk = new double[n];
182            state.dk = new double[n];
183            state.an = new double[n];
184            state.xn = new double[n];
185            state.dn = new double[n];
186            state.x = new double[n];
187            state.d = new double[n];
188            state.g = new double[n];
189            state.gc = new double[n];
190            state.work = new double[n];
191            state.yk = new double[n];
192            for(i_=0; i_<=n-1;i_++)
193            {
194                state.bndl[i_] = bndl[i_];
195            }
196            for(i_=0; i_<=n-1;i_++)
197            {
198                state.bndu[i_] = bndu[i_];
199            }
200           
201            //
202            // Prepare first run
203            //
204            for(i_=0; i_<=n-1;i_++)
205            {
206                state.x[i_] = x[i_];
207            }
208            state.rstate.ia = new int[3+1];
209            state.rstate.ba = new bool[1+1];
210            state.rstate.ra = new double[2+1];
211            state.rstate.stage = -1;
212        }
213
214
215        /*************************************************************************
216        This function sets stopping conditions for the ASA optimization algorithm.
217
218        INPUT PARAMETERS:
219            State   -   structure which stores algorithm state between calls and
220                        which is used for reverse communication. Must be initialized
221                        with MinASACreate()
222            EpsG    -   >=0
223                        The  subroutine  finishes  its  work   if   the  condition
224                        ||G||<EpsG is satisfied, where ||.|| means Euclidian norm,
225                        G - gradient.
226            EpsF    -   >=0
227                        The  subroutine  finishes  its work if on k+1-th iteration
228                        the  condition  |F(k+1)-F(k)|<=EpsF*max{|F(k)|,|F(k+1)|,1}
229                        is satisfied.
230            EpsX    -   >=0
231                        The subroutine finishes its work if  on  k+1-th  iteration
232                        the condition |X(k+1)-X(k)| <= EpsX is fulfilled.
233            MaxIts  -   maximum number of iterations. If MaxIts=0, the  number  of
234                        iterations is unlimited.
235
236        Passing EpsG=0, EpsF=0, EpsX=0 and MaxIts=0 (simultaneously) will lead to
237        automatic stopping criterion selection (small EpsX).
238
239          -- ALGLIB --
240             Copyright 02.04.2010 by Bochkanov Sergey
241        *************************************************************************/
242        public static void minasasetcond(ref minasastate state,
243            double epsg,
244            double epsf,
245            double epsx,
246            int maxits)
247        {
248            System.Diagnostics.Debug.Assert((double)(epsg)>=(double)(0), "MinASASetCond: negative EpsG!");
249            System.Diagnostics.Debug.Assert((double)(epsf)>=(double)(0), "MinASASetCond: negative EpsF!");
250            System.Diagnostics.Debug.Assert((double)(epsx)>=(double)(0), "MinASASetCond: negative EpsX!");
251            System.Diagnostics.Debug.Assert(maxits>=0, "MinASASetCond: negative MaxIts!");
252            if( (double)(epsg)==(double)(0) & (double)(epsf)==(double)(0) & (double)(epsx)==(double)(0) & maxits==0 )
253            {
254                epsx = 1.0E-6;
255            }
256            state.epsg = epsg;
257            state.epsf = epsf;
258            state.epsx = epsx;
259            state.maxits = maxits;
260        }
261
262
263        /*************************************************************************
264        This function turns on/off reporting.
265
266        INPUT PARAMETERS:
267            State   -   structure which stores algorithm state between calls and
268                        which is used for reverse communication. Must be
269                        initialized with MinASACreate()
270            NeedXRep-   whether iteration reports are needed or not
271
272        Usually  algorithm  returns from  MinASAIteration()  only  when  it  needs
273        function/gradient. However, with this function we can let  it  stop  after
274        each  iteration  (one  iteration  may  include   more  than  one  function
275        evaluation), which is indicated by XUpdated field.
276
277          -- ALGLIB --
278             Copyright 02.04.2010 by Bochkanov Sergey
279        *************************************************************************/
280        public static void minasasetxrep(ref minasastate state,
281            bool needxrep)
282        {
283            state.xrep = needxrep;
284        }
285
286
287        /*************************************************************************
288        This function sets optimization algorithm.
289
290        INPUT PARAMETERS:
291            State   -   structure which stores algorithm state between calls and
292                        which is used for reverse communication. Must be
293                        initialized with MinASACreate()
294            UAType  -   algorithm type:
295                        * -1    automatic selection of the best algorithm
296                        * 0     DY (Dai and Yuan) algorithm
297                        * 1     Hybrid DY-HS algorithm
298
299          -- ALGLIB --
300             Copyright 02.04.2010 by Bochkanov Sergey
301        *************************************************************************/
302        public static void minasasetalgorithm(ref minasastate state,
303            int algotype)
304        {
305            System.Diagnostics.Debug.Assert(algotype>=-1 & algotype<=1, "MinASASetAlgorithm: incorrect AlgoType!");
306            if( algotype==-1 )
307            {
308                algotype = 1;
309            }
310            state.cgtype = algotype;
311        }
312
313
314        /*************************************************************************
315        This function sets maximum step length
316
317        INPUT PARAMETERS:
318            State   -   structure which stores algorithm state between calls and
319                        which is used for reverse communication. Must be
320                        initialized with MinCGCreate()
321            StpMax  -   maximum step length, >=0. Set StpMax to 0.0,  if you don't
322                        want to limit step length.
323
324        Use this subroutine when you optimize target function which contains exp()
325        or  other  fast  growing  functions,  and optimization algorithm makes too
326        large  steps  which  leads  to overflow. This function allows us to reject
327        steps  that  are  too  large  (and  therefore  expose  us  to the possible
328        overflow) without actually calculating function value at the x+stp*d.
329
330          -- ALGLIB --
331             Copyright 02.04.2010 by Bochkanov Sergey
332        *************************************************************************/
333        public static void minasasetstpmax(ref minasastate state,
334            double stpmax)
335        {
336            System.Diagnostics.Debug.Assert((double)(stpmax)>=(double)(0), "MinASASetStpMax: StpMax<0!");
337            state.stpmax = stpmax;
338        }
339
340
341        /*************************************************************************
342        One ASA iteration
343
344        Called after initialization with MinASACreate.
345        See HTML documentation for examples.
346
347        INPUT PARAMETERS:
348            State   -   structure which stores algorithm state between calls and
349                        which is used for reverse communication. Must be initialized
350                        with MinASACreate.
351        RESULT:
352        * if function returned False, iterative proces has converged.
353          Use MinLBFGSResults() to obtain optimization results.
354        * if subroutine returned True, then, depending on structure fields, we
355          have one of the following situations
356
357
358        === FUNC/GRAD REQUEST ===
359        State.NeedFG is True => function value/gradient are needed.
360        Caller should calculate function value State.F and gradient
361        State.G[0..N-1] at State.X[0..N-1] and call MinLBFGSIteration() again.
362
363        === NEW INTERATION IS REPORTED ===
364        State.XUpdated is True => one more iteration was made.
365        State.X contains current position, State.F contains function value at X.
366        You can read info from these fields, but never modify  them  because  they
367        contain the only copy of optimization algorithm state.
368
369        One and only one of these fields (NeedFG, XUpdated) is true on return. New
370        iterations are reported only when reports  are  explicitly  turned  on  by
371        MinLBFGSSetXRep() function, so if you never called it, you can expect that
372        NeedFG is always True.
373
374
375          -- ALGLIB --
376             Copyright 20.03.2009 by Bochkanov Sergey
377        *************************************************************************/
378        public static bool minasaiteration(ref minasastate state)
379        {
380            bool result = new bool();
381            int n = 0;
382            int i = 0;
383            double betak = 0;
384            double v = 0;
385            double vv = 0;
386            int mcinfo = 0;
387            bool b = new bool();
388            bool stepfound = new bool();
389            int diffcnt = 0;
390            int i_ = 0;
391
392           
393            //
394            // Reverse communication preparations
395            // I know it looks ugly, but it works the same way
396            // anywhere from C++ to Python.
397            //
398            // This code initializes locals by:
399            // * random values determined during code
400            //   generation - on first subroutine call
401            // * values from previous call - on subsequent calls
402            //
403            if( state.rstate.stage>=0 )
404            {
405                n = state.rstate.ia[0];
406                i = state.rstate.ia[1];
407                mcinfo = state.rstate.ia[2];
408                diffcnt = state.rstate.ia[3];
409                b = state.rstate.ba[0];
410                stepfound = state.rstate.ba[1];
411                betak = state.rstate.ra[0];
412                v = state.rstate.ra[1];
413                vv = state.rstate.ra[2];
414            }
415            else
416            {
417                n = -983;
418                i = -989;
419                mcinfo = -834;
420                diffcnt = 900;
421                b = true;
422                stepfound = false;
423                betak = 214;
424                v = -338;
425                vv = -686;
426            }
427            if( state.rstate.stage==0 )
428            {
429                goto lbl_0;
430            }
431            if( state.rstate.stage==1 )
432            {
433                goto lbl_1;
434            }
435            if( state.rstate.stage==2 )
436            {
437                goto lbl_2;
438            }
439            if( state.rstate.stage==3 )
440            {
441                goto lbl_3;
442            }
443            if( state.rstate.stage==4 )
444            {
445                goto lbl_4;
446            }
447            if( state.rstate.stage==5 )
448            {
449                goto lbl_5;
450            }
451            if( state.rstate.stage==6 )
452            {
453                goto lbl_6;
454            }
455            if( state.rstate.stage==7 )
456            {
457                goto lbl_7;
458            }
459            if( state.rstate.stage==8 )
460            {
461                goto lbl_8;
462            }
463            if( state.rstate.stage==9 )
464            {
465                goto lbl_9;
466            }
467            if( state.rstate.stage==10 )
468            {
469                goto lbl_10;
470            }
471            if( state.rstate.stage==11 )
472            {
473                goto lbl_11;
474            }
475            if( state.rstate.stage==12 )
476            {
477                goto lbl_12;
478            }
479            if( state.rstate.stage==13 )
480            {
481                goto lbl_13;
482            }
483            if( state.rstate.stage==14 )
484            {
485                goto lbl_14;
486            }
487           
488            //
489            // Routine body
490            //
491           
492            //
493            // Prepare
494            //
495            n = state.n;
496            state.repterminationtype = 0;
497            state.repiterationscount = 0;
498            state.repnfev = 0;
499            state.debugrestartscount = 0;
500            state.cgtype = 1;
501            for(i_=0; i_<=n-1;i_++)
502            {
503                state.xk[i_] = state.x[i_];
504            }
505            for(i=0; i<=n-1; i++)
506            {
507                if( (double)(state.xk[i])==(double)(state.bndl[i]) | (double)(state.xk[i])==(double)(state.bndu[i]) )
508                {
509                    state.ak[i] = 0;
510                }
511                else
512                {
513                    state.ak[i] = 1;
514                }
515            }
516            state.mu = 0.1;
517            state.curalgo = 0;
518           
519            //
520            // Calculate F/G, initialize algorithm
521            //
522            clearrequestfields(ref state);
523            state.needfg = true;
524            state.rstate.stage = 0;
525            goto lbl_rcomm;
526        lbl_0:
527            if( ! state.xrep )
528            {
529                goto lbl_15;
530            }
531           
532            //
533            // progress report
534            //
535            clearrequestfields(ref state);
536            state.xupdated = true;
537            state.rstate.stage = 1;
538            goto lbl_rcomm;
539        lbl_1:
540        lbl_15:
541            if( (double)(asaboundedantigradnorm(ref state))<=(double)(state.epsg) )
542            {
543                state.repterminationtype = 4;
544                result = false;
545                return result;
546            }
547            state.repnfev = state.repnfev+1;
548           
549            //
550            // Main cycle
551            //
552            // At the beginning of new iteration:
553            // * CurAlgo stores current algorithm selector
554            // * State.XK, State.F and State.G store current X/F/G
555            // * State.AK stores current set of active constraints
556            //
557        lbl_17:
558            if( false )
559            {
560                goto lbl_18;
561            }
562           
563            //
564            // GPA algorithm
565            //
566            if( state.curalgo!=0 )
567            {
568                goto lbl_19;
569            }
570            state.k = 0;
571            state.acount = 0;
572        lbl_21:
573            if( false )
574            {
575                goto lbl_22;
576            }
577           
578            //
579            // Determine Dk = proj(xk - gk)-xk
580            //
581            for(i=0; i<=n-1; i++)
582            {
583                state.d[i] = asaboundval(state.xk[i]-state.g[i], state.bndl[i], state.bndu[i])-state.xk[i];
584            }
585           
586            //
587            // Armijo line search.
588            // * exact search with alpha=1 is tried first,
589            //   'exact' means that we evaluate f() EXACTLY at
590            //   bound(x-g,bndl,bndu), without intermediate floating
591            //   point operations.
592            // * alpha<1 are tried if explicit search wasn't successful
593            // Result is placed into XN.
594            //
595            // Two types of search are needed because we can't
596            // just use second type with alpha=1 because in finite
597            // precision arithmetics (x1-x0)+x0 may differ from x1.
598            // So while x1 is correctly bounded (it lie EXACTLY on
599            // boundary, if it is active), (x1-x0)+x0 may be
600            // not bounded.
601            //
602            v = 0.0;
603            for(i_=0; i_<=n-1;i_++)
604            {
605                v += state.d[i_]*state.g[i_];
606            }
607            state.dginit = v;
608            state.finit = state.f;
609            if( ! ((double)(asad1norm(ref state))<=(double)(state.stpmax) | (double)(state.stpmax)==(double)(0)) )
610            {
611                goto lbl_23;
612            }
613           
614            //
615            // Try alpha=1 step first
616            //
617            for(i=0; i<=n-1; i++)
618            {
619                state.x[i] = asaboundval(state.xk[i]-state.g[i], state.bndl[i], state.bndu[i]);
620            }
621            clearrequestfields(ref state);
622            state.needfg = true;
623            state.rstate.stage = 2;
624            goto lbl_rcomm;
625        lbl_2:
626            state.repnfev = state.repnfev+1;
627            stepfound = (double)(state.f)<=(double)(state.finit+gpaftol*state.dginit);
628            goto lbl_24;
629        lbl_23:
630            stepfound = false;
631        lbl_24:
632            if( ! stepfound )
633            {
634                goto lbl_25;
635            }
636           
637            //
638            // we are at the boundary(ies)
639            //
640            for(i_=0; i_<=n-1;i_++)
641            {
642                state.xn[i_] = state.x[i_];
643            }
644            state.stp = 1;
645            goto lbl_26;
646        lbl_25:
647           
648            //
649            // alpha=1 is too large, try smaller values
650            //
651            state.stp = 1;
652            linmin.linminnormalized(ref state.d, ref state.stp, n);
653            state.dginit = state.dginit/state.stp;
654            state.stp = gpadecay*state.stp;
655            if( (double)(state.stpmax)>(double)(0) )
656            {
657                state.stp = Math.Min(state.stp, state.stpmax);
658            }
659        lbl_27:
660            if( false )
661            {
662                goto lbl_28;
663            }
664            v = state.stp;
665            for(i_=0; i_<=n-1;i_++)
666            {
667                state.x[i_] = state.xk[i_];
668            }
669            for(i_=0; i_<=n-1;i_++)
670            {
671                state.x[i_] = state.x[i_] + v*state.d[i_];
672            }
673            clearrequestfields(ref state);
674            state.needfg = true;
675            state.rstate.stage = 3;
676            goto lbl_rcomm;
677        lbl_3:
678            state.repnfev = state.repnfev+1;
679            if( (double)(state.stp)<=(double)(stpmin) )
680            {
681                goto lbl_28;
682            }
683            if( (double)(state.f)<=(double)(state.finit+state.stp*gpaftol*state.dginit) )
684            {
685                goto lbl_28;
686            }
687            state.stp = state.stp*gpadecay;
688            goto lbl_27;
689        lbl_28:
690            for(i_=0; i_<=n-1;i_++)
691            {
692                state.xn[i_] = state.x[i_];
693            }
694        lbl_26:
695            state.repiterationscount = state.repiterationscount+1;
696            if( ! state.xrep )
697            {
698                goto lbl_29;
699            }
700           
701            //
702            // progress report
703            //
704            clearrequestfields(ref state);
705            state.xupdated = true;
706            state.rstate.stage = 4;
707            goto lbl_rcomm;
708        lbl_4:
709        lbl_29:
710           
711            //
712            // Calculate new set of active constraints.
713            // Reset counter if active set was changed.
714            // Prepare for the new iteration
715            //
716            for(i=0; i<=n-1; i++)
717            {
718                if( (double)(state.xn[i])==(double)(state.bndl[i]) | (double)(state.xn[i])==(double)(state.bndu[i]) )
719                {
720                    state.an[i] = 0;
721                }
722                else
723                {
724                    state.an[i] = 1;
725                }
726            }
727            for(i=0; i<=n-1; i++)
728            {
729                if( (double)(state.ak[i])!=(double)(state.an[i]) )
730                {
731                    state.acount = -1;
732                    break;
733                }
734            }
735            state.acount = state.acount+1;
736            for(i_=0; i_<=n-1;i_++)
737            {
738                state.xk[i_] = state.xn[i_];
739            }
740            for(i_=0; i_<=n-1;i_++)
741            {
742                state.ak[i_] = state.an[i_];
743            }
744           
745            //
746            // Stopping conditions
747            //
748            if( ! (state.repiterationscount>=state.maxits & state.maxits>0) )
749            {
750                goto lbl_31;
751            }
752           
753            //
754            // Too many iterations
755            //
756            state.repterminationtype = 5;
757            if( ! state.xrep )
758            {
759                goto lbl_33;
760            }
761            clearrequestfields(ref state);
762            state.xupdated = true;
763            state.rstate.stage = 5;
764            goto lbl_rcomm;
765        lbl_5:
766        lbl_33:
767            result = false;
768            return result;
769        lbl_31:
770            if( (double)(asaboundedantigradnorm(ref state))>(double)(state.epsg) )
771            {
772                goto lbl_35;
773            }
774           
775            //
776            // Gradient is small enough
777            //
778            state.repterminationtype = 4;
779            if( ! state.xrep )
780            {
781                goto lbl_37;
782            }
783            clearrequestfields(ref state);
784            state.xupdated = true;
785            state.rstate.stage = 6;
786            goto lbl_rcomm;
787        lbl_6:
788        lbl_37:
789            result = false;
790            return result;
791        lbl_35:
792            v = 0.0;
793            for(i_=0; i_<=n-1;i_++)
794            {
795                v += state.d[i_]*state.d[i_];
796            }
797            if( (double)(Math.Sqrt(v)*state.stp)>(double)(state.epsx) )
798            {
799                goto lbl_39;
800            }
801           
802            //
803            // Step size is too small, no further improvement is
804            // possible
805            //
806            state.repterminationtype = 2;
807            if( ! state.xrep )
808            {
809                goto lbl_41;
810            }
811            clearrequestfields(ref state);
812            state.xupdated = true;
813            state.rstate.stage = 7;
814            goto lbl_rcomm;
815        lbl_7:
816        lbl_41:
817            result = false;
818            return result;
819        lbl_39:
820            if( (double)(state.finit-state.f)>(double)(state.epsf*Math.Max(Math.Abs(state.finit), Math.Max(Math.Abs(state.f), 1.0))) )
821            {
822                goto lbl_43;
823            }
824           
825            //
826            // F(k+1)-F(k) is small enough
827            //
828            state.repterminationtype = 1;
829            if( ! state.xrep )
830            {
831                goto lbl_45;
832            }
833            clearrequestfields(ref state);
834            state.xupdated = true;
835            state.rstate.stage = 8;
836            goto lbl_rcomm;
837        lbl_8:
838        lbl_45:
839            result = false;
840            return result;
841        lbl_43:
842           
843            //
844            // Decide - should we switch algorithm or not
845            //
846            if( asauisempty(ref state) )
847            {
848                if( (double)(asaginorm(ref state))>=(double)(state.mu*asad1norm(ref state)) )
849                {
850                    state.curalgo = 1;
851                    goto lbl_22;
852                }
853                else
854                {
855                    state.mu = state.mu*asarho;
856                }
857            }
858            else
859            {
860                if( state.acount==n1 )
861                {
862                    if( (double)(asaginorm(ref state))>=(double)(state.mu*asad1norm(ref state)) )
863                    {
864                        state.curalgo = 1;
865                        goto lbl_22;
866                    }
867                }
868            }
869           
870            //
871            // Next iteration
872            //
873            state.k = state.k+1;
874            goto lbl_21;
875        lbl_22:
876        lbl_19:
877           
878            //
879            // CG algorithm
880            //
881            if( state.curalgo!=1 )
882            {
883                goto lbl_47;
884            }
885           
886            //
887            // first, check that there are non-active constraints.
888            // move to GPA algorithm, if all constraints are active
889            //
890            b = true;
891            for(i=0; i<=n-1; i++)
892            {
893                if( (double)(state.ak[i])!=(double)(0) )
894                {
895                    b = false;
896                    break;
897                }
898            }
899            if( b )
900            {
901                state.curalgo = 0;
902                goto lbl_17;
903            }
904           
905            //
906            // CG iterations
907            //
908            state.fold = state.f;
909            for(i_=0; i_<=n-1;i_++)
910            {
911                state.xk[i_] = state.x[i_];
912            }
913            for(i=0; i<=n-1; i++)
914            {
915                state.dk[i] = -(state.g[i]*state.ak[i]);
916                state.gc[i] = state.g[i]*state.ak[i];
917            }
918        lbl_49:
919            if( false )
920            {
921                goto lbl_50;
922            }
923           
924            //
925            // Store G[k] for later calculation of Y[k]
926            //
927            for(i=0; i<=n-1; i++)
928            {
929                state.yk[i] = -state.gc[i];
930            }
931           
932            //
933            // Make a CG step in direction given by DK[]:
934            // * calculate step. Step projection into feasible set
935            //   is used. It has several benefits: a) step may be
936            //   found with usual line search, b) multiple constraints
937            //   may be activated with one step, c) activated constraints
938            //   are detected in a natural way - just compare x[i] with
939            //   bounds
940            // * update active set, set B to True, if there
941            //   were changes in the set.
942            //
943            for(i_=0; i_<=n-1;i_++)
944            {
945                state.d[i_] = state.dk[i_];
946            }
947            for(i_=0; i_<=n-1;i_++)
948            {
949                state.xn[i_] = state.xk[i_];
950            }
951            state.mcstage = 0;
952            state.stp = 1;
953            linmin.linminnormalized(ref state.d, ref state.stp, n);
954            linmin.mcsrch(n, ref state.xn, ref state.f, ref state.gc, ref state.d, ref state.stp, state.stpmax, ref mcinfo, ref state.nfev, ref state.work, ref state.lstate, ref state.mcstage);
955        lbl_51:
956            if( state.mcstage==0 )
957            {
958                goto lbl_52;
959            }
960           
961            //
962            // preprocess data: bound State.XN so it belongs to the
963            // feasible set and store it in the State.X
964            //
965            for(i=0; i<=n-1; i++)
966            {
967                state.x[i] = asaboundval(state.xn[i], state.bndl[i], state.bndu[i]);
968            }
969           
970            //
971            // RComm
972            //
973            clearrequestfields(ref state);
974            state.needfg = true;
975            state.rstate.stage = 9;
976            goto lbl_rcomm;
977        lbl_9:
978           
979            //
980            // postprocess data: zero components of G corresponding to
981            // the active constraints
982            //
983            for(i=0; i<=n-1; i++)
984            {
985                if( (double)(state.x[i])==(double)(state.bndl[i]) | (double)(state.x[i])==(double)(state.bndu[i]) )
986                {
987                    state.gc[i] = 0;
988                }
989                else
990                {
991                    state.gc[i] = state.g[i];
992                }
993            }
994            linmin.mcsrch(n, ref state.xn, ref state.f, ref state.gc, ref state.d, ref state.stp, state.stpmax, ref mcinfo, ref state.nfev, ref state.work, ref state.lstate, ref state.mcstage);
995            goto lbl_51;
996        lbl_52:
997            diffcnt = 0;
998            for(i=0; i<=n-1; i++)
999            {
1000               
1001                //
1002                // XN contains unprojected result, project it,
1003                // save copy to X (will be used for progress reporting)
1004                //
1005                state.xn[i] = asaboundval(state.xn[i], state.bndl[i], state.bndu[i]);
1006               
1007                //
1008                // update active set
1009                //
1010                if( (double)(state.xn[i])==(double)(state.bndl[i]) | (double)(state.xn[i])==(double)(state.bndu[i]) )
1011                {
1012                    state.an[i] = 0;
1013                }
1014                else
1015                {
1016                    state.an[i] = 1;
1017                }
1018                if( (double)(state.an[i])!=(double)(state.ak[i]) )
1019                {
1020                    diffcnt = diffcnt+1;
1021                }
1022                state.ak[i] = state.an[i];
1023            }
1024            for(i_=0; i_<=n-1;i_++)
1025            {
1026                state.xk[i_] = state.xn[i_];
1027            }
1028            state.repnfev = state.repnfev+state.nfev;
1029            state.repiterationscount = state.repiterationscount+1;
1030            if( ! state.xrep )
1031            {
1032                goto lbl_53;
1033            }
1034           
1035            //
1036            // progress report
1037            //
1038            clearrequestfields(ref state);
1039            state.xupdated = true;
1040            state.rstate.stage = 10;
1041            goto lbl_rcomm;
1042        lbl_10:
1043        lbl_53:
1044           
1045            //
1046            // Check stopping conditions.
1047            //
1048            if( (double)(asaboundedantigradnorm(ref state))>(double)(state.epsg) )
1049            {
1050                goto lbl_55;
1051            }
1052           
1053            //
1054            // Gradient is small enough
1055            //
1056            state.repterminationtype = 4;
1057            if( ! state.xrep )
1058            {
1059                goto lbl_57;
1060            }
1061            clearrequestfields(ref state);
1062            state.xupdated = true;
1063            state.rstate.stage = 11;
1064            goto lbl_rcomm;
1065        lbl_11:
1066        lbl_57:
1067            result = false;
1068            return result;
1069        lbl_55:
1070            if( ! (state.repiterationscount>=state.maxits & state.maxits>0) )
1071            {
1072                goto lbl_59;
1073            }
1074           
1075            //
1076            // Too many iterations
1077            //
1078            state.repterminationtype = 5;
1079            if( ! state.xrep )
1080            {
1081                goto lbl_61;
1082            }
1083            clearrequestfields(ref state);
1084            state.xupdated = true;
1085            state.rstate.stage = 12;
1086            goto lbl_rcomm;
1087        lbl_12:
1088        lbl_61:
1089            result = false;
1090            return result;
1091        lbl_59:
1092            if( ! ((double)(asaginorm(ref state))>=(double)(state.mu*asad1norm(ref state)) & diffcnt==0) )
1093            {
1094                goto lbl_63;
1095            }
1096           
1097            //
1098            // These conditions are explicitly or implicitly
1099            // related to the current step size and influenced
1100            // by changes in the active constraints.
1101            //
1102            // For these reasons they are checked only when we don't
1103            // want to 'unstick' at the end of the iteration and there
1104            // were no changes in the active set.
1105            //
1106            // NOTE: consition |G|>=Mu*|D1| must be exactly opposite
1107            // to the condition used to switch back to GPA. At least
1108            // one inequality must be strict, otherwise infinite cycle
1109            // may occur when |G|=Mu*|D1| (we DON'T test stopping
1110            // conditions and we DON'T switch to GPA, so we cycle
1111            // indefinitely).
1112            //
1113            if( (double)(state.fold-state.f)>(double)(state.epsf*Math.Max(Math.Abs(state.fold), Math.Max(Math.Abs(state.f), 1.0))) )
1114            {
1115                goto lbl_65;
1116            }
1117           
1118            //
1119            // F(k+1)-F(k) is small enough
1120            //
1121            state.repterminationtype = 1;
1122            if( ! state.xrep )
1123            {
1124                goto lbl_67;
1125            }
1126            clearrequestfields(ref state);
1127            state.xupdated = true;
1128            state.rstate.stage = 13;
1129            goto lbl_rcomm;
1130        lbl_13:
1131        lbl_67:
1132            result = false;
1133            return result;
1134        lbl_65:
1135            v = 0.0;
1136            for(i_=0; i_<=n-1;i_++)
1137            {
1138                v += state.d[i_]*state.d[i_];
1139            }
1140            if( (double)(Math.Sqrt(v)*state.stp)>(double)(state.epsx) )
1141            {
1142                goto lbl_69;
1143            }
1144           
1145            //
1146            // X(k+1)-X(k) is small enough
1147            //
1148            state.repterminationtype = 2;
1149            if( ! state.xrep )
1150            {
1151                goto lbl_71;
1152            }
1153            clearrequestfields(ref state);
1154            state.xupdated = true;
1155            state.rstate.stage = 14;
1156            goto lbl_rcomm;
1157        lbl_14:
1158        lbl_71:
1159            result = false;
1160            return result;
1161        lbl_69:
1162        lbl_63:
1163           
1164            //
1165            // Check conditions for switching
1166            //
1167            if( (double)(asaginorm(ref state))<(double)(state.mu*asad1norm(ref state)) )
1168            {
1169                state.curalgo = 0;
1170                goto lbl_50;
1171            }
1172            if( diffcnt>0 )
1173            {
1174                if( asauisempty(ref state) | diffcnt>=n2 )
1175                {
1176                    state.curalgo = 1;
1177                }
1178                else
1179                {
1180                    state.curalgo = 0;
1181                }
1182                goto lbl_50;
1183            }
1184           
1185            //
1186            // Calculate D(k+1)
1187            //
1188            // Line search may result in:
1189            // * maximum feasible step being taken (already processed)
1190            // * point satisfying Wolfe conditions
1191            // * some kind of error (CG is restarted by assigning 0.0 to Beta)
1192            //
1193            if( mcinfo==1 )
1194            {
1195               
1196                //
1197                // Standard Wolfe conditions are satisfied:
1198                // * calculate Y[K] and BetaK
1199                //
1200                for(i_=0; i_<=n-1;i_++)
1201                {
1202                    state.yk[i_] = state.yk[i_] + state.gc[i_];
1203                }
1204                vv = 0.0;
1205                for(i_=0; i_<=n-1;i_++)
1206                {
1207                    vv += state.yk[i_]*state.dk[i_];
1208                }
1209                v = 0.0;
1210                for(i_=0; i_<=n-1;i_++)
1211                {
1212                    v += state.gc[i_]*state.gc[i_];
1213                }
1214                state.betady = v/vv;
1215                v = 0.0;
1216                for(i_=0; i_<=n-1;i_++)
1217                {
1218                    v += state.gc[i_]*state.yk[i_];
1219                }
1220                state.betahs = v/vv;
1221                if( state.cgtype==0 )
1222                {
1223                    betak = state.betady;
1224                }
1225                if( state.cgtype==1 )
1226                {
1227                    betak = Math.Max(0, Math.Min(state.betady, state.betahs));
1228                }
1229            }
1230            else
1231            {
1232               
1233                //
1234                // Something is wrong (may be function is too wild or too flat).
1235                //
1236                // We'll set BetaK=0, which will restart CG algorithm.
1237                // We can stop later (during normal checks) if stopping conditions are met.
1238                //
1239                betak = 0;
1240                state.debugrestartscount = state.debugrestartscount+1;
1241            }
1242            for(i_=0; i_<=n-1;i_++)
1243            {
1244                state.dn[i_] = -state.gc[i_];
1245            }
1246            for(i_=0; i_<=n-1;i_++)
1247            {
1248                state.dn[i_] = state.dn[i_] + betak*state.dk[i_];
1249            }
1250            for(i_=0; i_<=n-1;i_++)
1251            {
1252                state.dk[i_] = state.dn[i_];
1253            }
1254           
1255            //
1256            // update other information
1257            //
1258            state.fold = state.f;
1259            state.k = state.k+1;
1260            goto lbl_49;
1261        lbl_50:
1262        lbl_47:
1263            goto lbl_17;
1264        lbl_18:
1265            result = false;
1266            return result;
1267           
1268            //
1269            // Saving state
1270            //
1271        lbl_rcomm:
1272            result = true;
1273            state.rstate.ia[0] = n;
1274            state.rstate.ia[1] = i;
1275            state.rstate.ia[2] = mcinfo;
1276            state.rstate.ia[3] = diffcnt;
1277            state.rstate.ba[0] = b;
1278            state.rstate.ba[1] = stepfound;
1279            state.rstate.ra[0] = betak;
1280            state.rstate.ra[1] = v;
1281            state.rstate.ra[2] = vv;
1282            return result;
1283        }
1284
1285
1286        /*************************************************************************
1287        Conjugate gradient results
1288
1289        Called after MinASA returned False.
1290
1291        INPUT PARAMETERS:
1292            State   -   algorithm state (used by MinASAIteration).
1293
1294        OUTPUT PARAMETERS:
1295            X       -   array[0..N-1], solution
1296            Rep     -   optimization report:
1297                        * Rep.TerminationType completetion code:
1298                            * -2    rounding errors prevent further improvement.
1299                                    X contains best point found.
1300                            * -1    incorrect parameters were specified
1301                            *  1    relative function improvement is no more than
1302                                    EpsF.
1303                            *  2    relative step is no more than EpsX.
1304                            *  4    gradient norm is no more than EpsG
1305                            *  5    MaxIts steps was taken
1306                            *  7    stopping conditions are too stringent,
1307                                    further improvement is impossible
1308                        * Rep.IterationsCount contains iterations count
1309                        * NFEV countains number of function calculations
1310                        * ActiveConstraints contains number of active constraints
1311
1312          -- ALGLIB --
1313             Copyright 20.03.2009 by Bochkanov Sergey
1314        *************************************************************************/
1315        public static void minasaresults(ref minasastate state,
1316            ref double[] x,
1317            ref minasareport rep)
1318        {
1319            int i = 0;
1320            int i_ = 0;
1321
1322            x = new double[state.n-1+1];
1323            for(i_=0; i_<=state.n-1;i_++)
1324            {
1325                x[i_] = state.x[i_];
1326            }
1327            rep.iterationscount = state.repiterationscount;
1328            rep.nfev = state.repnfev;
1329            rep.terminationtype = state.repterminationtype;
1330            rep.activeconstraints = 0;
1331            for(i=0; i<=state.n-1; i++)
1332            {
1333                if( (double)(state.ak[i])==(double)(0) )
1334                {
1335                    rep.activeconstraints = rep.activeconstraints+1;
1336                }
1337            }
1338        }
1339
1340
1341        /*************************************************************************
1342        'bound' value: map X to [B1,B2]
1343
1344          -- ALGLIB --
1345             Copyright 20.03.2009 by Bochkanov Sergey
1346        *************************************************************************/
1347        private static double asaboundval(double x,
1348            double b1,
1349            double b2)
1350        {
1351            double result = 0;
1352
1353            if( (double)(x)<=(double)(b1) )
1354            {
1355                result = b1;
1356                return result;
1357            }
1358            if( (double)(x)>=(double)(b2) )
1359            {
1360                result = b2;
1361                return result;
1362            }
1363            result = x;
1364            return result;
1365        }
1366
1367
1368        /*************************************************************************
1369        Returns norm of bounded anti-gradient.
1370
1371        Bounded antigradient is a vector obtained from  anti-gradient  by  zeroing
1372        components which point outwards:
1373            result = norm(v)
1374            v[i]=0     if ((-g[i]<0)and(x[i]=bndl[i])) or
1375                          ((-g[i]>0)and(x[i]=bndu[i]))
1376            v[i]=-g[i] otherwise
1377
1378        This function may be used to check a stopping criterion.
1379
1380          -- ALGLIB --
1381             Copyright 20.03.2009 by Bochkanov Sergey
1382        *************************************************************************/
1383        private static double asaboundedantigradnorm(ref minasastate state)
1384        {
1385            double result = 0;
1386            int i = 0;
1387            double v = 0;
1388
1389            result = 0;
1390            for(i=0; i<=state.n-1; i++)
1391            {
1392                v = -state.g[i];
1393                if( (double)(state.x[i])==(double)(state.bndl[i]) & (double)(-state.g[i])<(double)(0) )
1394                {
1395                    v = 0;
1396                }
1397                if( (double)(state.x[i])==(double)(state.bndu[i]) & (double)(-state.g[i])>(double)(0) )
1398                {
1399                    v = 0;
1400                }
1401                result = result+AP.Math.Sqr(v);
1402            }
1403            result = Math.Sqrt(result);
1404            return result;
1405        }
1406
1407
1408        /*************************************************************************
1409        Returns norm of GI(x).
1410
1411        GI(x) is  a  gradient  vector  whose  components  associated  with  active
1412        constraints are zeroed. It  differs  from  bounded  anti-gradient  because
1413        components  of   GI(x)   are   zeroed  independently  of  sign(g[i]),  and
1414        anti-gradient's components are zeroed with respect to both constraint  and
1415        sign.
1416
1417          -- ALGLIB --
1418             Copyright 20.03.2009 by Bochkanov Sergey
1419        *************************************************************************/
1420        private static double asaginorm(ref minasastate state)
1421        {
1422            double result = 0;
1423            int i = 0;
1424            double v = 0;
1425
1426            result = 0;
1427            for(i=0; i<=state.n-1; i++)
1428            {
1429                if( (double)(state.x[i])!=(double)(state.bndl[i]) & (double)(state.x[i])!=(double)(state.bndu[i]) )
1430                {
1431                    result = result+AP.Math.Sqr(state.g[i]);
1432                }
1433            }
1434            result = Math.Sqrt(result);
1435            return result;
1436        }
1437
1438
1439        /*************************************************************************
1440        Returns norm(D1(State.X))
1441
1442        For a meaning of D1 see 'NEW ACTIVE SET ALGORITHM FOR BOX CONSTRAINED
1443        OPTIMIZATION' by WILLIAM W. HAGER AND HONGCHAO ZHANG.
1444
1445          -- ALGLIB --
1446             Copyright 20.03.2009 by Bochkanov Sergey
1447        *************************************************************************/
1448        private static double asad1norm(ref minasastate state)
1449        {
1450            double result = 0;
1451            int i = 0;
1452
1453            result = 0;
1454            for(i=0; i<=state.n-1; i++)
1455            {
1456                result = result+AP.Math.Sqr(asaboundval(state.x[i]-state.g[i], state.bndl[i], state.bndu[i])-state.x[i]);
1457            }
1458            result = Math.Sqrt(result);
1459            return result;
1460        }
1461
1462
1463        /*************************************************************************
1464        Returns True, if U set is empty.
1465
1466        * State.X is used as point,
1467        * State.G - as gradient,
1468        * D is calculated within function (because State.D may have different
1469          meaning depending on current optimization algorithm)
1470
1471        For a meaning of U see 'NEW ACTIVE SET ALGORITHM FOR BOX CONSTRAINED
1472        OPTIMIZATION' by WILLIAM W. HAGER AND HONGCHAO ZHANG.
1473
1474          -- ALGLIB --
1475             Copyright 20.03.2009 by Bochkanov Sergey
1476        *************************************************************************/
1477        private static bool asauisempty(ref minasastate state)
1478        {
1479            bool result = new bool();
1480            int i = 0;
1481            double d = 0;
1482            double d2 = 0;
1483            double d32 = 0;
1484
1485            d = asad1norm(ref state);
1486            d2 = Math.Sqrt(d);
1487            d32 = d*d2;
1488            result = true;
1489            for(i=0; i<=state.n-1; i++)
1490            {
1491                if( (double)(Math.Abs(state.g[i]))>=(double)(d2) & (double)(Math.Min(state.x[i]-state.bndl[i], state.bndu[i]-state.x[i]))>=(double)(d32) )
1492                {
1493                    result = false;
1494                    return result;
1495                }
1496            }
1497            return result;
1498        }
1499
1500
1501        /*************************************************************************
1502        Returns True, if optimizer "want  to  unstick"  from  one  of  the  active
1503        constraints, i.e. there is such active constraint with index I that either
1504        lower bound is active and g[i]<0, or upper bound is active and g[i]>0.
1505
1506        State.X is used as current point, State.X - as gradient.
1507          -- ALGLIB --
1508             Copyright 20.03.2009 by Bochkanov Sergey
1509        *************************************************************************/
1510        private static bool asawanttounstick(ref minasastate state)
1511        {
1512            bool result = new bool();
1513            int i = 0;
1514
1515            result = false;
1516            for(i=0; i<=state.n-1; i++)
1517            {
1518                if( (double)(state.x[i])==(double)(state.bndl[i]) & (double)(state.g[i])<(double)(0) )
1519                {
1520                    result = true;
1521                }
1522                if( (double)(state.x[i])==(double)(state.bndu[i]) & (double)(state.g[i])>(double)(0) )
1523                {
1524                    result = true;
1525                }
1526                if( result )
1527                {
1528                    return result;
1529                }
1530            }
1531            return result;
1532        }
1533
1534
1535        /*************************************************************************
1536        Clears request fileds (to be sure that we don't forgot to clear something)
1537        *************************************************************************/
1538        private static void clearrequestfields(ref minasastate state)
1539        {
1540            state.needfg = false;
1541            state.xupdated = false;
1542        }
1543    }
1544}
Note: See TracBrowser for help on using the repository browser.