Exemple #1
0
        public void Run(double SMALL, ref int NFTOTL, ref int NITER, int N, double F, ref double FNEW
            , ref double FM, ref double GTG, ref double OLDF, ISFUN SFUN, ref double[] G, int offset_g, double[] X, int offset_x)
        {
            #region Array Index Correction

             int o_g = -1 + offset_g;  int o_x = -1 + offset_x;
            #endregion
            // C
            // C CHECK INPUT PARAMETERS, COMPUTE THE INITIAL FUNCTION VALUE, SET
            // C CONSTANTS FOR THE SUBSEQUENT MINIMIZATION
            // C
            FM = F;
            // C
            // C COMPUTE THE INITIAL FUNCTION VALUE
            // C
            SFUN.Run(N, X, offset_x, ref FNEW, ref G, offset_g);
            NFTOTL = 1;
            // C
            // C SET CONSTANTS FOR LATER
            // C
            NITER = 0;
            OLDF = FNEW;
            GTG = this._ddot.Run(N, G, offset_g, 1, G, offset_g, 1);
            return;
        }
Exemple #2
0
        /// <param name="IERROR">
        /// - (INTEGER) ERROR CODE
        /// ( 0 =.GT. NORMAL RETURN
        /// ( 2 =.GT. MORE THAN MAXFUN EVALUATIONS
        /// ( 3 =.GT. LINE SEARCH FAILED TO FIND LOWER
        /// (          POINT (MAY NOT BE SERIOUS)
        /// (-1 =.GT. ERROR IN INPUT PARAMETERS
        ///</param>
        /// <param name="N">
        /// - (INTEGER) NUMBER OF VARIABLES
        ///</param>
        /// <param name="X">
        /// - (REAL*8) VECTOR OF LENGTH AT LEAST N; ON INPUT, AN INITIAL
        /// ESTIMATE OF THE SOLUTION; ON OUTPUT, THE COMPUTED SOLUTION.
        ///</param>
        /// <param name="F">
        /// - (REAL*8) ON INPUT, A ROUGH ESTIMATE OF THE VALUE OF THE
        /// OBJECTIVE FUNCTION AT THE SOLUTION; ON OUTPUT, THE VALUE
        /// OF THE OBJECTIVE FUNCTION AT THE SOLUTION
        ///</param>
        /// <param name="G">
        /// - (REAL*8) VECTOR OF LENGTH AT LEAST N; ON OUTPUT, THE FINAL
        /// VALUE OF THE GRADIENT
        ///</param>
        /// <param name="W">
        /// - (REAL*8) WORK VECTOR OF LENGTH AT LEAST 14*N
        ///</param>
        /// <param name="LW">
        /// - (INTEGER) THE DECLARED DIMENSION OF W
        ///</param>
        /// <param name="SFUN">
        /// - A USER-SPECIFIED SUBROUTINE THAT COMPUTES THE FUNCTION
        /// AND GRADIENT OF THE OBJECTIVE FUNCTION.  IT MUST HAVE
        /// THE CALLING SEQUENCE
        /// SUBROUTINE SFUN (N, X, F, G)
        /// INTEGER           N
        /// DOUBLE PRECISION  X(N), G(N), F
        ///</param>
        /// <param name="IPIVOT">
        /// - (INTEGER) WORK VECTOR OF LENGTH AT LEAST N, USED
        /// TO RECORD WHICH VARIABLES ARE AT THEIR BOUNDS.
        ///</param>
        public void Run(ref int IERROR, int N, ref double[] X, int offset_x, ref double F, ref double[] G, int offset_g, ref double[] W, int offset_w
            , int LW, ISFUN SFUN, double[] LOW, int offset_low, double[] UP, int offset_up, ref int[] IPIVOT, int offset_ipivot)
        {
            #region Variables

            double ETA = 0; double ACCRCY = 0; double XTOL = 0; double STEPMX = 0; double DSQRT = 0;
            #endregion
            #region Implicit Variables

            int MAXIT = 0; int MSGLVL = 0; int MAXFUN = 0; int NMAX = 0;
            #endregion
            #region Array Index Correction

             int o_x = -1 + offset_x;  int o_g = -1 + offset_g;  int o_w = -1 + offset_w;  int o_low = -1 + offset_low;
             int o_up = -1 + offset_up; int o_ipivot = -1 + offset_ipivot;
            #endregion
            #region Prolog

            // C
            // C THIS ROUTINE SOLVES THE OPTIMIZATION PROBLEM
            // C
            // C   MINIMIZE     F(X)
            // C      X
            // C   SUBJECT TO   LOW <= X <= UP
            // C
            // C WHERE X IS A VECTOR OF N REAL VARIABLES.  THE METHOD USED IS
            // C A TRUNCATED-NEWTON ALGORITHM (SEE "NEWTON-TYPE MINIMIZATION VIA
            // C THE LANCZOS ALGORITHM" BY S.G. NASH (TECHNICAL REPORT 378, MATH.
            // C THE LANCZOS METHOD" BY S.G. NASH (SIAM J. NUMER. ANAL. 21 (1984),
            // C PP. 770-778).  THIS ALGORITHM FINDS A LOCAL MINIMUM OF F(X).  IT DOES
            // C NOT ASSUME THAT THE FUNCTION F IS CONVEX (AND SO CANNOT GUARANTEE A
            // C GLOBAL SOLUTION), BUT DOES ASSUME THAT THE FUNCTION IS BOUNDED BELOW.
            // C IT CAN SOLVE PROBLEMS HAVING ANY NUMBER OF VARIABLES, BUT IT IS
            // C ESPECIALLY USEFUL WHEN THE NUMBER OF VARIABLES (N) IS LARGE.
            // C
            // C SUBROUTINE PARAMETERS:
            // C
            // C IERROR  - (INTEGER) ERROR CODE
            // C           ( 0 => NORMAL RETURN
            // C           ( 2 => MORE THAN MAXFUN EVALUATIONS
            // C           ( 3 => LINE SEARCH FAILED TO FIND LOWER
            // C           (          POINT (MAY NOT BE SERIOUS)
            // C           (-1 => ERROR IN INPUT PARAMETERS
            // C N       - (INTEGER) NUMBER OF VARIABLES
            // C X       - (REAL*8) VECTOR OF LENGTH AT LEAST N; ON INPUT, AN INITIAL
            // C           ESTIMATE OF THE SOLUTION; ON OUTPUT, THE COMPUTED SOLUTION.
            // C G       - (REAL*8) VECTOR OF LENGTH AT LEAST N; ON OUTPUT, THE FINAL
            // C           VALUE OF THE GRADIENT
            // C F       - (REAL*8) ON INPUT, A ROUGH ESTIMATE OF THE VALUE OF THE
            // C           OBJECTIVE FUNCTION AT THE SOLUTION; ON OUTPUT, THE VALUE
            // C           OF THE OBJECTIVE FUNCTION AT THE SOLUTION
            // C W       - (REAL*8) WORK VECTOR OF LENGTH AT LEAST 14*N
            // C LW      - (INTEGER) THE DECLARED DIMENSION OF W
            // C SFUN    - A USER-SPECIFIED SUBROUTINE THAT COMPUTES THE FUNCTION
            // C           AND GRADIENT OF THE OBJECTIVE FUNCTION.  IT MUST HAVE
            // C           THE CALLING SEQUENCE
            // C             SUBROUTINE SFUN (N, X, F, G)
            // C             INTEGER           N
            // C             DOUBLE PRECISION  X(N), G(N), F
            // C LOW, UP - (REAL*8) VECTORS OF LENGTH AT LEAST N CONTAINING
            // C           THE LOWER AND UPPER BOUNDS ON THE VARIABLES.  IF
            // C           THERE ARE NO BOUNDS ON A PARTICULAR VARIABLE, SET
            // C           THE BOUNDS TO -1.D38 AND 1.D38, RESPECTIVELY.
            // C IPIVOT  - (INTEGER) WORK VECTOR OF LENGTH AT LEAST N, USED
            // C           TO RECORD WHICH VARIABLES ARE AT THEIR BOUNDS.
            // C
            // C THIS IS AN EASY-TO-USE DRIVER FOR THE MAIN OPTIMIZATION ROUTINE
            // C LMQNBC.  MORE EXPERIENCED USERS WHO WISH TO CUSTOMIZE PERFORMANCE
            // C OF THIS ALGORITHM SHOULD CALL LMQBC DIRECTLY.
            // C
            // C----------------------------------------------------------------------
            // C THIS ROUTINE SETS UP ALL THE PARAMETERS FOR THE TRUNCATED-NEWTON
            // C ALGORITHM.  THE PARAMETERS ARE:
            // C
            // C ETA    - SEVERITY OF THE LINESEARCH
            // C MAXFUN - MAXIMUM ALLOWABLE NUMBER OF FUNCTION EVALUATIONS
            // C XTOL   - DESIRED ACCURACY FOR THE SOLUTION X*
            // C STEPMX - MAXIMUM ALLOWABLE STEP IN THE LINESEARCH
            // C ACCRCY - ACCURACY OF COMPUTED FUNCTION VALUES
            // C MSGLVL - CONTROLS QUANTITY OF PRINTED OUTPUT
            // C          0 = NONE, 1 = ONE LINE PER MAJOR ITERATION.
            // C MAXIT  - MAXIMUM NUMBER OF INNER ITERATIONS PER STEP
            // C
            // C
            // C SET PARAMETERS FOR THE OPTIMIZATION ROUTINE
            // C
            #endregion
            #region Body

            MAXIT = N / 2;
            if (MAXIT > 50) MAXIT = 50;
            if (MAXIT <= 0) MAXIT = 1;
            MSGLVL = 1;
            MAXFUN = 150 * N;
            ETA = .25E0;
            STEPMX = 1.0E1;
            ACCRCY = 1.0E2 * this._mchpr1.Run();
            XTOL = Math.Sqrt(ACCRCY);
            // C
            // C MINIMIZE FUNCTION
            // C
            this._lmqnbc.Run(ref IERROR, N, ref X, offset_x, ref F, ref G, offset_g, ref W, offset_w
                             , LW, SFUN, LOW, offset_low, UP, offset_up, ref IPIVOT, offset_ipivot, MSGLVL
                             , MAXIT, MAXFUN, ETA, STEPMX, ACCRCY, XTOL);
            // C
            // C PRINT RESULTS
            // C
            if (IERROR != 0) ;//ERROR-ERRORWRITE(*,800)IERROR
            //ERROR-ERROR      WRITE(*,810) F;
            if (MSGLVL < 1) return;
            //ERROR-ERROR      WRITE(*,820);
            NMAX = 10;
            if (N < NMAX) NMAX = N;
            //ERROR-ERROR      WRITE(*,830) (I,X(I),I=1,NMAX);
            return;
            #endregion
        }
