コード例 #1
0
 /*************************************************************************
 Clears request fileds (to be sure that we don't forget to clear something)
 *************************************************************************/
 private static void clearrequestfields(minnsstate state)
 {
     state.needfi = false;
     state.needfij = false;
     state.xupdated = false;
 }
コード例 #2
0
        /*************************************************************************

        Buffered implementation of minnsresults() which uses pre-allocated  buffer
        to store X[]. If buffer size is  too  small,  it  resizes  buffer.  It  is
        intended to be used in the inner cycles of performance critical algorithms
        where array reallocation penalty is too large to be ignored.

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnsresultsbuf(minnsstate state,
            ref double[] x,
            minnsreport rep)
        {
            int i = 0;
            int i_ = 0;

            if( alglib.ap.len(x)<state.n )
            {
                x = new double[state.n];
            }
            rep.iterationscount = state.repinneriterationscount;
            rep.nfev = state.repnfev;
            rep.varidx = state.repvaridx;
            rep.funcidx = state.repfuncidx;
            rep.terminationtype = state.repterminationtype;
            rep.cerr = Math.Max(state.replcerr, state.repnlcerr);
            rep.lcerr = state.replcerr;
            rep.nlcerr = state.repnlcerr;
            if( state.repterminationtype>0 )
            {
                for(i_=0; i_<=state.n-1;i_++)
                {
                    x[i_] = state.xc[i_];
                }
            }
            else
            {
                for(i=0; i<=state.n-1; i++)
                {
                    x[i] = Double.NaN;
                }
            }
        }
コード例 #3
0
        /*************************************************************************
        This subroutine restarts algorithm from new point.
        All optimization parameters (including constraints) are left unchanged.

        This  function  allows  to  solve multiple  optimization  problems  (which
        must have  same number of dimensions) without object reallocation penalty.

        INPUT PARAMETERS:
            State   -   structure previously allocated with minnscreate() call.
            X       -   new starting point.

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnsrestartfrom(minnsstate state,
            double[] x)
        {
            int n = 0;
            int i_ = 0;

            n = state.n;
            
            //
            // First, check for errors in the inputs
            //
            alglib.ap.assert(alglib.ap.len(x)>=n, "MinNSRestartFrom: Length(X)<N");
            alglib.ap.assert(apserv.isfinitevector(x, n), "MinNSRestartFrom: X contains infinite or NaN values!");
            
            //
            // Set XC
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.xstart[i_] = x[i_];
            }
            
            //
            // prepare RComm facilities
            //
            state.rstate.ia = new int[4+1];
            state.rstate.ra = new double[2+1];
            state.rstate.stage = -1;
            clearrequestfields(state);
        }
コード例 #4
0
        /*************************************************************************

        NOTES:

        1. This function has two different implementations: one which  uses  exact
           (analytical) user-supplied Jacobian, and one which uses  only  function
           vector and numerically  differentiates  function  in  order  to  obtain
           gradient.

           Depending  on  the  specific  function  used to create optimizer object
           you should choose appropriate variant of  minnsoptimize() -  one  which
           accepts function AND Jacobian or one which accepts ONLY function.

           Be careful to choose variant of minnsoptimize()  which  corresponds  to
           your optimization scheme! Table below lists different  combinations  of
           callback (function/gradient) passed to minnsoptimize()    and  specific
           function used to create optimizer.


                             |         USER PASSED TO minnsoptimize()
           CREATED WITH      |  function only   |  function and gradient
           ------------------------------------------------------------
           minnscreatef()    |     works               FAILS
           minnscreate()     |     FAILS               works

           Here "FAILS" denotes inappropriate combinations  of  optimizer creation
           function  and  minnsoptimize()  version.   Attemps   to    use     such
           combination will lead to exception. Either  you  did  not pass gradient
           when it WAS needed or you passed gradient when it was NOT needed.

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static bool minnsiteration(minnsstate state)
        {
            bool result = new bool();
            int i = 0;
            int k = 0;
            int n = 0;
            int ng = 0;
            int nh = 0;
            double v = 0;
            double xp = 0;
            double xm = 0;
            int i_ = 0;

            
            //
            // Reverse communication preparations
            // I know it looks ugly, but it works the same way
            // anywhere from C++ to Python.
            //
            // This code initializes locals by:
            // * random values determined during code
            //   generation - on first subroutine call
            // * values from previous call - on subsequent calls
            //
            if( state.rstate.stage>=0 )
            {
                i = state.rstate.ia[0];
                k = state.rstate.ia[1];
                n = state.rstate.ia[2];
                ng = state.rstate.ia[3];
                nh = state.rstate.ia[4];
                v = state.rstate.ra[0];
                xp = state.rstate.ra[1];
                xm = state.rstate.ra[2];
            }
            else
            {
                i = -983;
                k = -989;
                n = -834;
                ng = 900;
                nh = -287;
                v = 364;
                xp = 214;
                xm = -338;
            }
            if( state.rstate.stage==0 )
            {
                goto lbl_0;
            }
            if( state.rstate.stage==1 )
            {
                goto lbl_1;
            }
            if( state.rstate.stage==2 )
            {
                goto lbl_2;
            }
            if( state.rstate.stage==3 )
            {
                goto lbl_3;
            }
            
            //
            // Routine body
            //
            
            //
            // Init
            //
            state.replcerr = 0.0;
            state.repnlcerr = 0.0;
            state.repterminationtype = 0;
            state.repinneriterationscount = 0;
            state.repouteriterationscount = 0;
            state.repnfev = 0;
            state.repvaridx = 0;
            state.repfuncidx = 0;
            state.userterminationneeded = false;
            state.dbgncholesky = 0;
            n = state.n;
            ng = state.ng;
            nh = state.nh;
            clearrequestfields(state);
            
            //
            // AGS solver
            //
            if( state.solvertype!=0 )
            {
                goto lbl_4;
            }
            if( (double)(state.diffstep)!=(double)(0) )
            {
                apserv.rvectorsetlengthatleast(ref state.xbase, n);
                apserv.rvectorsetlengthatleast(ref state.fm, 1+ng+nh);
                apserv.rvectorsetlengthatleast(ref state.fp, 1+ng+nh);
            }
            state.rstateags.ia = new int[13+1];
            state.rstateags.ba = new bool[3+1];
            state.rstateags.ra = new double[9+1];
            state.rstateags.stage = -1;
        lbl_6:
            if( !agsiteration(state) )
            {
                goto lbl_7;
            }
            
            //
            // Numerical differentiation (if needed) - intercept NeedFiJ
            // request and replace it by sequence of NeedFi requests
            //
            if( !((double)(state.diffstep)!=(double)(0) && state.needfij) )
            {
                goto lbl_8;
            }
            state.needfij = false;
            state.needfi = true;
            for(i_=0; i_<=n-1;i_++)
            {
                state.xbase[i_] = state.x[i_];
            }
            k = 0;
        lbl_10:
            if( k>n-1 )
            {
                goto lbl_12;
            }
            v = state.xbase[k];
            xm = v-state.diffstep*state.s[k];
            xp = v+state.diffstep*state.s[k];
            if( state.hasbndl[k] && (double)(xm)<(double)(state.bndl[k]) )
            {
                xm = state.bndl[k];
            }
            if( state.hasbndu[k] && (double)(xp)>(double)(state.bndu[k]) )
            {
                xp = state.bndu[k];
            }
            alglib.ap.assert((double)(xm)<=(double)(xp), "MinNS: integrity check failed");
            if( (double)(xm)==(double)(xp) )
            {
                goto lbl_13;
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.xbase[i_];
            }
            state.x[k] = xm;
            state.rstate.stage = 0;
            goto lbl_rcomm;
        lbl_0:
            for(i_=0; i_<=ng+nh;i_++)
            {
                state.fm[i_] = state.fi[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.xbase[i_];
            }
            state.x[k] = xp;
            state.rstate.stage = 1;
            goto lbl_rcomm;
        lbl_1:
            for(i_=0; i_<=ng+nh;i_++)
            {
                state.fp[i_] = state.fi[i_];
            }
            for(i_=0; i_<=ng+nh;i_++)
            {
                state.j[i_,k] = state.fp[i_];
            }
            for(i_=0; i_<=ng+nh;i_++)
            {
                state.j[i_,k] = state.j[i_,k] - state.fm[i_];
            }
            v = 1/(xp-xm);
            for(i_=0; i_<=ng+nh;i_++)
            {
                state.j[i_,k] = v*state.j[i_,k];
            }
            state.repnfev = state.repnfev+2;
            goto lbl_14;
        lbl_13:
            for(i=0; i<=ng+nh; i++)
            {
                state.j[i,k] = 0.0;
            }
        lbl_14:
            k = k+1;
            goto lbl_10;
        lbl_12:
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.xbase[i_];
            }
            state.rstate.stage = 2;
            goto lbl_rcomm;
        lbl_2:
            
            //
            // Restore previous values of fields and continue
            //
            state.needfi = false;
            state.needfij = true;
            goto lbl_6;
        lbl_8:
            
            //
            // Forward request to caller
            //
            state.rstate.stage = 3;
            goto lbl_rcomm;
        lbl_3:
            apserv.inc(ref state.repnfev);
            goto lbl_6;
        lbl_7:
            result = false;
            return result;
        lbl_4:
            result = false;
            return result;
            
            //
            // Saving state
            //
        lbl_rcomm:
            result = true;
            state.rstate.ia[0] = i;
            state.rstate.ia[1] = k;
            state.rstate.ia[2] = n;
            state.rstate.ia[3] = ng;
            state.rstate.ia[4] = nh;
            state.rstate.ra[0] = v;
            state.rstate.ra[1] = xp;
            state.rstate.ra[2] = xm;
            return result;
        }
コード例 #5
0
        /*************************************************************************
        MinNS results

        INPUT PARAMETERS:
            State   -   algorithm state

        OUTPUT PARAMETERS:
            X       -   array[0..N-1], solution
            Rep     -   optimization report. You should check Rep.TerminationType
                        in  order  to  distinguish  successful  termination  from
                        unsuccessful one:
                        * -8   internal integrity control  detected  infinite  or
                               NAN   values   in   function/gradient.    Abnormal
                               termination signalled.
                        * -3   box constraints are inconsistent
                        * -1   inconsistent parameters were passed:
                               * penalty parameter for minnssetalgoags() is zero,
                                 but we have nonlinear constraints set by minnssetnlc()
                        *  2   sampling radius decreased below epsx
                        *  7    stopping conditions are too stringent,
                                further improvement is impossible,
                                X contains best point found so far.
                        *  8    User requested termination via minnsrequesttermination()

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnsresults(minnsstate state,
            ref double[] x,
            minnsreport rep)
        {
            x = new double[0];

            minnsresultsbuf(state, ref x, rep);
        }
コード例 #6
0
        /*************************************************************************
        This function calculates merit function (target function +  penalties  for
        violation of non-box constraints),  using  State.X  (unscaled),  State.Fi,
        State.J (unscaled) and State.SampleX (scaled) as inputs.

        Results are loaded:
        * target function value - to State.SampleF0[SampleIdx]
        * merit function value - to State.SampleF[SampleIdx]
        * gradient of merit function - to State.SampleGM[SampleIdx]

          -- ALGLIB --
             Copyright 02.06.2015 by Bochkanov Sergey
        *************************************************************************/
        private static void generatemeritfunction(minnsstate state,
            int sampleidx)
        {
            int n = 0;
            int i = 0;
            int j = 0;
            int nec = 0;
            int nic = 0;
            int ng = 0;
            int nh = 0;
            double v = 0;
            double s = 0;

            n = state.n;
            nec = state.nec;
            nic = state.nic;
            ng = state.ng;
            nh = state.nh;
            
            //
            // Integrity check
            //
            for(i=0; i<=n-1; i++)
            {
                alglib.ap.assert(!state.hasbndl[i] || (double)(state.x[i])>=(double)(state.bndl[i]), "MinNS: integrity error");
                alglib.ap.assert(!state.hasbndu[i] || (double)(state.x[i])<=(double)(state.bndu[i]), "MinNS: integrity error");
            }
            
            //
            // Prepare "raw" function
            //
            state.samplef[sampleidx] = state.fi[0];
            state.samplef0[sampleidx] = state.fi[0];
            for(j=0; j<=n-1; j++)
            {
                state.samplegm[sampleidx,j] = state.j[0,j]*state.s[j];
            }
            
            //
            // Modify merit function with linear constraints
            //
            for(i=0; i<=nec+nic-1; i++)
            {
                v = -state.scaledcleic[i,n];
                for(j=0; j<=n-1; j++)
                {
                    v = v+state.scaledcleic[i,j]*state.samplex[sampleidx,j];
                }
                if( i>=nec && (double)(v)<(double)(0) )
                {
                    continue;
                }
                state.samplef[sampleidx] = state.samplef[sampleidx]+state.rholinear[i]*Math.Abs(v);
                s = Math.Sign(v);
                for(j=0; j<=n-1; j++)
                {
                    state.samplegm[sampleidx,j] = state.samplegm[sampleidx,j]+state.rholinear[i]*s*state.scaledcleic[i,j];
                }
            }
            
            //
            // Modify merit function with nonlinear constraints
            //
            for(i=1; i<=ng+nh; i++)
            {
                v = state.fi[i];
                if( i<=ng && (double)(v)==(double)(0) )
                {
                    continue;
                }
                if( i>ng && (double)(v)<=(double)(0) )
                {
                    continue;
                }
                state.samplef[sampleidx] = state.samplef[sampleidx]+state.agsrhononlinear*Math.Abs(v);
                s = Math.Sign(v);
                for(j=0; j<=n-1; j++)
                {
                    state.samplegm[sampleidx,j] = state.samplegm[sampleidx,j]+state.agsrhononlinear*s*state.j[i,j]*state.s[j];
                }
            }
        }
