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; }
/// <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 }
/// <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 }
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 }
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 }
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 }
/// <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; }