Exemple #3
0
        /// <param name="MODET">
        /// - INTEGER WHICH CONTROLS AMOUNT OF OUTPUT
        ///</param>
        /// <param name="ZSOL">
        /// - COMPUTED SEARCH DIRECTION
        ///</param>
        /// <param name="R">
        /// - RESIDUAL
        ///</param>
        /// <param name="G">
        /// - CURRENT GRADIENT
        ///</param>
        /// <param name="NITER">
        /// - NONLINEAR ITERATION #
        ///</param>
        public void Run(int MODET, ref double[] ZSOL, int offset_zsol, ref double[] GV, int offset_gv, ref double[] R, int offset_r, ref double[] V, int offset_v, ref double[] DIAGB, int offset_diagb
            , ref double[] EMAT, int offset_emat, double[] X, int offset_x, double[] G, int offset_g, ref double[] ZK, int offset_zk, int N, ref double[] W, int offset_w
            , int LW, int NITER, int MAXIT, ref int NFEVAL, int NMODIF, ref int NLINCG
            , bool UPD1, double YKSK, ref double GSK, double YRSR, bool LRESET, ISFUN SFUN
            , bool BOUNDS, int[] IPIVOT, int offset_ipivot, double ACCRCY, ref double GTP, double GNORM, double XNORM)
        {
            #region Variables

            double ALPHA = 0; double BETA = 0; double DELTA = 0; double PR = 0; double QOLD = 0; double QNEW = 0;
            double QTEST = 0;double RHSNRM = 0; double RNORM = 0; double RZ = 0; double RZOLD = 0; double TOL = 0; double VGV = 0;
            double DNRM2 = 0;bool FIRST = false;
            #endregion
            #region Implicit Variables

            int I = 0; int K = 0;
            #endregion
            #region Array Index Correction

             int o_zsol = -1 + offset_zsol;  int o_gv = -1 + offset_gv;  int o_r = -1 + offset_r;  int o_v = -1 + offset_v;
             int o_diagb = -1 + offset_diagb; int o_emat = -1 + offset_emat;  int o_x = -1 + offset_x;  int o_g = -1 + offset_g;
             int o_zk = -1 + offset_zk; int o_w = -1 + offset_w;  int o_ipivot = -1 + offset_ipivot;
            #endregion
            #region Prolog

            // C
            // C THIS ROUTINE PERFORMS A PRECONDITIONED CONJUGATE-GRADIENT
            // C ITERATION IN ORDER TO SOLVE THE NEWTON EQUATIONS FOR A SEARCH
            // C DIRECTION FOR A TRUNCATED-NEWTON ALGORITHM.  WHEN THE VALUE OF THE
            // C QUADRATIC MODEL IS SUFFICIENTLY REDUCED,
            // C THE ITERATION IS TERMINATED.
            // C
            // C PARAMETERS
            // C
            // C MODET       - INTEGER WHICH CONTROLS AMOUNT OF OUTPUT
            // C ZSOL        - COMPUTED SEARCH DIRECTION
            // C G           - CURRENT GRADIENT
            // C GV,GZ1,V    - SCRATCH VECTORS
            // C R           - RESIDUAL
            // C DIAGB,EMAT  - DIAGONAL PRECONDITONING MATRIX
            // C NITER       - NONLINEAR ITERATION #
            // C FEVAL       - VALUE OF QUADRATIC FUNCTION
            // C
            // C *************************************************************
            // C INITIALIZATION
            // C *************************************************************
            // C
            // C GENERAL INITIALIZATION
            // C
            #endregion
            #region Body

            if (MODET > 0) ;//ERROR-ERRORWRITE(*,800)
            if (MAXIT == 0) return;
            FIRST = true;
            RHSNRM = GNORM;
            TOL = 1.0E-12;
            QOLD = 0.0E0;
            // C
            // C INITIALIZATION FOR PRECONDITIONED CONJUGATE-GRADIENT ALGORITHM
            // C
            this._initpc.Run(DIAGB, offset_diagb, ref EMAT, offset_emat, N, ref W, offset_w, LW, MODET
                             , UPD1, YKSK, GSK, YRSR, LRESET);
            for (I = 1; I <= N; I++)
            {
                R[I + o_r] =  - G[I + o_g];
                V[I + o_v] = 0.0E0;
                ZSOL[I + o_zsol] = 0.0E0;
            }
            // C
            // C ************************************************************
            // C MAIN ITERATION
            // C ************************************************************
            // C
            for (K = 1; K <= MAXIT; K++)
            {
                NLINCG += 1;
                if (MODET > 1) ;//ERROR-ERRORWRITE(*,810)K
                // C
                // C CG ITERATION TO SOLVE SYSTEM OF EQUATIONS
                // C
                if (BOUNDS) this._ztime.Run(N, ref R, offset_r, IPIVOT, offset_ipivot);
                this._msolve.Run(R, offset_r, ref ZK, offset_zk, N, ref W, offset_w, LW, UPD1
                                 , YKSK, ref GSK, YRSR, LRESET, FIRST);
                if (BOUNDS) this._ztime.Run(N, ref ZK, offset_zk, IPIVOT, offset_ipivot);
                RZ = this._ddot.Run(N, R, offset_r, 1, ZK, offset_zk, 1);
                if (RZ / RHSNRM < TOL) goto LABEL80;
                if (K == 1) BETA = 0.0E0;
                if (K > 1) BETA = RZ / RZOLD;
                for (I = 1; I <= N; I++)
                {
                    V[I + o_v] = ZK[I + o_zk] + BETA * V[I + o_v];
                }
                if (BOUNDS) this._ztime.Run(N, ref V, offset_v, IPIVOT, offset_ipivot);
                this._gtims.Run(V, offset_v, ref GV, offset_gv, N, X, offset_x, G, offset_g, ref W, offset_w
                                , LW, SFUN, ref FIRST, ref DELTA, ACCRCY, XNORM);
                if (BOUNDS) this._ztime.Run(N, ref GV, offset_gv, IPIVOT, offset_ipivot);
                NFEVAL += 1;
                VGV = this._ddot.Run(N, V, offset_v, 1, GV, offset_gv, 1);
                if (VGV / RHSNRM < TOL) goto LABEL50;
                this._ndia3.Run(N, ref EMAT, offset_emat, V, offset_v, GV, offset_gv, R, offset_r, VGV
                                , MODET);
                // C
                // C COMPUTE LINEAR STEP LENGTH
                // C
                ALPHA = RZ / VGV;
                if (MODET >= 1) ;//ERROR-ERRORWRITE(*,820)ALPHA
                // C
                // C COMPUTE CURRENT SOLUTION AND RELATED VECTORS
                // C
                this._daxpy.Run(N, ALPHA, V, offset_v, 1, ref ZSOL, offset_zsol, 1);
                this._daxpy.Run(N,  - ALPHA, GV, offset_gv, 1, ref R, offset_r, 1);
                // C
                // C TEST FOR CONVERGENCE
                // C
                GTP = this._ddot.Run(N, ZSOL, offset_zsol, 1, G, offset_g, 1);
                PR = this._ddot.Run(N, R, offset_r, 1, ZSOL, offset_zsol, 1);
                QNEW = 5.0E-1 * (GTP + PR);
                QTEST = K * (1.0E0 - QOLD / QNEW);
                if (QTEST < 0.0E0) goto LABEL70;
                QOLD = QNEW;
                if (QTEST <= 5.0E-1) goto LABEL70;
                // C
                // C PERFORM CAUTIONARY TEST
                // C
                if (GTP > 0) goto LABEL40;
                RZOLD = RZ;
            }
            // C
            // C TERMINATE ALGORITHM
            // C
            K -= 1;
            goto LABEL70;
            // C
            // C TRUNCATE ALGORITHM IN CASE OF AN EMERGENCY
            // C
            LABEL40:
            if (MODET >=  - 1) ;//ERROR-ERRORWRITE(*,830)K
            this._daxpy.Run(N,  - ALPHA, V, offset_v, 1, ref ZSOL, offset_zsol, 1);
            GTP = this._ddot.Run(N, ZSOL, offset_zsol, 1, G, offset_g, 1);
            goto LABEL90;
            LABEL50:;
            if (MODET >  - 2) ;//ERROR-ERRORWRITE(*,840)

            if (K > 1) goto LABEL70;
            this._msolve.Run(G, offset_g, ref ZSOL, offset_zsol, N, ref W, offset_w, LW, UPD1
                             , YKSK, ref GSK, YRSR, LRESET, FIRST);
            this._negvec.Run(N, ref ZSOL, offset_zsol);
            if (BOUNDS) this._ztime.Run(N, ref ZSOL, offset_zsol, IPIVOT, offset_ipivot);
            GTP = this._ddot.Run(N, ZSOL, offset_zsol, 1, G, offset_g, 1);
            LABEL70:;
            if (MODET >=  - 1) ;//ERROR-ERRORWRITE(*,850)K,RNORM
            goto LABEL90;
            LABEL80:;
            if (MODET >=  - 1) ;//ERROR-ERRORWRITE(*,860)
            if (K > 1) goto LABEL70;
            this._dcopy.Run(N, G, offset_g, 1, ref ZSOL, offset_zsol, 1);
            this._negvec.Run(N, ref ZSOL, offset_zsol);
            if (BOUNDS) this._ztime.Run(N, ref ZSOL, offset_zsol, IPIVOT, offset_ipivot);
            GTP = this._ddot.Run(N, ZSOL, offset_zsol, 1, G, offset_g, 1);
            goto LABEL70;
            // C
            // C STORE (OR RESTORE) DIAGONAL PRECONDITIONING
            // C
            LABEL90:;
            this._dcopy.Run(N, EMAT, offset_emat, 1, ref DIAGB, offset_diagb, 1);
            return;
            #endregion
        }