コード例 #7
0
        /*************************************************************************
                          NONSMOOTH NONCONVEX OPTIMIZATION
                    SUBJECT TO BOX/LINEAR/NONLINEAR-NONSMOOTH CONSTRAINTS

        DESCRIPTION:

        The  subroutine  minimizes  function   F(x)  of N arguments subject to any
        combination of:
        * bound constraints
        * linear inequality constraints
        * linear equality constraints
        * nonlinear equality constraints Gi(x)=0
        * nonlinear inequality constraints Hi(x)<=0

        IMPORTANT: see MinNSSetAlgoAGS for important  information  on  performance
                   restrictions of AGS solver.

        REQUIREMENTS:
        * starting point X0 must be feasible or not too far away from the feasible
          set
        * F(), G(), H() are continuous, locally Lipschitz  and  continuously  (but
          not necessarily twice) differentiable in an open dense  subset  of  R^N.
          Functions F(), G() and H() may be nonsmooth and non-convex.
          Informally speaking, it means  that  functions  are  composed  of  large
          differentiable "patches" with nonsmoothness having  place  only  at  the
          boundaries between these "patches".
          Most real-life nonsmooth  functions  satisfy  these  requirements.  Say,
          anything which involves finite number of abs(), min() and max() is  very
          likely to pass the test.
          Say, it is possible to optimize anything of the following:
          * f=abs(x0)+2*abs(x1)
          * f=max(x0,x1)
          * f=sin(max(x0,x1)+abs(x2))
        * for nonlinearly constrained problems: F()  must  be  bounded from  below
          without nonlinear constraints (this requirement is due to the fact that,
          contrary to box and linear constraints, nonlinear ones  require  special
          handling).
        * user must provide function value and gradient for F(), H(), G()  at  all
          points where function/gradient can be calculated. If optimizer  requires
          value exactly at the boundary between "patches" (say, at x=0 for f=abs(x)),
          where gradient is not defined, user may resolve tie arbitrarily (in  our
          case - return +1 or -1 at its discretion).
        * NS solver supports numerical differentiation, i.e. it may  differentiate
          your function for you,  but  it  results  in  2N  increase  of  function
          evaluations. Not recommended unless you solve really small problems. See
          minnscreatef() for more information on this functionality.

        USAGE:

        1. User initializes algorithm state with MinNSCreate() call  and   chooses
           what NLC solver to use. There is some solver which is used by  default,
           with default settings, but you should NOT rely on  default  choice.  It
           may change in future releases of ALGLIB without notice, and no one  can
           guarantee that new solver will be  able  to  solve  your  problem  with
           default settings.

           From the other side, if you choose solver explicitly, you can be pretty
           sure that it will work with new ALGLIB releases.

           In the current release following solvers can be used:
           * AGS solver (activated with MinNSSetAlgoAGS() function)

        2. User adds boundary and/or linear and/or nonlinear constraints by  means
           of calling one of the following functions:
           a) MinNSSetBC() for boundary constraints
           b) MinNSSetLC() for linear constraints
           c) MinNSSetNLC() for nonlinear constraints
           You may combine (a), (b) and (c) in one optimization problem.

        3. User sets scale of the variables with MinNSSetScale() function. It   is
           VERY important to set  scale  of  the  variables,  because  nonlinearly
           constrained problems are hard to solve when variables are badly scaled.

        4. User sets stopping conditions with MinNSSetCond().

        5. Finally, user calls MinNSOptimize()  function  which  takes   algorithm
           state and pointer (delegate, etc) to callback function which calculates
           F/G/H.

        7. User calls MinNSResults() to get solution

        8. Optionally user may call MinNSRestartFrom() to solve   another  problem
           with same N but another starting point. MinNSRestartFrom()  allows   to
           reuse already initialized structure.


        INPUT PARAMETERS:
            N       -   problem dimension, N>0:
                        * if given, only leading N elements of X are used
                        * if not given, automatically determined from size of X
            X       -   starting point, array[N]:
                        * it is better to set X to a feasible point
                        * but X can be infeasible, in which case algorithm will try
                          to find feasible point first, using X as initial
                          approximation.

        OUTPUT PARAMETERS:
            State   -   structure stores algorithm state

        NOTE: minnscreatef() function may be used if  you  do  not  have  analytic
              gradient.   This   function  creates  solver  which  uses  numerical
              differentiation with user-specified step.

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnscreate(int n,
            double[] x,
            minnsstate state)
        {
            alglib.ap.assert(n>=1, "MinNSCreate: N<1");
            alglib.ap.assert(alglib.ap.len(x)>=n, "MinNSCreate: Length(X)<N");
            alglib.ap.assert(apserv.isfinitevector(x, n), "MinNSCreate: X contains infinite or NaN values");
            minnsinitinternal(n, x, 0.0, state);
        }
コード例 #8
0
        /*************************************************************************
        This function sets scaling coefficients for NLC optimizer.

        ALGLIB optimizers use scaling matrices to test stopping  conditions  (step
        size and gradient are scaled before comparison with tolerances).  Scale of
        the I-th variable is a translation invariant measure of:
        a) "how large" the variable is
        b) how large the step should be to make significant changes in the function

        Scaling is also used by finite difference variant of the optimizer  - step
        along I-th axis is equal to DiffStep*S[I].

        INPUT PARAMETERS:
            State   -   structure stores algorithm state
            S       -   array[N], non-zero scaling coefficients
                        S[i] may be negative, sign doesn't matter.

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnssetscale(minnsstate state,
            double[] s)
        {
            int i = 0;

            alglib.ap.assert(alglib.ap.len(s)>=state.n, "MinNSSetScale: Length(S)<N");
            for(i=0; i<=state.n-1; i++)
            {
                alglib.ap.assert(math.isfinite(s[i]), "MinNSSetScale: S contains infinite or NAN elements");
                alglib.ap.assert((double)(s[i])!=(double)(0), "MinNSSetScale: S contains zero elements");
                state.s[i] = Math.Abs(s[i]);
            }
        }
コード例 #9
0
        /*************************************************************************
        This function tells MinNS unit to use  AGS  (adaptive  gradient  sampling)
        algorithm for nonsmooth constrained  optimization.  This  algorithm  is  a
        slight modification of one described in  "An  Adaptive  Gradient  Sampling
        Algorithm for Nonsmooth Optimization" by Frank E. Curtisy and Xiaocun Quez.

        This optimizer has following benefits and drawbacks:
        + robustness; it can be used with nonsmooth and nonconvex functions.
        + relatively easy tuning; most of the metaparameters are easy to select.
        - it has convergence of steepest descent, slower than CG/LBFGS.
        - each iteration involves evaluation of ~2N gradient values  and  solution
          of 2Nx2N quadratic programming problem, which  limits  applicability  of
          algorithm by small-scale problems (up to 50-100).

        IMPORTANT: this  algorithm  has  convergence  guarantees,   i.e.  it  will
                   steadily move towards some stationary point of the function.

                   However, "stationary point" does not  always  mean  "solution".
                   Nonsmooth problems often have "flat spots",  i.e.  areas  where
                   function do not change at all. Such "flat spots" are stationary
                   points by definition, and algorithm may be caught here.

                   Nonsmooth CONVEX tasks are not prone to  this  problem. Say, if
                   your function has form f()=MAX(f0,f1,...), and f_i are  convex,
                   then f() is convex too and you have guaranteed  convergence  to
                   solution.

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state
            Radius  -   initial sampling radius, >=0.

                        Internally multiplied  by  vector of  per-variable  scales
                        specified by minnssetscale()).

                        You should select relatively large sampling radius, roughly
                        proportional to scaled length of the first  steps  of  the
                        algorithm. Something close to 0.1 in magnitude  should  be
                        good for most problems.

                        AGS solver can automatically decrease radius, so too large
                        radius is  not a problem (assuming that you  won't  choose
                        so large radius that algorithm  will  sample  function  in
                        too far away points, where gradient value is irrelevant).

                        Too small radius won't cause algorithm to fail, but it may
                        slow down algorithm (it may  have  to  perform  too  short
                        steps).
            Penalty -   penalty coefficient for nonlinear constraints:
                        * for problem with nonlinear constraints  should  be  some
                          problem-specific  positive   value,  large  enough  that
                          penalty term changes shape of the function.
                          Starting  from  some  problem-specific   value   penalty
                          coefficient becomes  large  enough  to  exactly  enforce
                          nonlinear constraints;  larger  values  do  not  improve
                          precision.
                          Increasing it too much may slow down convergence, so you
                          should choose it carefully.
                        * can be zero for problems WITHOUT  nonlinear  constraints
                          (i.e. for unconstrained ones or ones with  just  box  or
                          linear constraints)
                        * if you specify zero value for problem with at least  one
                          nonlinear  constraint,  algorithm  will  terminate  with
                          error code -1.

        ALGORITHM OUTLINE

        The very basic outline of unconstrained AGS algorithm is given below:

        0. If sampling radius is below EpsX  or  we  performed  more  then  MaxIts
           iterations - STOP.
        1. sample O(N) gradient values at random locations  around  current point;
           informally speaking, this sample is an implicit piecewise  linear model
           of the function, although algorithm formulation does  not  mention that
           explicitly
        2. solve quadratic programming problem in order to find descent direction
        3. if QP solver tells us that we  are  near  solution,  decrease  sampling
           radius and move to (0)
        4. perform backtracking line search
        5. after moving to new point, goto (0)

        As for the constraints:
        * box constraints are handled exactly  by  modification  of  the  function
          being minimized
        * linear/nonlinear constraints are handled by adding L1  penalty.  Because
          our solver can handle nonsmoothness, we can  use  L1  penalty  function,
          which is an exact one  (i.e.  exact  solution  is  returned  under  such
          penalty).
        * penalty coefficient for  linear  constraints  is  chosen  automatically;
          however, penalty coefficient for nonlinear constraints must be specified
          by user.

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnssetalgoags(minnsstate state,
            double radius,
            double penalty)
        {
            alglib.ap.assert(math.isfinite(radius), "MinNSSetAlgoAGS: Radius is not finite");
            alglib.ap.assert((double)(radius)>(double)(0), "MinNSSetAlgoAGS: Radius<=0");
            alglib.ap.assert(math.isfinite(penalty), "MinNSSetAlgoAGS: Penalty is not finite");
            alglib.ap.assert((double)(penalty)>=(double)(0.0), "MinNSSetAlgoAGS: Penalty<0");
            state.agsrhononlinear = penalty;
            state.agsradius = radius;
            state.solvertype = 0;
        }
コード例 #10
0
        /*************************************************************************
        This function sets nonlinear constraints.

        In fact, this function sets NUMBER of nonlinear  constraints.  Constraints
        itself (constraint functions) are passed to minnsoptimize() method.   This
        method requires user-defined vector function F[]  and  its  Jacobian  J[],
        where:
        * first component of F[] and first row  of  Jacobian  J[]  correspond   to
          function being minimized
        * next NLEC components of F[] (and rows  of  J)  correspond  to  nonlinear
          equality constraints G_i(x)=0
        * next NLIC components of F[] (and rows  of  J)  correspond  to  nonlinear
          inequality constraints H_i(x)<=0

        NOTE: you may combine nonlinear constraints with linear/boundary ones.  If
              your problem has mixed constraints, you  may explicitly specify some
              of them as linear ones. It may help optimizer to  handle  them  more
              efficiently.

        INPUT PARAMETERS:
            State   -   structure previously allocated with minnscreate() call.
            NLEC    -   number of Non-Linear Equality Constraints (NLEC), >=0
            NLIC    -   number of Non-Linear Inquality Constraints (NLIC), >=0

        NOTE 1: nonlinear constraints are satisfied only  approximately!   It   is
                possible   that  algorithm  will  evaluate  function  outside   of
                the feasible area!

        NOTE 2: algorithm scales variables  according  to   scale   specified   by
                minnssetscale()  function,  so  it can handle problems with  badly
                scaled variables (as long as we KNOW their scales).

                However,  there  is  no  way  to  automatically  scale   nonlinear
                constraints Gi(x) and Hi(x). Inappropriate scaling  of  Gi/Hi  may
                ruin convergence. Solving problem with  constraint  "1000*G0(x)=0"
                is NOT same as solving it with constraint "0.001*G0(x)=0".

                It  means  that  YOU  are  the  one who is responsible for correct
                scaling of nonlinear constraints Gi(x) and Hi(x). We recommend you
                to scale nonlinear constraints in such way that I-th component  of
                dG/dX (or dH/dx) has approximately unit  magnitude  (for  problems
                with unit scale)  or  has  magnitude approximately equal to 1/S[i]
                (where S is a scale set by minnssetscale() function).

        NOTE 3: nonlinear constraints are always hard to handle,  no  matter  what
                algorithm you try to use. Even basic box/linear constraints modify
                function  curvature   by  adding   valleys  and  ridges.  However,
                nonlinear constraints add valleys which are very  hard  to  follow
                due to their "curved" nature.

                It means that optimization with single nonlinear constraint may be
                significantly slower than optimization with multiple linear  ones.
                It is normal situation, and we recommend you to  carefully  choose
                Rho parameter of minnssetalgoags(), because too  large  value  may
                slow down convergence.


          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnssetnlc(minnsstate state,
            int nlec,
            int nlic)
        {
            alglib.ap.assert(nlec>=0, "MinNSSetNLC: NLEC<0");
            alglib.ap.assert(nlic>=0, "MinNSSetNLC: NLIC<0");
            state.ng = nlec;
            state.nh = nlic;
            state.fi = new double[1+state.ng+state.nh];
            state.j = new double[1+state.ng+state.nh, state.n];
        }
コード例 #11
0
        /*************************************************************************
        This function sets stopping conditions for iterations of optimizer.

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state
            EpsX    -   >=0
                        The AGS solver finishes its work if  on  k+1-th  iteration
                        sampling radius decreases below EpsX.
            MaxIts  -   maximum number of iterations. If MaxIts=0, the  number  of
                        iterations is unlimited.

        Passing EpsX=0  and  MaxIts=0  (simultaneously)  will  lead  to  automatic
        stopping criterion selection. We do not recommend you to rely  on  default
        choice in production code.

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnssetcond(minnsstate state,
            double epsx,
            int maxits)
        {
            alglib.ap.assert(math.isfinite(epsx), "MinNSSetCond: EpsX is not finite number");
            alglib.ap.assert((double)(epsx)>=(double)(0), "MinNSSetCond: negative EpsX");
            alglib.ap.assert(maxits>=0, "MinNSSetCond: negative MaxIts!");
            if( (double)(epsx)==(double)(0) && maxits==0 )
            {
                epsx = 1.0E-6;
            }
            state.epsx = epsx;
            state.maxits = maxits;
        }
コード例 #12
0
        /*************************************************************************
        This function sets linear constraints.

        Linear constraints are inactive by default (after initial creation).
        They are preserved after algorithm restart with minnsrestartfrom().

        INPUT PARAMETERS:
            State   -   structure previously allocated with minnscreate() call.
            C       -   linear constraints, array[K,N+1].
                        Each row of C represents one constraint, either equality
                        or inequality (see below):
                        * first N elements correspond to coefficients,
                        * last element corresponds to the right part.
                        All elements of C (including right part) must be finite.
            CT      -   type of constraints, array[K]:
                        * if CT[i]>0, then I-th constraint is C[i,*]*x >= C[i,n+1]
                        * if CT[i]=0, then I-th constraint is C[i,*]*x  = C[i,n+1]
                        * if CT[i]<0, then I-th constraint is C[i,*]*x <= C[i,n+1]
            K       -   number of equality/inequality constraints, K>=0:
                        * if given, only leading K elements of C/CT are used
                        * if not given, automatically determined from sizes of C/CT

        NOTE: linear (non-bound) constraints are satisfied only approximately:

        * there always exists some minor violation (about current sampling  radius
          in magnitude during optimization, about EpsX in the solution) due to use
          of penalty method to handle constraints.
        * numerical differentiation, if used, may  lead  to  function  evaluations
          outside  of the feasible  area,   because   algorithm  does  NOT  change
          numerical differentiation formula according to linear constraints.

        If you want constraints to be  satisfied  exactly, try to reformulate your
        problem  in  such  manner  that  all constraints will become boundary ones
        (this kind of constraints is always satisfied exactly, both in  the  final
        solution and in all intermediate points).

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnssetlc(minnsstate state,
            double[,] c,
            int[] ct,
            int k)
        {
            int n = 0;
            int i = 0;
            int i_ = 0;

            n = state.n;
            
            //
            // First, check for errors in the inputs
            //
            alglib.ap.assert(k>=0, "MinNSSetLC: K<0");
            alglib.ap.assert(alglib.ap.cols(c)>=n+1 || k==0, "MinNSSetLC: Cols(C)<N+1");
            alglib.ap.assert(alglib.ap.rows(c)>=k, "MinNSSetLC: Rows(C)<K");
            alglib.ap.assert(alglib.ap.len(ct)>=k, "MinNSSetLC: Length(CT)<K");
            alglib.ap.assert(apserv.apservisfinitematrix(c, k, n+1), "MinNSSetLC: C contains infinite or NaN values!");
            
            //
            // Handle zero K
            //
            if( k==0 )
            {
                state.nec = 0;
                state.nic = 0;
                return;
            }
            
            //
            // Equality constraints are stored first, in the upper
            // NEC rows of State.CLEIC matrix. Inequality constraints
            // are stored in the next NIC rows.
            //
            // NOTE: we convert inequality constraints to the form
            // A*x<=b before copying them.
            //
            apserv.rmatrixsetlengthatleast(ref state.cleic, k, n+1);
            state.nec = 0;
            state.nic = 0;
            for(i=0; i<=k-1; i++)
            {
                if( ct[i]==0 )
                {
                    for(i_=0; i_<=n;i_++)
                    {
                        state.cleic[state.nec,i_] = c[i,i_];
                    }
                    state.nec = state.nec+1;
                }
            }
            for(i=0; i<=k-1; i++)
            {
                if( ct[i]!=0 )
                {
                    if( ct[i]>0 )
                    {
                        for(i_=0; i_<=n;i_++)
                        {
                            state.cleic[state.nec+state.nic,i_] = -c[i,i_];
                        }
                    }
                    else
                    {
                        for(i_=0; i_<=n;i_++)
                        {
                            state.cleic[state.nec+state.nic,i_] = c[i,i_];
                        }
                    }
                    state.nic = state.nic+1;
                }
            }
        }
コード例 #13
0
        /*************************************************************************
        This function sets boundary constraints.

        Boundary constraints are inactive by default (after initial creation).
        They are preserved after algorithm restart with minnsrestartfrom().

        INPUT PARAMETERS:
            State   -   structure stores algorithm state
            BndL    -   lower bounds, array[N].
                        If some (all) variables are unbounded, you may specify
                        very small number or -INF.
            BndU    -   upper bounds, array[N].
                        If some (all) variables are unbounded, you may specify
                        very large number or +INF.

        NOTE 1: it is possible to specify BndL[i]=BndU[i]. In this case I-th
        variable will be "frozen" at X[i]=BndL[i]=BndU[i].

        NOTE 2: AGS solver has following useful properties:
        * bound constraints are always satisfied exactly
        * function is evaluated only INSIDE area specified by  bound  constraints,
          even  when  numerical  differentiation is used (algorithm adjusts  nodes
          according to boundary constraints)

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnssetbc(minnsstate state,
            double[] bndl,
            double[] bndu)
        {
            int i = 0;
            int n = 0;

            n = state.n;
            alglib.ap.assert(alglib.ap.len(bndl)>=n, "MinNSSetBC: Length(BndL)<N");
            alglib.ap.assert(alglib.ap.len(bndu)>=n, "MinNSSetBC: Length(BndU)<N");
            for(i=0; i<=n-1; i++)
            {
                alglib.ap.assert(math.isfinite(bndl[i]) || Double.IsNegativeInfinity(bndl[i]), "MinNSSetBC: BndL contains NAN or +INF");
                alglib.ap.assert(math.isfinite(bndu[i]) || Double.IsPositiveInfinity(bndu[i]), "MinNSSetBC: BndL contains NAN or -INF");
                state.bndl[i] = bndl[i];
                state.hasbndl[i] = math.isfinite(bndl[i]);
                state.bndu[i] = bndu[i];
                state.hasbndu[i] = math.isfinite(bndu[i]);
            }
        }
コード例 #14
0
        /*************************************************************************
        Version of minnscreatef() which uses numerical differentiation. I.e.,  you
        do not have to calculate derivatives yourself. However, this version needs
        2N times more function evaluations.

        2-point differentiation formula is  used,  because  more  precise  4-point
        formula is unstable when used on non-smooth functions.

        INPUT PARAMETERS:
            N       -   problem dimension, N>0:
                        * if given, only leading N elements of X are used
                        * if not given, automatically determined from size of X
            X       -   starting point, array[N]:
                        * it is better to set X to a feasible point
                        * but X can be infeasible, in which case algorithm will try
                          to find feasible point first, using X as initial
                          approximation.
            DiffStep-   differentiation  step,  DiffStep>0.   Algorithm   performs
                        numerical differentiation  with  step  for  I-th  variable
                        being equal to DiffStep*S[I] (here S[] is a  scale vector,
                        set by minnssetscale() function).
                        Do not use  too  small  steps,  because  it  may  lead  to
                        catastrophic cancellation during intermediate calculations.

        OUTPUT PARAMETERS:
            State   -   structure stores algorithm state

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnscreatef(int n,
            double[] x,
            double diffstep,
            minnsstate state)
        {
            alglib.ap.assert(n>=1, "MinNSCreateF: N<1");
            alglib.ap.assert(alglib.ap.len(x)>=n, "MinNSCreateF: Length(X)<N");
            alglib.ap.assert(apserv.isfinitevector(x, n), "MinNSCreateF: X contains infinite or NaN values");
            alglib.ap.assert(math.isfinite(diffstep), "MinNSCreateF: DiffStep is infinite or NaN!");
            alglib.ap.assert((double)(diffstep)>(double)(0), "MinNSCreateF: DiffStep is non-positive!");
            minnsinitinternal(n, x, diffstep, state);
        }
コード例 #15
0
        /*************************************************************************
        Internal initialization subroutine.
        Sets default NLC solver with default criteria.
        *************************************************************************/
        private static void minnsinitinternal(int n,
            double[] x,
            double diffstep,
            minnsstate state)
        {
            int i = 0;
            double[,] c = new double[0,0];
            int[] ct = new int[0];

            state.agsinitstp = 0.2;
            state.agsstattold = 1.0E-10;
            state.agsshortstpabs = 1.0E-10;
            state.agsshortstprel = 0.75;
            state.agsshortf = 10*math.machineepsilon;
            state.agsrhononlinear = 0.0;
            state.agsraddecay = 0.2;
            state.agsalphadecay = 0.5;
            state.agsdecrease = 0.1;
            state.agsmaxraddecays = 50;
            state.agsmaxbacktrack = 20;
            state.agsmaxbacktracknonfull = 8;
            state.agspenaltylevel = 10.0;
            state.agspenaltyincrease = 20.0;
            state.agsminupdate = Math.Max(5, n/2);
            state.agssamplesize = Math.Max(2*n+1, state.agsminupdate+1);
            state.agsshortlimit = 4+state.agssamplesize/state.agsminupdate;
            
            //
            // Initialize other params
            //
            state.n = n;
            state.diffstep = diffstep;
            state.bndl = new double[n];
            state.hasbndl = new bool[n];
            state.bndu = new double[n];
            state.hasbndu = new bool[n];
            state.s = new double[n];
            state.xstart = new double[n];
            state.xc = new double[n];
            state.xn = new double[n];
            state.d = new double[n];
            state.x = new double[n];
            for(i=0; i<=n-1; i++)
            {
                state.bndl[i] = Double.NegativeInfinity;
                state.hasbndl[i] = false;
                state.bndu[i] = Double.PositiveInfinity;
                state.hasbndu[i] = false;
                state.s[i] = 1.0;
                state.xstart[i] = x[i];
                state.xc[i] = x[i];
            }
            minnssetlc(state, c, ct, 0);
            minnssetnlc(state, 0, 0);
            minnssetcond(state, 0.0, 0);
            minnssetxrep(state, false);
            minnssetalgoags(state, 0.1, 1000.0);
            minnsrestartfrom(state, x);
        }