Exemple #4
0
        public void Run(ref int IFAIL, int N, ref double[] X, int offset_x, ref double F, ref double[] G, int offset_g, ref double[] W, int offset_w
            , int LW, ISFUN SFUN, double[] LOW, int offset_low, double[] UP, int offset_up, ref int[] IPIVOT, int offset_ipivot, int MSGLVL
            , int MAXIT, int MAXFUN, double ETA, double STEPMX, double ACCRCY, double XTOL)
        {
            #region Variables

            int I = 0; int ICYCLE = 0; int IOLDG = 0; int IPK = 0; int IYK = 0; int NFTOTL = 0; int NITER = 0; int NM1 = 0;
            int NUMF = 0;int NWHY = 0; double ABSTOL = 0; double ALPHA = 0; double DIFNEW = 0; double DIFOLD = 0;
            double EPSMCH = 0;double EPSRED = 0; double FKEEP = 0; double FLAST = 0; double FM = 0; double FNEW = 0;
            double FOLD = 0;double FSTOP = 0; double FTEST = 0; double GNORM = 0; double GSK = 0; double GTG = 0;
            double GTPNEW = 0;double OLDF = 0; double OLDGTP = 0; double ONE = 0; double PE = 0; double PEPS = 0;
            double PNORM = 0;double RELTOL = 0; double RTEPS = 0; double RTLEPS = 0; double RTOL = 0; double RTOLSQ = 0;
            double SMALL = 0;double SPE = 0; double TINY = 0; double TNYTOL = 0; double TOLEPS = 0; double XNORM = 0;
            double YKSK = 0;double YRSR = 0; double ZERO = 0; bool CONV = false; bool LRESET = false; bool UPD1 = false;
            bool NEWCON = false;double DABS = 0; double DSQRT = 0;
            #endregion
            #region Implicit Variables

            int IER = 0; int IRESET = 0; int NFEVAL = 0; int NMODIF = 0; int NLINCG = 0; int LHYR = 0; int IDIAGB = 0;
            int MODET = 0;int ISK = 0;
            #endregion
            #region Array Index Correction

             int o_x = -1 + offset_x;  int o_g = -1 + offset_g;  int o_w = -1 + offset_w;  int o_low = -1 + offset_low;
             int o_up = -1 + offset_up; int o_ipivot = -1 + offset_ipivot;
            #endregion
            #region Prolog

            // C
            // C THIS ROUTINE IS A BOUNDS-CONSTRAINED TRUNCATED-NEWTON METHOD.
            // C THE TRUNCATED-NEWTON METHOD IS PRECONDITIONED BY A LIMITED-MEMORY
            // C QUASI-NEWTON METHOD (THIS PRECONDITIONING STRATEGY IS DEVELOPED
            // C IN THIS ROUTINE) WITH A FURTHER DIAGONAL SCALING (SEE ROUTINE NDIA3).
            // C FOR FURTHER DETAILS ON THE PARAMETERS, SEE ROUTINE TNBC.
            // C
            // C
            // C THE FOLLOWING STANDARD FUNCTIONS AND SYSTEM FUNCTIONS ARE USED
            // C
            // C
            // C CHECK THAT INITIAL X IS FEASIBLE AND THAT THE BOUNDS ARE CONSISTENT
            // C
            #endregion
            #region Body

            this._crash.Run(N, ref X, offset_x, ref IPIVOT, offset_ipivot, LOW, offset_low, UP, offset_up, ref IER);
            if (IER != 0) ;//ERROR-ERRORWRITE(*,800)
            if (IER != 0) return;
            if (MSGLVL >= 1) ;//ERROR-ERRORWRITE(*,810)
            // C
            // C INITIALIZE VARIABLES
            // C
            this._setpar.Run(N);
            UPD1 = true;
            IRESET = 0;
            NFEVAL = 0;
            NMODIF = 0;
            NLINCG = 0;
            FSTOP = F;
            CONV = false;
            ZERO = 0.0E0;
            ONE = 1.0E0;
            NM1 = N - 1;
            // C
            // C WITHIN THIS ROUTINE THE ARRAY W(LOLDG) IS SHARED BY W(LHYR)
            // C
            LHYR = LOLDG.v;
            // C
            // C CHECK PARAMETERS AND SET CONSTANTS
            // C
            this._chkucp.Run(LWTEST.v, MAXFUN, ref NWHY, N, ref ALPHA, ref EPSMCH
                             , ETA, ref PEPS, ref RTEPS, ref RTOL, ref RTOLSQ, STEPMX
                             , ref FTEST, XTOL, ref XNORM, X, offset_x, LW, ref SMALL
                             , ref TINY, ACCRCY);
            if (NWHY < 0) goto LABEL160;
            this._setucr.Run(SMALL, ref NFTOTL, ref NITER, N, F, ref FNEW
                             , ref FM, ref GTG, ref OLDF, SFUN, ref G, offset_g, X, offset_x);
            FOLD = FNEW;
            FLAST = FNEW;
            // C
            // C TEST THE LAGRANGE MULTIPLIERS TO SEE IF THEY ARE NON-NEGATIVE.
            // C BECAUSE THE CONSTRAINTS ARE ONLY LOWER BOUNDS, THE COMPONENTS
            // C OF THE GRADIENT CORRESPONDING TO THE ACTIVE CONSTRAINTS ARE THE
            // C LAGRANGE MULTIPLIERS.  AFTERWORDS, THE PROJECTED GRADIENT IS FORMED.
            // C
            for (I = 1; I <= N; I++)
            {
                if (IPIVOT[I + o_ipivot] == 2) goto LABEL10;
                if ( - IPIVOT[I + o_ipivot] * G[I + o_g] >= 0.0E0) goto LABEL10;
                IPIVOT[I + o_ipivot] = 0;
            LABEL10:;
            }
            this._ztime.Run(N, ref G, offset_g, IPIVOT, offset_ipivot);
            GTG = this._ddot.Run(N, G, offset_g, 1, G, offset_g, 1);
            if (MSGLVL >= 1)
            {
                this._monit.Run(N, X, offset_x, FNEW, G, offset_g, NITER, NFTOTL
                    , NFEVAL, Convert.ToInt32(LRESET), IPIVOT, offset_ipivot);
            }
            // C
            // C CHECK IF THE INITIAL POINT IS A LOCAL MINIMUM.
            // C
            FTEST = ONE + Math.Abs(FNEW);
            if (GTG < 1.0E-4 * EPSMCH * FTEST * FTEST) goto LABEL130;
            // C
            // C SET INITIAL VALUES TO OTHER PARAMETERS
            // C
            ICYCLE = NM1;
            TOLEPS = RTOL + RTEPS;
            RTLEPS = RTOLSQ + EPSMCH;
            GNORM = Math.Sqrt(GTG);
            DIFNEW = ZERO;
            EPSRED = 5.0E-2;
            FKEEP = FNEW;
            // C
            // C SET THE DIAGONAL OF THE APPROXIMATE HESSIAN TO UNITY.
            // C
            IDIAGB = LDIAGB.v;
            for (I = 1; I <= N; I++)
            {
                W[IDIAGB + o_w] = ONE;
                IDIAGB += 1;
            }
            // C
            // C ..................START OF MAIN ITERATIVE LOOP..........
            // C
            // C COMPUTE THE NEW SEARCH DIRECTION
            // C
            MODET = MSGLVL - 3;
            this._modlnp.Run(MODET, ref W, LPK.v + o_w, ref W, LGV.v + o_w, ref W, LZ1.v + o_w, ref W, LV.v + o_w, ref W, LDIAGB.v + o_w
                             , ref W, LEMAT.v + o_w, X, offset_x, G, offset_g, ref W, LZK.v + o_w, N, ref W, offset_w
                             , LW, NITER, MAXIT, ref NFEVAL, NMODIF, ref NLINCG
                             , UPD1, YKSK, ref GSK, YRSR, LRESET, SFUN
                             , true, IPIVOT, offset_ipivot, ACCRCY, ref GTPNEW, GNORM, XNORM);
            LABEL20:;
            this._dcopy.Run(N, G, offset_g, 1, ref W, LOLDG.v + o_w, 1);
            PNORM = this._dnrm2.Run(N, W, LPK.v + o_w, 1);
            OLDF = FNEW;
            OLDGTP = GTPNEW;
            // C
            // C PREPARE TO COMPUTE THE STEP LENGTH
            // C
            PE = PNORM + EPSMCH;
            // C
            // C COMPUTE THE ABSOLUTE AND RELATIVE TOLERANCES FOR THE LINEAR SEARCH
            // C
            RELTOL = RTEPS * (XNORM + ONE) / PE;
            ABSTOL =  - EPSMCH * FTEST / (OLDGTP - EPSMCH);
            // C
            // C COMPUTE THE SMALLEST ALLOWABLE SPACING BETWEEN POINTS IN
            // C THE LINEAR SEARCH
            // C
            TNYTOL = EPSMCH * (XNORM + ONE) / PE;
            this._stpmax.Run(STEPMX, PE, ref SPE, N, X, offset_x, W, LPK.v + o_w
                             , IPIVOT, offset_ipivot, LOW, offset_low, UP, offset_up);
            // C
            // C SET THE INITIAL STEP LENGTH.
            // C
            ALPHA = this._step1.Run(FNEW, FM, OLDGTP, SPE);
            // C
            // C PERFORM THE LINEAR SEARCH
            // C
            this._linder.Run(N, SFUN, SMALL, EPSMCH, ref RELTOL, ref ABSTOL
                             , TNYTOL, ETA, ZERO, SPE, W, LPK.v + o_w, OLDGTP
                             , ref X, offset_x, ref FNEW, ref ALPHA, ref G, offset_g, ref NUMF, ref NWHY
                             , ref W, offset_w, LW);
            NEWCON = false;
            if (Math.Abs(ALPHA - SPE) > 1.0E1 * EPSMCH) goto LABEL30;
            NEWCON = true;
            NWHY = 0;
            this._modz.Run(N, ref X, offset_x, W, LPK.v + o_w, ref IPIVOT, offset_ipivot, EPSMCH, LOW, offset_low
                           , UP, offset_up, ref FLAST, FNEW);
            FLAST = FNEW;
            // C
            LABEL30:
            if (MSGLVL >= 3) ;//ERROR-ERRORWRITE(*,820)ALPHA,PNORM
            FOLD = FNEW;
            NITER += 1;
            NFTOTL += NUMF;
            // C
            // C IF REQUIRED, PRINT THE DETAILS OF THIS ITERATION
            // C
            if (MSGLVL >= 1)
            {
                this._monit.Run(N, X, offset_x, FNEW, G, offset_g, NITER, NFTOTL
                                , NFEVAL, Convert.ToInt32(LRESET), IPIVOT, offset_ipivot);
            }
            if (NWHY < 0) goto LABEL160;
            if (NWHY == 0 || NWHY == 2) goto LABEL40;
            // C
            // C THE LINEAR SEARCH HAS FAILED TO FIND A LOWER POINT
            // C
            NWHY = 3;
            goto LABEL140;
            LABEL40:
            if (NWHY <= 1) goto LABEL50;
            SFUN.Run(N, X, offset_x, ref FNEW, ref G, offset_g);
            NFTOTL += 1;
            // C
            // C TERMINATE IF MORE THAN MAXFUN EVALUATIONS HAVE BEEN MADE
            // C
            LABEL50:  NWHY = 2;
            if (NFTOTL + NFEVAL > MAXFUN) goto LABEL150;
            NWHY = 0;
            // C
            // C SET UP PARAMETERS USED IN CONVERGENCE AND RESETTING TESTS
            // C
            DIFOLD = DIFNEW;
            DIFNEW = OLDF - FNEW;
            // C
            // C IF THIS IS THE FIRST ITERATION OF A NEW CYCLE, COMPUTE THE
            // C PERCENTAGE REDUCTION FACTOR FOR THE RESETTING TEST.
            // C
            if (ICYCLE != 1) goto LABEL60;
            if (DIFNEW > 2.0E0 * DIFOLD) EPSRED += EPSRED;
            if (DIFNEW < 5.0E-1) EPSRED = 5.0E-1;
            LABEL60:  this._dcopy.Run(N, G, offset_g, 1, ref W, LGV.v + o_w, 1);
            this._ztime.Run(N, ref W, LGV.v + o_w, IPIVOT, offset_ipivot);
            GTG = this._ddot.Run(N, W, LGV.v + o_w, 1, W, LGV.v + o_w, 1);
            GNORM = Math.Sqrt(GTG);
            FTEST = ONE + Math.Abs(FNEW);
            XNORM = this._dnrm2.Run(N, X, offset_x, 1);
            // C
            // C TEST FOR CONVERGENCE
            // C
            this._cnvtst.Run(ref CONV, ALPHA, PNORM, TOLEPS, XNORM, DIFNEW
                             , RTLEPS, FTEST, GTG, PEPS, EPSMCH, GTPNEW
                             , FNEW, ref FLAST, G, offset_g, ref IPIVOT, offset_ipivot, N, ACCRCY);
            if (CONV) goto LABEL130;
            this._ztime.Run(N, ref G, offset_g, IPIVOT, offset_ipivot);
            // C
            // C COMPUTE THE CHANGE IN THE ITERATES AND THE CORRESPONDING CHANGE
            // C IN THE GRADIENTS
            // C
            if (NEWCON) goto LABEL90;
            ISK = LSK.v;
            IPK = LPK.v;
            IYK = LYK.v;
            IOLDG = LOLDG.v;
            for (I = 1; I <= N; I++)
            {
                W[IYK + o_w] = G[I + o_g] - W[IOLDG + o_w];
                W[ISK + o_w] = ALPHA * W[IPK + o_w];
                IPK += 1;
                ISK += 1;
                IYK += 1;
                IOLDG += 1;
            }
            // C
            // C SET UP PARAMETERS USED IN UPDATING THE PRECONDITIONING STRATEGY.
            // C
            YKSK = this._ddot.Run(N, W, LYK.v + o_w, 1, W, LSK.v + o_w, 1);
            LRESET = false;
            if (ICYCLE == NM1 || DIFNEW < EPSRED * (FKEEP - FNEW)) LRESET = true;
            if (LRESET) goto LABEL80;
            YRSR = this._ddot.Run(N, W, LYR.v + o_w, 1, W, LSR.v + o_w, 1);
            if (YRSR <= ZERO) LRESET = true;
            LABEL80:;
            UPD1 = false;
            // C
            // C      COMPUTE THE NEW SEARCH DIRECTION
            // C
            LABEL90:
            if (UPD1 && MSGLVL >= 3) ;//ERROR-ERRORWRITE(*,830)
            if (NEWCON && MSGLVL >= 3) ;//ERROR-ERRORWRITE(*,840)
            MODET = MSGLVL - 3;
            this._modlnp.Run(MODET, ref W, LPK.v + o_w, ref W, LGV.v + o_w, ref W, LZ1.v + o_w, ref W, LV.v + o_w, ref W, LDIAGB.v + o_w
                             , ref W, LEMAT.v + o_w, X, offset_x, G, offset_g, ref W, LZK.v + o_w, N, ref W, offset_w
                             , LW, NITER, MAXIT, ref NFEVAL, NMODIF, ref NLINCG
                             , UPD1, YKSK, ref GSK, YRSR, LRESET, SFUN
                             , true, IPIVOT, offset_ipivot, ACCRCY, ref GTPNEW, GNORM, XNORM);
            if (NEWCON) goto LABEL20;
            if (LRESET) goto LABEL110;
            // C
            // C COMPUTE THE ACCUMULATED STEP AND ITS CORRESPONDING
            // C GRADIENT DIFFERENCE.
            // C
            this._dxpy.Run(N, W, LSK.v + o_w, 1, ref W, LSR.v + o_w, 1);
            this._dxpy.Run(N, W, LYK.v + o_w, 1, ref W, LYR.v + o_w, 1);
            ICYCLE += 1;
            goto LABEL20;
            // C
            // C RESET
            // C
            LABEL110:  IRESET += 1;
            // C
            // C INITIALIZE THE SUM OF ALL THE CHANGES IN X.
            // C
            this._dcopy.Run(N, W, LSK.v + o_w, 1, ref W, LSR.v + o_w, 1);
            this._dcopy.Run(N, W, LYK.v + o_w, 1, ref W, LYR.v + o_w, 1);
            FKEEP = FNEW;
            ICYCLE = 1;
            goto LABEL20;
            // C
            // C ...............END OF MAIN ITERATION.......................
            // C
            LABEL130:  IFAIL = 0;
            F = FNEW;
            return;
            LABEL140:  OLDF = FNEW;
            // C
            // C LOCAL SEARCH COULD BE INSTALLED HERE
            // C
            LABEL150:  F = OLDF;
            if (MSGLVL >= 1)
            {
                this._monit.Run(N, X, offset_x, F, G, offset_g, NITER, NFTOTL
                                , NFEVAL, IRESET, IPIVOT, offset_ipivot);
            }
            // C
            // C SET IFAIL
            // C
            LABEL160:  IFAIL = NWHY;
            return;
            #endregion
        }
Exemple #5
0
        public void Run(ref int IFAIL, int N, ref double[] X, int offset_x, ref double F, ref double[] G, int offset_g, ref double[] W, int offset_w
            , int LW, ISFUN SFUN, int MSGLVL, int MAXIT, int MAXFUN, double ETA
            , double STEPMX, double ACCRCY, double XTOL)
        {
            #region Variables

            int offset_ipivot = 0; int o_ipivot = -1; int I = 0; int ICYCLE = 0; int IOLDG = 0; int IPK = 0; int IYK = 0;
            int NFTOTL = 0;int NITER = 0; int NM1 = 0; int NUMF = 0; int NWHY = 0; double ABSTOL = 0; double ALPHA = 0;
            double DIFNEW = 0;double DIFOLD = 0; double EPSMCH = 0; double EPSRED = 0; double FKEEP = 0; double FM = 0;
            double FNEW = 0;double FOLD = 0; double FSTOP = 0; double FTEST = 0; double GNORM = 0; double GSK = 0; double GTG = 0;
            double GTPNEW = 0;double OLDF = 0; double OLDGTP = 0; double ONE = 0; double PE = 0; double PEPS = 0;
            double PNORM = 0;double RELTOL = 0; double RTEPS = 0; double RTLEPS = 0; double RTOL = 0; double RTOLSQ = 0;
            double SMALL = 0;double SPE = 0; double TINY = 0; double TNYTOL = 0; double TOLEPS = 0; double XNORM = 0;
            double YKSK = 0;double YRSR = 0; double ZERO = 0; bool LRESET = false; bool UPD1 = false; double DABS = 0;
            double DSQRT = 0;
            #endregion
            #region Implicit Variables

            int IRESET = 0; int NFEVAL = 0; int NMODIF = 0; int NLINCG = 0; int LHYR = 0; int IDIAGB = 0; int MODET = 0;
            int ISK = 0;
            #endregion
            #region Array Index Correction

             int o_x = -1 + offset_x;  int o_g = -1 + offset_g;  int o_w = -1 + offset_w;
            #endregion
            #region Prolog

            // C     ********Mi Modificacio EN LMQN*******
            // C
            // C     Se define IPIVOT(1) pues tal y como esta la subrutina pasa un valor sin especificar

            // C
            // C	********************

            // C
            // C THIS ROUTINE IS A TRUNCATED-NEWTON METHOD.
            // C THE TRUNCATED-NEWTON METHOD IS PRECONDITIONED BY A LIMITED-MEMORY
            // C QUASI-NEWTON METHOD (THIS PRECONDITIONING STRATEGY IS DEVELOPED
            // C IN THIS ROUTINE) WITH A FURTHER DIAGONAL SCALING (SEE ROUTINE NDIA3).
            // C FOR FURTHER DETAILS ON THE PARAMETERS, SEE ROUTINE TN.
            // C
            // C
            // C THE FOLLOWING IMSL AND STANDARD FUNCTIONS ARE USED
            // C
            // C
            // C INITIALIZE PARAMETERS AND CONSTANTS
            // C
            #endregion
            #region Body

            if (MSGLVL >=  - 2) ;//ERROR-ERRORWRITE(*,800)
            this._setpar.Run(N);
            UPD1 = true;
            IRESET = 0;
            NFEVAL = 0;
            NMODIF = 0;
            NLINCG = 0;
            FSTOP = F;
            ZERO = 0.0E0;
            ONE = 1.0E0;
            NM1 = N - 1;
            // C
            // C WITHIN THIS ROUTINE THE ARRAY W(LOLDG) IS SHARED BY W(LHYR)
            // C
            LHYR = LOLDG.v;
            // C
            // C CHECK PARAMETERS AND SET CONSTANTS
            // C
            this._chkucp.Run(LWTEST.v, MAXFUN, ref NWHY, N, ref ALPHA, ref EPSMCH
                             , ETA, ref PEPS, ref RTEPS, ref RTOL, ref RTOLSQ, STEPMX
                             , ref FTEST, XTOL, ref XNORM, X, offset_x, LW, ref SMALL
                             , ref TINY, ACCRCY);
            if (NWHY < 0) goto LABEL120;
            this._setucr.Run(SMALL, ref NFTOTL, ref NITER, N, F, ref FNEW
                             , ref FM, ref GTG, ref OLDF, SFUN, ref G, offset_g, X, offset_x);
            FOLD = FNEW;
            if (MSGLVL >= 1) ;//ERROR-ERRORWRITE(*,810)NITER,NFTOTL,NLINCG,FNEW,GTG
            // C
            // C CHECK FOR SMALL GRADIENT AT THE STARTING POINT.
            // C
            FTEST = ONE + Math.Abs(FNEW);
            if (GTG < 1.0E-4 * EPSMCH * FTEST * FTEST) goto LABEL90;
            // C
            // C SET INITIAL VALUES TO OTHER PARAMETERS
            // C
            ICYCLE = NM1;
            TOLEPS = RTOL + RTEPS;
            RTLEPS = RTOLSQ + EPSMCH;
            GNORM = Math.Sqrt(GTG);
            DIFNEW = ZERO;
            EPSRED = 5.0E-2;
            FKEEP = FNEW;
            // C
            // C SET THE DIAGONAL OF THE APPROXIMATE HESSIAN TO UNITY.
            // C
            IDIAGB = LDIAGB.v;
            for (I = 1; I <= N; I++)
            {
                W[IDIAGB + o_w] = ONE;
                IDIAGB += 1;
            }
            // C
            // C ..................START OF MAIN ITERATIVE LOOP..........
            // C
            // C COMPUTE THE NEW SEARCH DIRECTION
            // C
            MODET = MSGLVL - 3;
            this._modlnp.Run(MODET, ref W, LPK.v + o_w, ref W, LGV.v + o_w, ref W, LZ1.v + o_w, ref W, LV.v + o_w, ref W, LDIAGB.v + o_w
                             , ref W, LEMAT.v + o_w, X, offset_x, G, offset_g, ref W, LZK.v + o_w, N, ref W, offset_w
                             , LW, NITER, MAXIT, ref NFEVAL, NMODIF, ref NLINCG
                             , UPD1, YKSK, ref GSK, YRSR, LRESET, SFUN
                             , false, IPIVOT, offset_ipivot, ACCRCY, ref GTPNEW, GNORM, XNORM);
            LABEL20:;
            this._dcopy.Run(N, G, offset_g, 1, ref W, LOLDG.v + o_w, 1);
            PNORM = this._dnrm2.Run(N, W, LPK.v + o_w, 1);
            OLDF = FNEW;
            OLDGTP = GTPNEW;
            // C
            // C PREPARE TO COMPUTE THE STEP LENGTH
            // C
            PE = PNORM + EPSMCH;
            // C
            // C COMPUTE THE ABSOLUTE AND RELATIVE TOLERANCES FOR THE LINEAR SEARCH
            // C
            RELTOL = RTEPS * (XNORM + ONE) / PE;
            ABSTOL =  - EPSMCH * FTEST / (OLDGTP - EPSMCH);
            // C
            // C COMPUTE THE SMALLEST ALLOWABLE SPACING BETWEEN POINTS IN
            // C THE LINEAR SEARCH
            // C
            TNYTOL = EPSMCH * (XNORM + ONE) / PE;
            SPE = STEPMX / PE;
            // C
            // C SET THE INITIAL STEP LENGTH.
            // C
            ALPHA = this._step1.Run(FNEW, FM, OLDGTP, SPE);
            // C
            // C PERFORM THE LINEAR SEARCH
            // C
            this._linder.Run(N, SFUN, SMALL, EPSMCH, ref RELTOL, ref ABSTOL
                             , TNYTOL, ETA, ZERO, SPE, W, LPK.v + o_w, OLDGTP
                             , ref X, offset_x, ref FNEW, ref ALPHA, ref G, offset_g, ref NUMF, ref NWHY
                             , ref W, offset_w, LW);
            // C
            FOLD = FNEW;
            NITER += 1;
            NFTOTL += NUMF;
            GTG = this._ddot.Run(N, G, offset_g, 1, G, offset_g, 1);
            if (MSGLVL >= 1) ;//ERROR-ERRORWRITE(*,810)NITER,NFTOTL,NLINCG,FNEW,GTG
            if (NWHY < 0) goto LABEL120;
            if (NWHY == 0 || NWHY == 2) goto LABEL30;
            // C
            // C THE LINEAR SEARCH HAS FAILED TO FIND A LOWER POINT
            // C
            NWHY = 3;
            goto LABEL100;
            LABEL30:
            if (NWHY <= 1) goto LABEL40;
            SFUN.Run(N, X, offset_x, ref FNEW, ref G, offset_g);
            NFTOTL += 1;
            // C
            // C TERMINATE IF MORE THAN MAXFUN EVALUTATIONS HAVE BEEN MADE
            // C
            LABEL40:  NWHY = 2;

            // C     Se modificaron las siguentes lineas
            // C     ********Mi Modificacion EN LMQN y LMQNCB*******
            // C
            // C
            // C	Se cambio IF (NFTOTL .GT. MAXFUN)  por IF (NFTOTL + NFEVAL .GT. MAXFUN)
            // C
            // C	********************
            // C      IF (NFTOTL .GT. MAXFUN) GO TO 110

            if (NFTOTL + NFEVAL > MAXFUN) goto LABEL110;

            NWHY = 0;
            // C
            // C SET UP PARAMETERS USED IN CONVERGENCE AND RESETTING TESTS
            // C
            DIFOLD = DIFNEW;
            DIFNEW = OLDF - FNEW;
            // C
            // C IF THIS IS THE FIRST ITERATION OF A NEW CYCLE, COMPUTE THE
            // C PERCENTAGE REDUCTION FACTOR FOR THE RESETTING TEST.
            // C
            if (ICYCLE != 1) goto LABEL50;
            if (DIFNEW > 2.0E0 * DIFOLD) EPSRED += EPSRED;
            if (DIFNEW < 5.0E-1) EPSRED = 5.0E-1;
            LABEL50:;
            GNORM = Math.Sqrt(GTG);
            FTEST = ONE + Math.Abs(FNEW);
            XNORM = this._dnrm2.Run(N, X, offset_x, 1);
            // C
            // C TEST FOR CONVERGENCE
            // C
            if ((ALPHA * PNORM < TOLEPS * (ONE + XNORM) && Math.Abs(DIFNEW) < RTLEPS * FTEST && GTG < PEPS * FTEST * FTEST) || GTG < 1.0E-4 * ACCRCY * FTEST * FTEST) goto LABEL90;
            // C
            // C COMPUTE THE CHANGE IN THE ITERATES AND THE CORRESPONDING CHANGE
            // C IN THE GRADIENTS
            // C
            ISK = LSK.v;
            IPK = LPK.v;
            IYK = LYK.v;
            IOLDG = LOLDG.v;
            for (I = 1; I <= N; I++)
            {
                W[IYK + o_w] = G[I + o_g] - W[IOLDG + o_w];
                W[ISK + o_w] = ALPHA * W[IPK + o_w];
                IPK += 1;
                ISK += 1;
                IYK += 1;
                IOLDG += 1;
            }
            // C
            // C SET UP PARAMETERS USED IN UPDATING THE DIRECTION OF SEARCH.
            // C
            YKSK = this._ddot.Run(N, W, LYK.v + o_w, 1, W, LSK.v + o_w, 1);
            LRESET = false;
            if (ICYCLE == NM1 || DIFNEW < EPSRED * (FKEEP - FNEW)) LRESET = true;
            if (LRESET) goto LABEL70;
            YRSR = this._ddot.Run(N, W, LYR.v + o_w, 1, W, LSR.v + o_w, 1);
            if (YRSR <= ZERO) LRESET = true;
            LABEL70:;
            UPD1 = false;
            // C
            // C      COMPUTE THE NEW SEARCH DIRECTION
            // C
            MODET = MSGLVL - 3;
            this._modlnp.Run(MODET, ref W, LPK.v + o_w, ref W, LGV.v + o_w, ref W, LZ1.v + o_w, ref W, LV.v + o_w, ref W, LDIAGB.v + o_w
                             , ref W, LEMAT.v + o_w, X, offset_x, G, offset_g, ref W, LZK.v + o_w, N, ref W, offset_w
                             , LW, NITER, MAXIT, ref NFEVAL, NMODIF, ref NLINCG
                             , UPD1, YKSK, ref GSK, YRSR, LRESET, SFUN
                             , false, IPIVOT, offset_ipivot, ACCRCY, ref GTPNEW, GNORM, XNORM);
            if (LRESET) goto LABEL80;
            // C
            // C      STORE THE ACCUMULATED CHANGE IN THE POINT AND GRADIENT AS AN
            // C      "AVERAGE" DIRECTION FOR PRECONDITIONING.
            // C
            this._dxpy.Run(N, W, LSK.v + o_w, 1, ref W, LSR.v + o_w, 1);
            this._dxpy.Run(N, W, LYK.v + o_w, 1, ref W, LYR.v + o_w, 1);
            ICYCLE += 1;
            goto LABEL20;
            // C
            // C RESET
            // C
            LABEL80:  IRESET += 1;
            // C
            // C INITIALIZE THE SUM OF ALL THE CHANGES IN X.
            // C
            this._dcopy.Run(N, W, LSK.v + o_w, 1, ref W, LSR.v + o_w, 1);
            this._dcopy.Run(N, W, LYK.v + o_w, 1, ref W, LYR.v + o_w, 1);
            FKEEP = FNEW;
            ICYCLE = 1;
            goto LABEL20;
            // C
            // C ...............END OF MAIN ITERATION.......................
            // C
            LABEL90:  IFAIL = 0;
            F = FNEW;
            return;
            LABEL100:  OLDF = FNEW;
            // C
            // C LOCAL SEARCH HERE COULD BE INSTALLED HERE
            // C
            LABEL110:  F = OLDF;
            // C
            // C SET IFAIL
            // C
            LABEL120:  IFAIL = NWHY;
            return;
            #endregion
        }