コード例 #16
0
        /*************************************************************************
        This function turns on/off reporting.

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state
            NeedXRep-   whether iteration reports are needed or not

        If NeedXRep is True, algorithm will call rep() callback function if  it is
        provided to minnsoptimize().

          -- ALGLIB --
             Copyright 28.11.2010 by Bochkanov Sergey
        *************************************************************************/
        public static void minnssetxrep(minnsstate state,
            bool needxrep)
        {
            state.xrep = needxrep;
        }
コード例 #17
0
        /*************************************************************************
        This function performs actual processing for AUL algorith. It expects that
        caller redirects its reverse communication  requests  NeedFiJ/XUpdated  to
        external user who will provide analytic derivative (or handle reports about
        progress).

        In case external user does not have analytic derivative, it is responsibility
        of caller to intercept NeedFiJ request and  replace  it  with  appropriate
        numerical differentiation scheme.

          -- ALGLIB --
             Copyright 06.06.2015 by Bochkanov Sergey
        *************************************************************************/
        private static bool agsiteration(minnsstate state)
        {
            bool result = new bool();
            int n = 0;
            int nec = 0;
            int nic = 0;
            int ng = 0;
            int nh = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            double radius0 = 0;
            double radius = 0;
            int radiusdecays = 0;
            double alpha = 0;
            double recommendedstep = 0;
            double dnrm = 0;
            double dg = 0;
            double v = 0;
            double vv = 0;
            int maxsamplesize = 0;
            int cursamplesize = 0;
            double v0 = 0;
            double v1 = 0;
            bool restartneeded = new bool();
            bool b = new bool();
            bool alphadecreased = new bool();
            int shortstepscnt = 0;
            int backtrackits = 0;
            int maxbacktrackits = 0;
            bool fullsample = new bool();
            int i_ = 0;

            
            //
            // Reverse communication preparations
            // I know it looks ugly, but it works the same way
            // anywhere from C++ to Python.
            //
            // This code initializes locals by:
            // * random values determined during code
            //   generation - on first subroutine call
            // * values from previous call - on subsequent calls
            //
            if( state.rstateags.stage>=0 )
            {
                n = state.rstateags.ia[0];
                nec = state.rstateags.ia[1];
                nic = state.rstateags.ia[2];
                ng = state.rstateags.ia[3];
                nh = state.rstateags.ia[4];
                i = state.rstateags.ia[5];
                j = state.rstateags.ia[6];
                k = state.rstateags.ia[7];
                radiusdecays = state.rstateags.ia[8];
                maxsamplesize = state.rstateags.ia[9];
                cursamplesize = state.rstateags.ia[10];
                shortstepscnt = state.rstateags.ia[11];
                backtrackits = state.rstateags.ia[12];
                maxbacktrackits = state.rstateags.ia[13];
                restartneeded = state.rstateags.ba[0];
                b = state.rstateags.ba[1];
                alphadecreased = state.rstateags.ba[2];
                fullsample = state.rstateags.ba[3];
                radius0 = state.rstateags.ra[0];
                radius = state.rstateags.ra[1];
                alpha = state.rstateags.ra[2];
                recommendedstep = state.rstateags.ra[3];
                dnrm = state.rstateags.ra[4];
                dg = state.rstateags.ra[5];
                v = state.rstateags.ra[6];
                vv = state.rstateags.ra[7];
                v0 = state.rstateags.ra[8];
                v1 = state.rstateags.ra[9];
            }
            else
            {
                n = -686;
                nec = 912;
                nic = 585;
                ng = 497;
                nh = -271;
                i = -581;
                j = 745;
                k = -533;
                radiusdecays = -77;
                maxsamplesize = 678;
                cursamplesize = -293;
                shortstepscnt = 316;
                backtrackits = 647;
                maxbacktrackits = -756;
                restartneeded = false;
                b = true;
                alphadecreased = false;
                fullsample = false;
                radius0 = 13;
                radius = -740;
                alpha = 262;
                recommendedstep = 439;
                dnrm = 327;
                dg = 222;
                v = -589;
                vv = 274;
                v0 = 845;
                v1 = 456;
            }
            if( state.rstateags.stage==0 )
            {
                goto lbl_0;
            }
            if( state.rstateags.stage==1 )
            {
                goto lbl_1;
            }
            if( state.rstateags.stage==2 )
            {
                goto lbl_2;
            }
            if( state.rstateags.stage==3 )
            {
                goto lbl_3;
            }
            
            //
            // Routine body
            //
            alglib.ap.assert(state.solvertype==0, "MinNS: internal error");
            n = state.n;
            nec = state.nec;
            nic = state.nic;
            ng = state.ng;
            nh = state.nh;
            
            //
            // Check consistency of parameters
            //
            if( ng+nh>0 && (double)(state.agsrhononlinear)==(double)(0) )
            {
                state.repterminationtype = -1;
                result = false;
                return result;
            }
            
            //
            // Allocate arrays.
            //
            apserv.rvectorsetlengthatleast(ref state.colmax, n);
            apserv.rvectorsetlengthatleast(ref state.diagh, n);
            apserv.rvectorsetlengthatleast(ref state.signmin, n);
            apserv.rvectorsetlengthatleast(ref state.signmax, n);
            maxsamplesize = state.agssamplesize;
            apserv.rmatrixsetlengthatleast(ref state.samplex, maxsamplesize+1, n);
            apserv.rmatrixsetlengthatleast(ref state.samplegm, maxsamplesize+1, n);
            apserv.rmatrixsetlengthatleast(ref state.samplegmbc, maxsamplesize+1, n);
            apserv.rvectorsetlengthatleast(ref state.samplef, maxsamplesize+1);
            apserv.rvectorsetlengthatleast(ref state.samplef0, maxsamplesize+1);
            apserv.rvectorsetlengthatleast(ref state.grs, n);
            
            //
            // Prepare optimizer
            //
            apserv.rvectorsetlengthatleast(ref state.tmp0, maxsamplesize);
            apserv.rvectorsetlengthatleast(ref state.tmp1, maxsamplesize);
            apserv.ivectorsetlengthatleast(ref state.tmp3, 1);
            apserv.rmatrixsetlengthatleast(ref state.tmp2, 1, maxsamplesize+1);
            for(i=0; i<=maxsamplesize-1; i++)
            {
                state.tmp0[i] = 0.0;
                state.tmp1[i] = Double.PositiveInfinity;
            }
            
            //
            // Prepare RNG, seed it with fixed values so
            // that each run on same problem yeilds same results
            //
            hqrnd.hqrndseed(7235, 98532, state.agsrs);
            
            //
            // Prepare initial point subject to current bound constraints and
            // perform scaling of bound constraints, linear constraints, point itself
            //
            apserv.rvectorsetlengthatleast(ref state.scaledbndl, n);
            apserv.rvectorsetlengthatleast(ref state.scaledbndu, n);
            for(i=0; i<=n-1; i++)
            {
                
                //
                // Check and scale constraints
                //
                if( (state.hasbndl[i] && state.hasbndu[i]) && (double)(state.bndu[i])<(double)(state.bndl[i]) )
                {
                    state.repterminationtype = -3;
                    result = false;
                    return result;
                }
                if( state.hasbndl[i] )
                {
                    state.scaledbndl[i] = state.bndl[i]/state.s[i];
                }
                else
                {
                    state.scaledbndl[i] = Double.NegativeInfinity;
                }
                if( state.hasbndu[i] )
                {
                    state.scaledbndu[i] = state.bndu[i]/state.s[i];
                }
                else
                {
                    state.scaledbndu[i] = Double.PositiveInfinity;
                }
                if( state.hasbndl[i] && state.hasbndu[i] )
                {
                    alglib.ap.assert((double)(state.scaledbndl[i])<=(double)(state.scaledbndu[i]), "MinNS: integrity check failed");
                }
                if( (state.hasbndl[i] && state.hasbndu[i]) && (double)(state.bndl[i])==(double)(state.bndu[i]) )
                {
                    alglib.ap.assert((double)(state.scaledbndl[i])==(double)(state.scaledbndu[i]), "MinNS: integrity check failed");
                }
                
                //
                // Scale and constrain point
                //
                state.xc[i] = state.xstart[i];
                if( state.hasbndl[i] && (double)(state.xc[i])<=(double)(state.bndl[i]) )
                {
                    state.xc[i] = state.scaledbndl[i];
                    continue;
                }
                if( state.hasbndu[i] && (double)(state.xc[i])>=(double)(state.bndu[i]) )
                {
                    state.xc[i] = state.scaledbndu[i];
                    continue;
                }
                state.xc[i] = state.xc[i]/state.s[i];
                if( state.hasbndl[i] && (double)(state.xc[i])<=(double)(state.scaledbndl[i]) )
                {
                    state.xc[i] = state.scaledbndl[i];
                }
                if( state.hasbndu[i] && (double)(state.xc[i])>=(double)(state.scaledbndu[i]) )
                {
                    state.xc[i] = state.scaledbndu[i];
                }
            }
            apserv.rmatrixsetlengthatleast(ref state.scaledcleic, nec+nic, n+1);
            apserv.rvectorsetlengthatleast(ref state.rholinear, nec+nic);
            for(i=0; i<=nec+nic-1; i++)
            {
                
                //
                // Initial value of penalty coefficient is zero
                //
                state.rholinear[i] = 0.0;
                
                //
                // Scale and normalize linear constraints
                //
                vv = 0.0;
                for(j=0; j<=n-1; j++)
                {
                    v = state.cleic[i,j]*state.s[j];
                    state.scaledcleic[i,j] = v;
                    vv = vv+v*v;
                }
                vv = Math.Sqrt(vv);
                state.scaledcleic[i,n] = state.cleic[i,n];
                if( (double)(vv)>(double)(0) )
                {
                    for(j=0; j<=n; j++)
                    {
                        state.scaledcleic[i,j] = state.scaledcleic[i,j]/vv;
                    }
                }
            }
            
            //
            // Main cycle
            //
            // We maintain several variables during iteration:
            // * RecommendedStep-   current estimate of recommended step length;
            //                      must be Radius0 on first entry
            // * Radius         -   current sampling radius
            // * CurSampleSize  -   current sample size (may change in future versions)
            // * FullSample     -   whether we have full sample, or only partial one
            // * RadiusDecays   -   total number of decreases performed for sampling radius
            //
            radius = state.agsradius;
            radius0 = radius;
            recommendedstep = Math.Min(radius0, state.agsinitstp);
            cursamplesize = 1;
            radiusdecays = 0;
            shortstepscnt = 0;
            fullsample = false;
        lbl_4:
            if( false )
            {
                goto lbl_5;
            }
            
            //
            // First phase of iteration - central point:
            //
            // 1. evaluate function at central point - first entry in sample.
            //    Its status is ignored, it is always recalculated.
            // 2. report point and check gradient/function value for NAN/INF
            // 3. check penalty coefficients for linear terms; increase them
            //    if directional derivative of function being optimized (not
            //    merit function!) is larger than derivative of penalty.
            // 4. update report on constraint violation
            //
            cursamplesize = Math.Max(cursamplesize, 1);
            for(i_=0; i_<=n-1;i_++)
            {
                state.samplex[0,i_] = state.xc[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.xc[i_];
            }
            unscalepointbc(state, state.x);
            clearrequestfields(state);
            state.needfij = true;
            state.rstateags.stage = 0;
            goto lbl_rcomm;
        lbl_0:
            state.needfij = false;
            state.replcerr = 0.0;
            for(i=0; i<=nec+nic-1; i++)
            {
                v = -state.scaledcleic[i,n];
                for(j=0; j<=n-1; j++)
                {
                    v = v+state.scaledcleic[i,j]*state.xc[j];
                }
                if( i>=nec && (double)(v)<=(double)(0) )
                {
                    continue;
                }
                state.replcerr = Math.Max(state.replcerr, Math.Abs(v));
            }
            state.repnlcerr = 0.0;
            for(i=1; i<=ng+nh; i++)
            {
                v = state.fi[i];
                if( i>ng && (double)(v)<=(double)(0) )
                {
                    continue;
                }
                state.repnlcerr = Math.Max(state.repnlcerr, Math.Abs(v));
            }
            for(j=0; j<=n-1; j++)
            {
                state.grs[j] = state.j[0,j]*state.s[j];
            }
            generatemeritfunction(state, 0);
            if( !state.xrep )
            {
                goto lbl_6;
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.xc[i_];
            }
            state.f = state.samplef0[0];
            unscalepointbc(state, state.x);
            clearrequestfields(state);
            state.xupdated = true;
            state.rstateags.stage = 1;
            goto lbl_rcomm;
        lbl_1:
            state.xupdated = false;
        lbl_6:
            if( state.userterminationneeded )
            {
                
                //
                // User requested termination
                //
                state.repterminationtype = 8;
                goto lbl_5;
            }
            v = 0;
            for(i=0; i<=n-1; i++)
            {
                v = v+math.sqr(state.samplegm[0,i]);
            }
            if( !math.isfinite(v) || !math.isfinite(state.samplef[0]) )
            {
                
                //
                // Abnormal termination - infinities in function/gradient
                //
                state.repterminationtype = -8;
                goto lbl_5;
            }
            restartneeded = false;
            for(i=0; i<=nec+nic-1; i++)
            {
                
                //
                // Evaluate penalty function.
                //
                // Skip update if penalty is satisfied exactly (this check
                // also covers situations when I-th row is exactly zero).
                //
                v = -state.scaledcleic[i,n];
                for(j=0; j<=n-1; j++)
                {
                    v = v+state.scaledcleic[i,j]*state.xc[j];
                }
                if( i<nec && (double)(v)==(double)(0) )
                {
                    continue;
                }
                if( i>=nec && (double)(v)<=(double)(0) )
                {
                    continue;
                }
                
                //
                // Calculate directional derivative, compare it with threshold.
                //
                // NOTE: we rely on the fact that ScaledCLEIC is normalized
                //
                alglib.ap.assert((double)(state.agspenaltylevel)>(double)(1.0), "MinNS: integrity error");
                alglib.ap.assert((double)(state.agspenaltyincrease)>(double)(state.agspenaltylevel), "MinNS: integrity error");
                v = 0.0;
                for(j=0; j<=n-1; j++)
                {
                    v = v+state.grs[j]*state.scaledcleic[i,j];
                }
                v = Math.Abs(v);
                if( (double)(v*state.agspenaltylevel)>(double)(state.rholinear[i]) )
                {
                    state.rholinear[i] = v*state.agspenaltyincrease;
                    restartneeded = true;
                }
            }
            if( restartneeded )
            {
                cursamplesize = 0;
                goto lbl_4;
            }
            
            //
            // Check stopping conditions.
            //
            if( radiusdecays>=state.agsmaxraddecays )
            {
                
                //
                // Too many attempts to decrease radius
                //
                state.repterminationtype = 7;
                goto lbl_5;
            }
            if( state.repinneriterationscount>=state.maxits && state.maxits>0 )
            {
                
                //
                // Too many iterations
                //
                state.repterminationtype = 5;
                goto lbl_5;
            }
            if( (double)(radius)<=(double)(state.epsx*state.agsraddecay) )
            {
                
                //
                // Radius is smaller than required step tolerance multiplied by radius decay.
                //
                // Additional decay is required in order to make sure that optimization session
                // with radius equal to EpsX was successfully done.
                //
                state.repterminationtype = 2;
                goto lbl_5;
            }
            
            //
            // Update sample:
            //
            // 1. invalidate entries which are too far away from XC
            //    and move all valid entries to beginning of the sample.
            // 2. add new entries until we have AGSSampleSize
            //    items in our sample. We remove oldest entries from
            //    sample until we have enough place to add at least
            //    AGSMinUpdate items.
            // 3. prepare "modified" gradient sample with respect to
            //    boundary constraints.
            //
            alglib.ap.assert(cursamplesize>=1, "MinNS: integrity check failed");
            k = 1;
            for(i=1; i<=cursamplesize-1; i++)
            {
                
                //
                // If entry is outside of Radius-ball around XC, discard it.
                //
                v = 0.0;
                for(j=0; j<=n-1; j++)
                {
                    v = Math.Max(v, Math.Abs(state.samplex[i,j]-state.xc[j]));
                }
                if( (double)(v)>(double)(radius) )
                {
                    continue;
                }
                
                //
                // If central point is exactly at boundary, and corresponding
                // component of entry is OUT of boundary, entry is discarded.
                //
                b = false;
                for(j=0; j<=n-1; j++)
                {
                    b = b || ((state.hasbndl[j] && (double)(state.xc[j])==(double)(state.scaledbndl[j])) && (double)(state.samplex[i,j])!=(double)(state.scaledbndl[j]));
                    b = b || ((state.hasbndu[j] && (double)(state.xc[j])==(double)(state.scaledbndu[j])) && (double)(state.samplex[i,j])!=(double)(state.scaledbndu[j]));
                }
                if( b )
                {
                    continue;
                }
                
                //
                // Move to the beginning
                //
                for(i_=0; i_<=n-1;i_++)
                {
                    state.samplex[k,i_] = state.samplex[i,i_];
                }
                for(i_=0; i_<=n-1;i_++)
                {
                    state.samplegm[k,i_] = state.samplegm[i,i_];
                }
                state.samplef[k] = state.samplef[i];
                state.samplef0[k] = state.samplef0[i];
                k = k+1;
            }
            cursamplesize = k;
            if( state.agssamplesize-cursamplesize<state.agsminupdate )
            {
                
                //
                // Remove oldest entries
                //
                k = state.agsminupdate-(state.agssamplesize-cursamplesize);
                alglib.ap.assert(k<=cursamplesize-1, "MinNS: integrity check failed");
                for(i=1; i<=cursamplesize-k-1; i++)
                {
                    for(i_=0; i_<=n-1;i_++)
                    {
                        state.samplex[i,i_] = state.samplex[i+k,i_];
                    }
                    for(i_=0; i_<=n-1;i_++)
                    {
                        state.samplegm[i,i_] = state.samplegm[i+k,i_];
                    }
                    state.samplef[i] = state.samplef[i+k];
                    state.samplef0[i] = state.samplef0[i+k];
                }
                cursamplesize = cursamplesize-k;
            }
            k = 0;
            i = cursamplesize;
        lbl_8:
            if( i>Math.Min(cursamplesize+state.agsminupdate, state.agssamplesize)-1 )
            {
                goto lbl_10;
            }
            for(j=0; j<=n-1; j++)
            {
                
                //
                // Undistorted position
                //
                state.samplex[i,j] = state.xc[j];
                
                //
                // Do not apply distortion, if we are exactly at boundary constraint.
                //
                if( (state.hasbndl[j] && state.hasbndu[j]) && (double)(state.scaledbndl[j])==(double)(state.scaledbndu[j]) )
                {
                    continue;
                }
                if( state.hasbndl[j] && (double)(state.samplex[i,j])==(double)(state.scaledbndl[j]) )
                {
                    continue;
                }
                if( state.hasbndu[j] && (double)(state.samplex[i,j])==(double)(state.scaledbndu[j]) )
                {
                    continue;
                }
                
                //
                // Apply distortion
                //
                if( (double)(hqrnd.hqrnduniformr(state.agsrs))>=(double)(0.5) )
                {
                    
                    //
                    // Sample at the left side with 50% probability
                    //
                    v0 = state.samplex[i,j]-radius;
                    v1 = state.samplex[i,j];
                    if( state.hasbndl[j] )
                    {
                        v0 = Math.Max(state.scaledbndl[j], v0);
                    }
                }
                else
                {
                    
                    //
                    // Sample at the right side with 50% probability
                    //
                    v0 = state.samplex[i,j];
                    v1 = state.samplex[i,j]+radius;
                    if( state.hasbndu[j] )
                    {
                        v1 = Math.Min(state.scaledbndu[j], v1);
                    }
                }
                alglib.ap.assert((double)(v1)>=(double)(v0), "MinNS: integrity check failed");
                state.samplex[i,j] = apserv.boundval(v0+(v1-v0)*hqrnd.hqrnduniformr(state.agsrs), v0, v1);
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.samplex[i,i_];
            }
            unscalepointbc(state, state.x);
            clearrequestfields(state);
            state.needfij = true;
            state.rstateags.stage = 2;
            goto lbl_rcomm;
        lbl_2:
            state.needfij = false;
            generatemeritfunction(state, i);
            k = k+1;
            i = i+1;
            goto lbl_8;
        lbl_10:
            cursamplesize = cursamplesize+k;
            fullsample = cursamplesize==state.agssamplesize;
            for(j=0; j<=cursamplesize-1; j++)
            {
                
                //
                // For J-th element in gradient sample, process all of its components
                // and modify them according to status of box constraints
                //
                for(i=0; i<=n-1; i++)
                {
                    alglib.ap.assert(!state.hasbndl[i] || (double)(state.xc[i])>=(double)(state.scaledbndl[i]), "MinNS: integrity error");
                    alglib.ap.assert(!state.hasbndu[i] || (double)(state.xc[i])<=(double)(state.scaledbndu[i]), "MinNS: integrity error");
                    state.samplegmbc[j,i] = state.samplegm[j,i];
                    if( (state.hasbndl[i] && state.hasbndu[i]) && (double)(state.scaledbndl[i])==(double)(state.scaledbndu[i]) )
                    {
                        
                        //
                        // I-th box constraint is of equality type (lower bound matches upper one).
                        // Simplest case, always active.
                        //
                        state.samplegmbc[j,i] = 0.0;
                        continue;
                    }
                    if( state.hasbndl[i] && (double)(state.xc[i])==(double)(state.scaledbndl[i]) )
                    {
                        
                        //
                        // We are at lower bound.
                        //
                        // A bit more complex:
                        // * first, we have to activate/deactivate constraint depending on gradient at XC
                        // * second, in any case, I-th column of gradient sample must be non-positive
                        //
                        if( (double)(state.samplegm[0,i])>=(double)(0.0) )
                        {
                            state.samplegmbc[j,i] = 0.0;
                        }
                        state.samplegmbc[j,i] = Math.Min(state.samplegmbc[j,i], 0.0);
                        continue;
                    }
                    if( state.hasbndu[i] && (double)(state.xc[i])==(double)(state.scaledbndu[i]) )
                    {
                        
                        //
                        // We are at upper bound.
                        //
                        // A bit more complex:
                        // * first, we have to activate/deactivate constraint depending on gradient at XC
                        // * second, in any case, I-th column of gradient sample must be non-negative
                        //
                        if( (double)(state.samplegm[0,i])<=(double)(0.0) )
                        {
                            state.samplegmbc[j,i] = 0.0;
                        }
                        state.samplegmbc[j,i] = Math.Max(state.samplegmbc[j,i], 0.0);
                        continue;
                    }
                }
            }
            
            //
            // Calculate diagonal Hessian.
            //
            // This Hessian serves two purposes:
            // * first, it improves performance of gradient descent step
            // * second, it improves condition number of QP subproblem
            //   solved to determine step
            //
            // The idea is that for each variable we check whether sample
            // includes entries with alternating sign of gradient:
            // * if gradients with different signs are present, Hessian
            //   component is set to M/R, where M is a maximum magnitude
            //   of corresponding gradient component, R is a sampling radius.
            //   Note that sign=0 and sign=1 are treated as different ones
            // * if all gradients have same sign, Hessian component is
            //   set to M/R0, where R0 is initial sampling radius.
            //
            for(j=0; j<=n-1; j++)
            {
                state.colmax[j] = 0.0;
                state.signmin[j] = 1;
                state.signmax[j] = -1;
            }
            for(i=0; i<=cursamplesize-1; i++)
            {
                for(j=0; j<=n-1; j++)
                {
                    v = state.samplegmbc[i,j];
                    state.colmax[j] = Math.Max(state.colmax[j], Math.Abs(v));
                    state.signmin[j] = Math.Min(state.signmin[j], Math.Sign(v));
                    state.signmax[j] = Math.Max(state.signmax[j], Math.Sign(v));
                }
            }
            for(j=0; j<=n-1; j++)
            {
                if( (double)(state.signmin[j])!=(double)(state.signmax[j]) )
                {
                    
                    //
                    // Alternating signs of gradient - step is proportional to current sampling radius
                    //
                    alglib.ap.assert((double)(state.colmax[j])!=(double)(0), "MinNS: integrity check failed");
                    alglib.ap.assert((double)(radius)!=(double)(0), "MinNS: integrity check failed");
                    state.diagh[j] = state.colmax[j]/radius;
                    continue;
                }
                if( (double)(state.colmax[j])!=(double)(0) )
                {
                    
                    //
                    // Non-alternating sign of gradient, but non-zero.
                    // Step is proportional to initial sampling radius
                    //
                    alglib.ap.assert((double)(radius0)!=(double)(0), "MinNS: integrity check failed");
                    state.diagh[j] = state.colmax[j]/radius0;
                    continue;
                }
                state.diagh[j] = 1;
            }
            
            //
            // PROJECTION PHASE
            //
            // We project zero vector on convex hull of gradient sample.
            // If projection is small enough, we decrease radius and restart.
            // Otherwise, this phase returns search direction in State.D.
            //
            // NOTE: because we use iterative solver, it may have trouble
            //       dealing with ill-conditioned problems. So we also employ
            //       second, backup test for stationarity - when too many
            //       subsequent backtracking searches resulted in short steps.
            //
            solveqp(state.samplegmbc, state.diagh, cursamplesize, n, ref state.tmp0, ref state.dbgncholesky, state.nsqp);
            for(j=0; j<=n-1; j++)
            {
                state.d[j] = 0.0;
            }
            for(i=0; i<=cursamplesize-1; i++)
            {
                v = state.tmp0[i];
                for(i_=0; i_<=n-1;i_++)
                {
                    state.d[i_] = state.d[i_] + v*state.samplegmbc[i,i_];
                }
            }
            v = 0.0;
            for(j=0; j<=n-1; j++)
            {
                v = Math.Max(v, Math.Abs(state.d[j]/apserv.coalesce(state.colmax[j], 1.0)));
            }
            if( (double)(v)<=(double)(state.agsstattold) )
            {
                
                //
                // Stationarity test succeded.
                // Decrease radius and restart.
                //
                // NOTE: we also clear ShortStepsCnt on restart
                //
                radius = radius*state.agsraddecay;
                shortstepscnt = 0;
                apserv.inc(ref radiusdecays);
                apserv.inc(ref state.repinneriterationscount);
                goto lbl_4;
            }
            for(i=0; i<=n-1; i++)
            {
                state.d[i] = -(state.d[i]/state.diagh[i]);
            }
            
            //
            // Perform backtracking line search.
            // Update initial step length depending on search results.
            // Here we assume that D is non-zero.
            //
            // NOTE: if AGSShortLimit subsequent line searches resulted
            //       in steps shorter than AGSStatTolStp, we decrease radius.
            //
            dnrm = 0.0;
            dg = 0.0;
            for(i=0; i<=n-1; i++)
            {
                dnrm = dnrm+math.sqr(state.d[i]);
                dg = dg+state.d[i]*state.samplegmbc[0,i];
            }
            dnrm = Math.Sqrt(dnrm);
            alglib.ap.assert((double)(dnrm)>(double)(0), "MinNS: integrity error");
            alpha = recommendedstep/dnrm;
            alphadecreased = false;
            backtrackits = 0;
            if( fullsample )
            {
                maxbacktrackits = state.agsmaxbacktrack;
            }
            else
            {
                maxbacktrackits = state.agsmaxbacktracknonfull;
            }
        lbl_11:
            if( false )
            {
                goto lbl_12;
            }
            
            //
            // Prepare XN and evaluate merit function at XN
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.xn[i_] = state.xc[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.xn[i_] = state.xn[i_] + alpha*state.d[i_];
            }
            optserv.enforceboundaryconstraints(state.xn, state.scaledbndl, state.hasbndl, state.scaledbndu, state.hasbndu, n, 0);
            for(i_=0; i_<=n-1;i_++)
            {
                state.samplex[maxsamplesize,i_] = state.xn[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.xn[i_];
            }
            unscalepointbc(state, state.x);
            clearrequestfields(state);
            state.needfij = true;
            state.rstateags.stage = 3;
            goto lbl_rcomm;
        lbl_3:
            state.needfij = false;
            generatemeritfunction(state, maxsamplesize);
            
            //
            // Check sufficient decrease condition
            //
            alglib.ap.assert((double)(dnrm)>(double)(0), "MinNS: integrity error");
            if( (double)(state.samplef[maxsamplesize])<=(double)(state.samplef[0]+alpha*state.agsdecrease*dg) )
            {
                goto lbl_12;
            }
            
            //
            // Decrease Alpha
            //
            alpha = alpha*state.agsalphadecay;
            alphadecreased = true;
            
            //
            // Update and check iterations counter.
            //
            apserv.inc(ref backtrackits);
            if( backtrackits>=maxbacktrackits )
            {
                
                //
                // Too many backtracking searches performed without success.
                // Terminate iterations.
                //
                alpha = 0.0;
                alphadecreased = true;
                for(i_=0; i_<=n-1;i_++)
                {
                    state.xn[i_] = state.xc[i_];
                }
                goto lbl_12;
            }
            goto lbl_11;
        lbl_12:
            if( ((double)(alpha*dnrm)<=(double)(state.agsshortstpabs) || (double)(alpha*dnrm)<=(double)(state.agsshortstprel*radius)) || (double)(Math.Abs(state.samplef[0]-state.samplef[maxsamplesize]))<=(double)(state.agsshortf) )
            {
                apserv.inc(ref shortstepscnt);
            }
            else
            {
                shortstepscnt = 0;
            }
            if( shortstepscnt>=state.agsshortlimit )
            {
                
                //
                // Too many subsequent short steps.
                //
                // It may be possible that optimizer is unable to find out
                // that we have to decrease radius because of ill-conditioned
                // gradients.
                //
                // Decrease radius and restart.
                //
                radius = radius*state.agsraddecay;
                shortstepscnt = 0;
                apserv.inc(ref radiusdecays);
                apserv.inc(ref state.repinneriterationscount);
                goto lbl_4;
            }
            if( !alphadecreased )
            {
                recommendedstep = recommendedstep*2.0;
            }
            if( alphadecreased && fullsample )
            {
                recommendedstep = recommendedstep*0.5;
            }
            
            //
            // Next iteration
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.xc[i_] = state.xn[i_];
            }
            apserv.inc(ref state.repinneriterationscount);
            goto lbl_4;
        lbl_5:
            
            //
            // Convert back from scaled to unscaled representation
            //
            unscalepointbc(state, state.xc);
            result = false;
            return result;
            
            //
            // Saving state
            //
        lbl_rcomm:
            result = true;
            state.rstateags.ia[0] = n;
            state.rstateags.ia[1] = nec;
            state.rstateags.ia[2] = nic;
            state.rstateags.ia[3] = ng;
            state.rstateags.ia[4] = nh;
            state.rstateags.ia[5] = i;
            state.rstateags.ia[6] = j;
            state.rstateags.ia[7] = k;
            state.rstateags.ia[8] = radiusdecays;
            state.rstateags.ia[9] = maxsamplesize;
            state.rstateags.ia[10] = cursamplesize;
            state.rstateags.ia[11] = shortstepscnt;
            state.rstateags.ia[12] = backtrackits;
            state.rstateags.ia[13] = maxbacktrackits;
            state.rstateags.ba[0] = restartneeded;
            state.rstateags.ba[1] = b;
            state.rstateags.ba[2] = alphadecreased;
            state.rstateags.ba[3] = fullsample;
            state.rstateags.ra[0] = radius0;
            state.rstateags.ra[1] = radius;
            state.rstateags.ra[2] = alpha;
            state.rstateags.ra[3] = recommendedstep;
            state.rstateags.ra[4] = dnrm;
            state.rstateags.ra[5] = dg;
            state.rstateags.ra[6] = v;
            state.rstateags.ra[7] = vv;
            state.rstateags.ra[8] = v0;
            state.rstateags.ra[9] = v1;
            return result;
        }
コード例 #18
0
        /*************************************************************************
        This subroutine submits request for termination of running  optimizer.  It
        should be called from user-supplied callback when user decides that it  is
        time to "smoothly" terminate optimization process.  As  result,  optimizer
        stops at point which was "current accepted" when termination  request  was
        submitted and returns error code 8 (successful termination).

        INPUT PARAMETERS:
            State   -   optimizer structure

        NOTE: after  request  for  termination  optimizer  may   perform   several
              additional calls to user-supplied callbacks. It does  NOT  guarantee
              to stop immediately - it just guarantees that these additional calls
              will be discarded later.

        NOTE: calling this function on optimizer which is NOT running will have no
              effect.

        NOTE: multiple calls to this function are possible. First call is counted,
              subsequent calls are silently ignored.

          -- ALGLIB --
             Copyright 18.05.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void minnsrequesttermination(minnsstate state)
        {
            state.userterminationneeded = true;
        }
コード例 #19
0
        /*************************************************************************
        This function performs transformation of  X  from  scaled  coordinates  to
        unscaled ones, paying special attention to box constraints:
        * points which were exactly at the boundary before scaling will be  mapped
          to corresponding boundary after scaling
        * in any case, unscaled box constraints will be satisfied

          -- ALGLIB --
             Copyright 02.06.2015 by Bochkanov Sergey
        *************************************************************************/
        private static void unscalepointbc(minnsstate state,
            double[] x)
        {
            int i = 0;

            for(i=0; i<=state.n-1; i++)
            {
                if( state.hasbndl[i] && (double)(x[i])<=(double)(state.scaledbndl[i]) )
                {
                    x[i] = state.bndl[i];
                    continue;
                }
                if( state.hasbndu[i] && (double)(x[i])>=(double)(state.scaledbndu[i]) )
                {
                    x[i] = state.bndu[i];
                    continue;
                }
                x[i] = x[i]*state.s[i];
                if( state.hasbndl[i] && (double)(x[i])<=(double)(state.bndl[i]) )
                {
                    x[i] = state.bndl[i];
                }
                if( state.hasbndu[i] && (double)(x[i])>=(double)(state.bndu[i]) )
                {
                    x[i] = state.bndu[i];
                }
            }
        }
コード例 #20
0
 public override alglib.apobject make_copy()
 {
     minnsstate _result = new minnsstate();
     _result.solvertype = solvertype;
     _result.n = n;
     _result.epsx = epsx;
     _result.maxits = maxits;
     _result.xrep = xrep;
     _result.diffstep = diffstep;
     _result.s = (double[])s.Clone();
     _result.bndl = (double[])bndl.Clone();
     _result.bndu = (double[])bndu.Clone();
     _result.hasbndl = (bool[])hasbndl.Clone();
     _result.hasbndu = (bool[])hasbndu.Clone();
     _result.nec = nec;
     _result.nic = nic;
     _result.cleic = (double[,])cleic.Clone();
     _result.ng = ng;
     _result.nh = nh;
     _result.x = (double[])x.Clone();
     _result.f = f;
     _result.fi = (double[])fi.Clone();
     _result.j = (double[,])j.Clone();
     _result.needfij = needfij;
     _result.needfi = needfi;
     _result.xupdated = xupdated;
     _result.rstate = (rcommstate)rstate.make_copy();
     _result.rstateags = (rcommstate)rstateags.make_copy();
     _result.agsrs = (hqrnd.hqrndstate)agsrs.make_copy();
     _result.agsradius = agsradius;
     _result.agssamplesize = agssamplesize;
     _result.agsraddecay = agsraddecay;
     _result.agsalphadecay = agsalphadecay;
     _result.agsdecrease = agsdecrease;
     _result.agsinitstp = agsinitstp;
     _result.agsstattold = agsstattold;
     _result.agsshortstpabs = agsshortstpabs;
     _result.agsshortstprel = agsshortstprel;
     _result.agsshortf = agsshortf;
     _result.agsshortlimit = agsshortlimit;
     _result.agsrhononlinear = agsrhononlinear;
     _result.agsminupdate = agsminupdate;
     _result.agsmaxraddecays = agsmaxraddecays;
     _result.agsmaxbacktrack = agsmaxbacktrack;
     _result.agsmaxbacktracknonfull = agsmaxbacktracknonfull;
     _result.agspenaltylevel = agspenaltylevel;
     _result.agspenaltyincrease = agspenaltyincrease;
     _result.xstart = (double[])xstart.Clone();
     _result.xc = (double[])xc.Clone();
     _result.xn = (double[])xn.Clone();
     _result.grs = (double[])grs.Clone();
     _result.d = (double[])d.Clone();
     _result.colmax = (double[])colmax.Clone();
     _result.diagh = (double[])diagh.Clone();
     _result.signmin = (double[])signmin.Clone();
     _result.signmax = (double[])signmax.Clone();
     _result.userterminationneeded = userterminationneeded;
     _result.scaledbndl = (double[])scaledbndl.Clone();
     _result.scaledbndu = (double[])scaledbndu.Clone();
     _result.scaledcleic = (double[,])scaledcleic.Clone();
     _result.rholinear = (double[])rholinear.Clone();
     _result.samplex = (double[,])samplex.Clone();
     _result.samplegm = (double[,])samplegm.Clone();
     _result.samplegmbc = (double[,])samplegmbc.Clone();
     _result.samplef = (double[])samplef.Clone();
     _result.samplef0 = (double[])samplef0.Clone();
     _result.nsqp = (minnsqp)nsqp.make_copy();
     _result.tmp0 = (double[])tmp0.Clone();
     _result.tmp1 = (double[])tmp1.Clone();
     _result.tmp2 = (double[,])tmp2.Clone();
     _result.tmp3 = (int[])tmp3.Clone();
     _result.xbase = (double[])xbase.Clone();
     _result.fp = (double[])fp.Clone();
     _result.fm = (double[])fm.Clone();
     _result.repinneriterationscount = repinneriterationscount;
     _result.repouteriterationscount = repouteriterationscount;
     _result.repnfev = repnfev;
     _result.repvaridx = repvaridx;
     _result.repfuncidx = repfuncidx;
     _result.repterminationtype = repterminationtype;
     _result.replcerr = replcerr;
     _result.repnlcerr = repnlcerr;
     _result.dbgncholesky = dbgncholesky;
     return _result;
 }