Exemple #6
0
        public void Run(int N, ISFUN SFUN, double SMALL, double EPSMCH, ref double RELTOL, ref double ABSTOL
            , double TNYTOL, double ETA, double SFTBND, double XBND, double[] P, int offset_p, double GTP
            , ref double[] X, int offset_x, ref double F, ref double ALPHA, ref double[] G, int offset_g, ref int NFTOTL, ref int IFLAG
            , ref double[] W, int offset_w, int LW)
        {
            #region Variables

            int I = 0; int IENTRY = 0; int ITEST = 0; int L = 0; int LG = 0; int LX = 0; int NUMF = 0; int ITCNT = 0;
            double A = 0;double B = 0; double B1 = 0; double BIG = 0; double E = 0; double FACTOR = 0; double FMIN = 0;
            double FPRESN = 0;double FU = 0; double FW = 0; double GMIN = 0; double GTEST1 = 0; double GTEST2 = 0; double GU = 0;
            double GW = 0;double OLDF = 0; double SCXBND = 0; double STEP = 0; double TOL = 0; double U = 0; double XMIN = 0;
            double XW = 0;double RMU = 0; double RTSMLL = 0; double UALPHA = 0; bool BRAKTD = false; double DSQRT = 0;
            #endregion
            #region Implicit Variables

            int LSPRNT = 0; int NPRNT = 0;
            #endregion
            #region Array Index Correction

             int o_p = -1 + offset_p;  int o_x = -1 + offset_x;  int o_g = -1 + offset_g;  int o_w = -1 + offset_w;
            #endregion
            // C
            // C
            // C
            // C      THE FOLLOWING STANDARD FUNCTIONS AND SYSTEM FUNCTIONS ARE
            // C      CALLED WITHIN LINDER
            // C
            // C
            // C      ALLOCATE THE ADDRESSES FOR LOCAL WORKSPACE
            // C
            #region Body

            LX = 1;
            LG = LX + N;
            LSPRNT = 0;
            NPRNT = 10000;
            RTSMLL = Math.Sqrt(SMALL);
            BIG = 1.0E0 / SMALL;
            ITCNT = 0;
            // C
            // C      SET THE ESTIMATED RELATIVE PRECISION IN F(X).
            // C
            FPRESN = 10.0E0 * EPSMCH;
            NUMF = 0;
            U = ALPHA;
            FU = F;
            FMIN = F;
            GU = GTP;
            RMU = 1.0E-4;
            // C
            // C      FIRST ENTRY SETS UP THE INITIAL INTERVAL OF UNCERTAINTY.
            // C
            IENTRY = 1;
            LABEL10:;
            // C
            // C TEST FOR TOO MANY ITERATIONS
            // C
            ITCNT += 1;
            IFLAG = 1;
            if (ITCNT > 20) goto LABEL50;
            IFLAG = 0;
            this._getptc.Run(BIG, SMALL, RTSMLL, ref RELTOL, ref ABSTOL, TNYTOL
                             , FPRESN, ETA, RMU, XBND, ref U, ref FU
                             , ref GU, ref XMIN, ref FMIN, ref GMIN, ref XW, ref FW
                             , ref GW, ref A, ref B, ref OLDF, ref B1, ref SCXBND
                             , ref E, ref STEP, ref FACTOR, ref BRAKTD, ref GTEST1, ref GTEST2
                             , ref TOL, ref IENTRY, ref ITEST);
            // CLSOUT
            if (LSPRNT >= NPRNT)
            {
                this._lsout.Run(IENTRY, ITEST, XMIN, FMIN, GMIN, XW
                                , FW, GW, U, A, B, TOL
                                , RELTOL, SCXBND, XBND);
            }
            // C
            // C      IF ITEST=1, THE ALGORITHM REQUIRES THE FUNCTION VALUE TO BE
            // C      CALCULATED.
            // C
            if (ITEST != 1) goto LABEL30;
            UALPHA = XMIN + U;
            L = LX;
            for (I = 1; I <= N; I++)
            {
                W[L + o_w] = X[I + o_x] + UALPHA * P[I + o_p];
                L += 1;
            }
            SFUN.Run(N, W, LX + o_w, ref FU, ref W, LG + o_w);
            NUMF += 1;
            GU = this._ddot.Run(N, W, LG + o_w, 1, P, offset_p, 1);
            // C
            // C      THE GRADIENT VECTOR CORRESPONDING TO THE BEST POINT IS
            // C      OVERWRITTEN IF FU IS LESS THAN FMIN AND FU IS SUFFICIENTLY
            // C      LOWER THAN F AT THE ORIGIN.
            // C
            if (FU <= FMIN && FU <= OLDF - UALPHA * GTEST1) this._dcopy.Run(N, W, LG + o_w, 1, ref G, offset_g, 1);
            goto LABEL10;
            // C
            // C      IF ITEST=2 OR 3 A LOWER POINT COULD NOT BE FOUND
            // C
            LABEL30:;
            NFTOTL = NUMF;
            IFLAG = 1;
            if (ITEST != 0) goto LABEL50;
            // C
            // C      IF ITEST=0 A SUCCESSFUL SEARCH HAS BEEN MADE
            // C
            IFLAG = 0;
            F = FMIN;
            ALPHA = XMIN;
            for (I = 1; I <= N; I++)
            {
                X[I + o_x] += ALPHA * P[I + o_p];
            }
            LABEL50:  return;
            #endregion
        }
Exemple #7
0
        /// <param name="V">
        /// AND STORES THE RESULT IN THE VECTOR GV (FINITE-DIFFERENCE VERSION)
        ///</param>
        public void Run(double[] V, int offset_v, ref double[] GV, int offset_gv, int N, double[] X, int offset_x, double[] G, int offset_g, ref double[] W, int offset_w
            , int LW, ISFUN SFUN, ref bool FIRST, ref double DELTA, double ACCRCY, double XNORM)
        {
            #region Variables

            double DINV = 0; double F = 0; double DSQRT = 0;
            #endregion
            #region Implicit Variables

            int IHG = 0; int I = 0;
            #endregion
            #region Array Index Correction

             int o_v = -1 + offset_v;  int o_gv = -1 + offset_gv;  int o_x = -1 + offset_x;  int o_g = -1 + offset_g;
             int o_w = -1 + offset_w;
            #endregion
            // C
            // C THIS ROUTINE COMPUTES THE PRODUCT OF THE MATRIX G TIMES THE VECTOR
            // C V AND STORES THE RESULT IN THE VECTOR GV (FINITE-DIFFERENCE VERSION)
            // C
            if (!FIRST) goto LABEL20;
            DELTA = Math.Sqrt(ACCRCY) * (1.0E0 + XNORM);
            FIRST = false;
            LABEL20:;
            DINV = 1.0E0 / DELTA;
            IHG = LHG.v;
            for (I = 1; I <= N; I++)
            {
                W[IHG + o_w] = X[I + o_x] + DELTA * V[I + o_v];
                IHG += 1;
            }
            SFUN.Run(N, W, LHG.v + o_w, ref F, ref GV, offset_gv);
            for (I = 1; I <= N; I++)
            {
                GV[I + o_gv] = (GV[I + o_gv] - G[I + o_g]) * DINV;
            }
            return;
        }