# To unbundle, sh this file echo Readme 1>&2 sed 's/.//' >Readme <<'EOF Readme' - - This directory contains the - limited memory code for solving - large unconstrained optimization - problems. - - sdrive.f - is a simple driver - lbfgs.f - contains all the supporting - routines - makefile - a makefile for Unix users - - This directory also contains the paper - liu-nocedal.ps which describes - the limited memory algorithm. - EOF Readme echo makefile 1>&2 sed 's/.//' >makefile <<'EOF makefile' -fname = sdrive.o lbfgs.o - -main : $(fname) - f77 $(fname) $(extras) -o sdrive - -.f.o :; f77 -c $*.f - EOF makefile echo sdrive.f 1>&2 sed 's/.//' >sdrive.f <<'EOF sdrive.f' -C -C *********************** -C SIMPLE DRIVER FOR LBFGS -C *********************** -C -C Example of driver for LBFGS routine, using a -C simple test problem. The solution point is at -C X=(1,...,1) and the optimal function value of 0. -C -C JORGE NOCEDAL -C *** July 1990 *** -C - PROGRAM SDRIVE - PARAMETER(NDIM=2000,MSAVE=7,NWORK=NDIM*(2*MSAVE +1)+2*MSAVE) - DOUBLE PRECISION X(NDIM),G(NDIM),DIAG(NDIM),W(NWORK) - DOUBLE PRECISION F,EPS,XTOL,GTOL,T1,T2,STPMIN,STPMAX - INTEGER IPRINT(2),IFLAG,ICALL,N,M,MP,LP,J - LOGICAL DIAGCO -C -C The driver for LBFGS must always declare LB2 as EXTERNAL -C - EXTERNAL LB2 - COMMON /LB3/MP,LP,GTOL,STPMIN,STPMAX -C - N=100 - M=5 - IPRINT(1)= 1 - IPRINT(2)= 0 -C -C We do not wish to provide the diagonal matrices Hk0, and -C therefore set DIAGCO to FALSE. -C - DIAGCO= .FALSE. - EPS= 1.0D-5 - XTOL= 1.0D-16 - ICALL=0 - IFLAG=0 - DO 10 J=1,N,2 - X(J)=-1.2D0 - X(J+1)=1.D0 - 10 CONTINUE -C - 20 CONTINUE - F= 0.D0 - DO 30 J=1,N,2 - T1= 1.D0-X(J) - T2= 1.D1*(X(J+1)-X(J)**2) - G(J+1)= 2.D1*T2 - G(J)= -2.D0*(X(J)*G(J+1)+T1) - F= F+T1**2+T2**2 - 30 CONTINUE - CALL LBFGS(N,M,X,F,G,DIAGCO,DIAG,IPRINT,EPS,XTOL,W,IFLAG) - IF(IFLAG.LE.0) GO TO 50 - ICALL=ICALL + 1 -C We allow at most 2000 evaluations of F and G - IF(ICALL.GT.2000) GO TO 50 - GO TO 20 - 50 CONTINUE - END -C -C ** LAST LINE OF SIMPLE DRIVER (SDRIVE) ** - EOF sdrive.f echo lbfgs.f 1>&2 sed 's/.//' >lbfgs.f <<'EOF lbfgs.f' -C ---------------------------------------------------------------------- -C This file contains the LBFGS algorithm and supporting routines -C -C **************** -C LBFGS SUBROUTINE -C **************** -C - SUBROUTINE LBFGS(N,M,X,F,G,DIAGCO,DIAG,IPRINT,EPS,XTOL,W,IFLAG) -C - INTEGER N,M,IPRINT(2),IFLAG - DOUBLE PRECISION X(N),G(N),DIAG(N),W(N*(2*M+1)+2*M) - DOUBLE PRECISION F,EPS,XTOL - LOGICAL DIAGCO -C -C LIMITED MEMORY BFGS METHOD FOR LARGE SCALE OPTIMIZATION -C JORGE NOCEDAL -C *** July 1990 *** -C -C -C This subroutine solves the unconstrained minimization problem -C -C min F(x), x= (x1,x2,...,xN), -C -C using the limited memory BFGS method. The routine is especially -C effective on problems involving a large number of variables. In -C a typical iteration of this method an approximation Hk to the -C inverse of the Hessian is obtained by applying M BFGS updates to -C a diagonal matrix Hk0, using information from the previous M steps. -C The user specifies the number M, which determines the amount of -C storage required by the routine. The user may also provide the -C diagonal matrices Hk0 if not satisfied with the default choice. -C The algorithm is described in "On the limited memory BFGS method -C for large scale optimization", by D. Liu and J. Nocedal, -C Mathematical Programming B 45 (1989) 503-528. -C -C The user is required to calculate the function value F and its -C gradient G. In order to allow the user complete control over -C these computations, reverse communication is used. The routine -C must be called repeatedly under the control of the parameter -C IFLAG. -C -C The steplength is determined at each iteration by means of the -C line search routine MCVSRCH, which is a slight modification of -C the routine CSRCH written by More' and Thuente. -C -C The calling statement is -C -C CALL LBFGS(N,M,X,F,G,DIAGCO,DIAG,IPRINT,EPS,XTOL,W,IFLAG) -C -C where -C -C N is an INTEGER variable that must be set by the user to the -C number of variables. It is not altered by the routine. -C Restriction: N>0. -C -C M is an INTEGER variable that must be set by the user to -C the number of corrections used in the BFGS update. It -C is not altered by the routine. Values of M less than 3 are -C not recommended; large values of M will result in excessive -C computing time. 3<= M <=7 is recommended. Restriction: M>0. -C -C X is a DOUBLE PRECISION array of length N. On initial entry -C it must be set by the user to the values of the initial -C estimate of the solution vector. On exit with IFLAG=0, it -C contains the values of the variables at the best point -C found (usually a solution). -C -C F is a DOUBLE PRECISION variable. Before initial entry and on -C a re-entry with IFLAG=1, it must be set by the user to -C contain the value of the function F at the point X. -C -C G is a DOUBLE PRECISION array of length N. Before initial -C entry and on a re-entry with IFLAG=1, it must be set by -C the user to contain the components of the gradient G at -C the point X. -C -C DIAGCO is a LOGICAL variable that must be set to .TRUE. if the -C user wishes to provide the diagonal matrix Hk0 at each -C iteration. Otherwise it should be set to .FALSE., in which -C case LBFGS will use a default value described below. If -C DIAGCO is set to .TRUE. the routine will return at each -C iteration of the algorithm with IFLAG=2, and the diagonal -C matrix Hk0 must be provided in the array DIAG. -C -C -C DIAG is a DOUBLE PRECISION array of length N. If DIAGCO=.TRUE., -C then on initial entry or on re-entry with IFLAG=2, DIAG -C it must be set by the user to contain the values of the -C diagonal matrix Hk0. Restriction: all elements of DIAG -C must be positive. -C -C IPRINT is an INTEGER array of length two which must be set by the -C user. -C -C IPRINT(1) specifies the frequency of the output: -C IPRINT(1) < 0 : no output is generated, -C IPRINT(1) = 0 : output only at first and last iteration, -C IPRINT(1) > 0 : output every IPRINT(1) iterations. -C -C IPRINT(2) specifies the type of output generated: -C IPRINT(2) = 0 : iteration count, number of function -C evaluations, function value, norm of the -C gradient, and steplength, -C IPRINT(2) = 1 : same as IPRINT(2)=0, plus vector of -C variables and gradient vector at the -C initial point, -C IPRINT(2) = 2 : same as IPRINT(2)=1, plus vector of -C variables, -C IPRINT(2) = 3 : same as IPRINT(2)=2, plus gradient vector. -C -C -C EPS is a positive DOUBLE PRECISION variable that must be set by -C the user, and determines the accuracy with which the solution -C is to be found. The subroutine terminates when -C -C ||G|| < EPS max(1,||X||), -C -C where ||.|| denotes the Euclidean norm. -C -C XTOL is a positive DOUBLE PRECISION variable that must be set by -C the user to an estimate of the machine precision (e.g. -C 10**(-16) on a SUN station 3/60). The line search routine will -C terminate if the relative width of the interval of uncertainty -C is less than XTOL. -C -C W is a DOUBLE PRECISION array of length N(2M+1)+2M used as -C workspace for LBFGS. This array must not be altered by the -C user. -C -C IFLAG is an INTEGER variable that must be set to 0 on initial entry -C to the subroutine. A return with IFLAG<0 indicates an error, -C and IFLAG=0 indicates that the routine has terminated without -C detecting errors. On a return with IFLAG=1, the user must -C evaluate the function F and gradient G. On a return with -C IFLAG=2, the user must provide the diagonal matrix Hk0. -C -C The following negative values of IFLAG, detecting an error, -C are possible: -C -C IFLAG=-1 The line search routine MCSRCH failed. The -C parameter INFO provides more detailed information -C (see also the documentation of MCSRCH): -C -C INFO = 0 IMPROPER INPUT PARAMETERS. -C -C INFO = 2 RELATIVE WIDTH OF THE INTERVAL OF -C UNCERTAINTY IS AT MOST XTOL. -C -C INFO = 3 MORE THAN 20 FUNCTION EVALUATIONS WERE -C REQUIRED AT THE PRESENT ITERATION. -C -C INFO = 4 THE STEP IS TOO SMALL. -C -C INFO = 5 THE STEP IS TOO LARGE. -C -C INFO = 6 ROUNDING ERRORS PREVENT FURTHER PROGRESS. -C THERE MAY NOT BE A STEP WHICH SATISFIES -C THE SUFFICIENT DECREASE AND CURVATURE -C CONDITIONS. TOLERANCES MAY BE TOO SMALL. -C -C -C IFLAG=-2 The i-th diagonal element of the diagonal inverse -C Hessian approximation, given in DIAG, is not -C positive. -C -C IFLAG=-3 Improper input parameters for LBFGS (N or M are -C not positive). -C -C -C -C ON THE DRIVER: -C -C The program that calls LBFGS must contain the declaration: -C -C EXTERNAL LB2 -C -C LB2 is a BLOCK DATA that defines the default values of several -C parameters described in the COMMON section. -C -C -C -C COMMON: -C -C The subroutine contains one common area, which the user may wish to -C reference: -C - COMMON /LB3/MP,LP,GTOL,STPMIN,STPMAX -C -C MP is an INTEGER variable with default value 6. It is used as the -C unit number for the printing of the monitoring information -C controlled by IPRINT. -C -C LP is an INTEGER variable with default value 6. It is used as the -C unit number for the printing of error messages. This printing -C may be suppressed by setting LP to a non-positive value. -C -C GTOL is a DOUBLE PRECISION variable with default value 0.9, which -C controls the accuracy of the line search routine MCSRCH. If the -C function and gradient evaluations are inexpensive with respect -C to the cost of the iteration (which is sometimes the case when -C solving very large problems) it may be advantageous to set GTOL -C to a small value. A typical small value is 0.1. Restriction: -C GTOL should be greater than 1.D-04. -C -C STPMIN and STPMAX are non-negative DOUBLE PRECISION variables which -C specify lower and uper bounds for the step in the line search. -C Their default values are 1.D-20 and 1.D+20, respectively. These -C values need not be modified unless the exponents are too large -C for the machine being used, or unless the problem is extremely -C badly scaled (in which case the exponents should be increased). -C -C -C MACHINE DEPENDENCIES -C -C The only variables that are machine-dependent are XTOL, -C STPMIN and STPMAX. -C -C -C GENERAL INFORMATION -C -C Other routines called directly: DAXPY, DDOT, LB1, MCSRCH -C -C Input/Output : No input; diagnostic messages on unit MP and -C error messages on unit LP. -C -C -C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -C - DOUBLE PRECISION GTOL,ONE,ZERO,GNORM,DDOT,STP1,FTOL,STPMIN, - . STPMAX,STP,YS,YY,SQ,YR,BETA,XNORM - INTEGER MP,LP,ITER,NFUN,POINT,ISPT,IYPT,MAXFEV,INFO, - . BOUND,NPT,CP,I,NFEV,INMC,IYCN,ISCN - LOGICAL FINISH -C - SAVE - DATA ONE,ZERO/1.0D+0,0.0D+0/ -C -C INITIALIZE -C ---------- -C - IF(IFLAG.EQ.0) GO TO 10 - GO TO (172,100) IFLAG - 10 ITER= 0 - IF(N.LE.0.OR.M.LE.0) GO TO 196 - IF(GTOL.LE.1.D-04) THEN - IF(LP.GT.0) WRITE(LP,245) - GTOL=9.D-01 - ENDIF - NFUN= 1 - POINT= 0 - FINISH= .FALSE. - IF(DIAGCO) THEN - DO 30 I=1,N - 30 IF (DIAG(I).LE.ZERO) GO TO 195 - ELSE - DO 40 I=1,N - 40 DIAG(I)= 1.0D0 - ENDIF -C -C THE WORK VECTOR W IS DIVIDED AS FOLLOWS: -C --------------------------------------- -C THE FIRST N LOCATIONS ARE USED TO STORE THE GRADIENT AND -C OTHER TEMPORARY INFORMATION. -C LOCATIONS (N+1)...(N+M) STORE THE SCALARS RHO. -C LOCATIONS (N+M+1)...(N+2M) STORE THE NUMBERS ALPHA USED -C IN THE FORMULA THAT COMPUTES H*G. -C LOCATIONS (N+2M+1)...(N+2M+NM) STORE THE LAST M SEARCH -C STEPS. -C LOCATIONS (N+2M+NM+1)...(N+2M+2NM) STORE THE LAST M -C GRADIENT DIFFERENCES. -C -C THE SEARCH STEPS AND GRADIENT DIFFERENCES ARE STORED IN A -C CIRCULAR ORDER CONTROLLED BY THE PARAMETER POINT. -C - ISPT= N+2*M - IYPT= ISPT+N*M - DO 50 I=1,N - 50 W(ISPT+I)= -G(I)*DIAG(I) - GNORM= DSQRT(DDOT(N,G,1,G,1)) - STP1= ONE/GNORM -C -C PARAMETERS FOR LINE SEARCH ROUTINE -C - FTOL= 1.0D-4 - MAXFEV= 20 -C - IF(IPRINT(1).GE.0) CALL LB1(IPRINT,ITER,NFUN, - * GNORM,N,M,X,F,G,STP,FINISH) -C -C -------------------- -C MAIN ITERATION LOOP -C -------------------- -C - 80 ITER= ITER+1 - INFO=0 - BOUND=ITER-1 - IF(ITER.EQ.1) GO TO 165 - IF (ITER .GT. M)BOUND=M -C - YS= DDOT(N,W(IYPT+NPT+1),1,W(ISPT+NPT+1),1) - IF(.NOT.DIAGCO) THEN - YY= DDOT(N,W(IYPT+NPT+1),1,W(IYPT+NPT+1),1) - DO 90 I=1,N - 90 DIAG(I)= YS/YY - ELSE - IFLAG=2 - RETURN - ENDIF - 100 CONTINUE - IF(DIAGCO) THEN - DO 110 I=1,N - 110 IF (DIAG(I).LE.ZERO) GO TO 195 - ENDIF -C -C COMPUTE -H*G USING THE FORMULA GIVEN IN: Nocedal, J. 1980, -C "Updating quasi-Newton matrices with limited storage", -C Mathematics of Computation, Vol.24, No.151, pp. 773-782. -C --------------------------------------------------------- -C - CP= POINT - IF (POINT.EQ.0) CP=M - W(N+CP)= ONE/YS - DO 112 I=1,N - 112 W(I)= -G(I) - CP= POINT - DO 125 I= 1,BOUND - CP=CP-1 - IF (CP.EQ. -1)CP=M-1 - SQ= DDOT(N,W(ISPT+CP*N+1),1,W,1) - INMC=N+M+CP+1 - IYCN=IYPT+CP*N - W(INMC)= W(N+CP+1)*SQ - CALL DAXPY(N,-W(INMC),W(IYCN+1),1,W,1) - 125 CONTINUE -C - DO 130 I=1,N - 130 W(I)=DIAG(I)*W(I) -C - DO 145 I=1,BOUND - YR= DDOT(N,W(IYPT+CP*N+1),1,W,1) - BETA= W(N+CP+1)*YR - INMC=N+M+CP+1 - BETA= W(INMC)-BETA - ISCN=ISPT+CP*N - CALL DAXPY(N,BETA,W(ISCN+1),1,W,1) - CP=CP+1 - IF (CP.EQ.M)CP=0 - 145 CONTINUE -C -C STORE THE NEW SEARCH DIRECTION -C ------------------------------ -C - DO 160 I=1,N - 160 W(ISPT+POINT*N+I)= W(I) -C -C OBTAIN THE ONE-DIMENSIONAL MINIMIZER OF THE FUNCTION -C BY USING THE LINE SEARCH ROUTINE MCSRCH -C ---------------------------------------------------- - 165 NFEV=0 - STP=ONE - IF (ITER.EQ.1) STP=STP1 - DO 170 I=1,N - 170 W(I)=G(I) - 172 CONTINUE - CALL MCSRCH(N,X,F,G,W(ISPT+POINT*N+1),STP,FTOL, - * XTOL,MAXFEV,INFO,NFEV,DIAG) - IF (INFO .EQ. -1) THEN - IFLAG=1 - RETURN - ENDIF - IF (INFO .NE. 1) GO TO 190 - NFUN= NFUN + NFEV -C -C COMPUTE THE NEW STEP AND GRADIENT CHANGE -C ----------------------------------------- -C - NPT=POINT*N - DO 175 I=1,N - W(ISPT+NPT+I)= STP*W(ISPT+NPT+I) - 175 W(IYPT+NPT+I)= G(I)-W(I) - POINT=POINT+1 - IF (POINT.EQ.M)POINT=0 -C -C TERMINATION TEST -C ---------------- -C - GNORM= DSQRT(DDOT(N,G,1,G,1)) - XNORM= DSQRT(DDOT(N,X,1,X,1)) - XNORM= DMAX1(1.0D0,XNORM) - IF (GNORM/XNORM .LE. EPS) FINISH=.TRUE. -C - IF(IPRINT(1).GE.0) CALL LB1(IPRINT,ITER,NFUN, - * GNORM,N,M,X,F,G,STP,FINISH) - IF (FINISH) THEN - IFLAG=0 - RETURN - ENDIF - GO TO 80 -C -C ------------------------------------------------------------ -C END OF MAIN ITERATION LOOP. ERROR EXITS. -C ------------------------------------------------------------ -C - 190 IFLAG=-1 - IF(LP.GT.0) WRITE(LP,200) INFO - RETURN - 195 IFLAG=-2 - IF(LP.GT.0) WRITE(LP,235) I - RETURN - 196 IFLAG= -3 - IF(LP.GT.0) WRITE(LP,240) -C -C FORMATS -C ------- -C - 200 FORMAT(/' IFLAG= -1 ',/' LINE SEARCH FAILED. SEE' - . ' DOCUMENTATION OF ROUTINE MCSRCH',/' ERROR RETURN' - . ' OF LINE SEARCH: INFO= ',I2,/ - . ' POSSIBLE CAUSES: FUNCTION OR GRADIENT ARE INCORRECT',/, - . ' OR INCORRECT TOLERANCES') - 235 FORMAT(/' IFLAG= -2',/' THE',I5,'-TH DIAGONAL ELEMENT OF THE',/, - . ' INVERSE HESSIAN APPROXIMATION IS NOT POSITIVE') - 240 FORMAT(/' IFLAG= -3',/' IMPROPER INPUT PARAMETERS (N OR M', - . ' ARE NOT POSITIVE)') - 245 FORMAT(/' GTOL IS LESS THAN OR EQUAL TO 1.D-04', - . / ' IT HAS BEEN RESET TO 9.D-01') - RETURN - END -C -C LAST LINE OF SUBROUTINE LBFGS -C -C - SUBROUTINE LB1(IPRINT,ITER,NFUN, - * GNORM,N,M,X,F,G,STP,FINISH) -C -C ------------------------------------------------------------- -C THIS ROUTINE PRINTS MONITORING INFORMATION. THE FREQUENCY AND -C AMOUNT OF OUTPUT ARE CONTROLLED BY IPRINT. -C ------------------------------------------------------------- -C - INTEGER IPRINT(2),ITER,NFUN,LP,MP,N,M - DOUBLE PRECISION X(N),G(N),F,GNORM,STP,GTOL,STPMIN,STPMAX - LOGICAL FINISH - COMMON /LB3/MP,LP,GTOL,STPMIN,STPMAX -C - IF (ITER.EQ.0)THEN - WRITE(MP,10) - WRITE(MP,20) N,M - WRITE(MP,30)F,GNORM - IF (IPRINT(2).GE.1)THEN - WRITE(MP,40) - WRITE(MP,50) (X(I),I=1,N) - WRITE(MP,60) - WRITE(MP,50) (G(I),I=1,N) - ENDIF - WRITE(MP,10) - WRITE(MP,70) - ELSE - IF ((IPRINT(1).EQ.0).AND.(ITER.NE.1.AND..NOT.FINISH))RETURN - IF (IPRINT(1).NE.0)THEN - IF(MOD(ITER-1,IPRINT(1)).EQ.0.OR.FINISH)THEN - IF(IPRINT(2).GT.1.AND.ITER.GT.1) WRITE(MP,70) - WRITE(MP,80)ITER,NFUN,F,GNORM,STP - ELSE - RETURN - ENDIF - ELSE - IF( IPRINT(2).GT.1.AND.FINISH) WRITE(MP,70) - WRITE(MP,80)ITER,NFUN,F,GNORM,STP - ENDIF - IF (IPRINT(2).EQ.2.OR.IPRINT(2).EQ.3)THEN - IF (FINISH)THEN - WRITE(MP,90) - ELSE - WRITE(MP,40) - ENDIF - WRITE(MP,50)(X(I),I=1,N) - IF (IPRINT(2).EQ.3)THEN - WRITE(MP,60) - WRITE(MP,50)(G(I),I=1,N) - ENDIF - ENDIF - IF (FINISH) WRITE(MP,100) - ENDIF -C - 10 FORMAT('*************************************************') - 20 FORMAT(' N=',I5,' NUMBER OF CORRECTIONS=',I2, - . /, ' INITIAL VALUES') - 30 FORMAT(' F= ',1PD10.3,' GNORM= ',1PD10.3) - 40 FORMAT(' VECTOR X= ') - 50 FORMAT(6(2X,1PD10.3)) - 60 FORMAT(' GRADIENT VECTOR G= ') - 70 FORMAT(/' I NFN',4X,'FUNC',8X,'GNORM',7X,'STEPLENGTH'/) - 80 FORMAT(2(I4,1X),3X,3(1PD10.3,2X)) - 90 FORMAT(' FINAL POINT X= ') - 100 FORMAT(/' THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.', - . /' IFLAG = 0') -C - RETURN - END -C ****** -C -C -C ---------------------------------------------------------- -C DATA -C ---------------------------------------------------------- -C - BLOCK DATA LB2 - INTEGER LP,MP - DOUBLE PRECISION GTOL,STPMIN,STPMAX - COMMON /LB3/MP,LP,GTOL,STPMIN,STPMAX - DATA MP,LP,GTOL,STPMIN,STPMAX/6,6,9.0D-01,1.0D-20,1.0D+20/ - END -C -C -C ---------------------------------------------------------- -C - subroutine daxpy(n,da,dx,incx,dy,incy) -c -c constant times a vector plus a vector. -c uses unrolled loops for increments equal to one. -c jack dongarra, linpack, 3/11/78. -c - double precision dx(1),dy(1),da - integer i,incx,incy,ix,iy,m,mp1,n -c - if(n.le.0)return - if (da .eq. 0.0d0) return - if(incx.eq.1.and.incy.eq.1)go to 20 -c -c code for unequal increments or equal increments -c not equal to 1 -c - ix = 1 - iy = 1 - if(incx.lt.0)ix = (-n+1)*incx + 1 - if(incy.lt.0)iy = (-n+1)*incy + 1 - do 10 i = 1,n - dy(iy) = dy(iy) + da*dx(ix) - ix = ix + incx - iy = iy + incy - 10 continue - return -c -c code for both increments equal to 1 -c -c -c clean-up loop -c - 20 m = mod(n,4) - if( m .eq. 0 ) go to 40 - do 30 i = 1,m - dy(i) = dy(i) + da*dx(i) - 30 continue - if( n .lt. 4 ) return - 40 mp1 = m + 1 - do 50 i = mp1,n,4 - dy(i) = dy(i) + da*dx(i) - dy(i + 1) = dy(i + 1) + da*dx(i + 1) - dy(i + 2) = dy(i + 2) + da*dx(i + 2) - dy(i + 3) = dy(i + 3) + da*dx(i + 3) - 50 continue - return - end -C -C -C ---------------------------------------------------------- -C - double precision function ddot(n,dx,incx,dy,incy) -c -c forms the dot product of two vectors. -c uses unrolled loops for increments equal to one. -c jack dongarra, linpack, 3/11/78. -c - double precision dx(1),dy(1),dtemp - integer i,incx,incy,ix,iy,m,mp1,n -c - ddot = 0.0d0 - dtemp = 0.0d0 - if(n.le.0)return - if(incx.eq.1.and.incy.eq.1)go to 20 -c -c code for unequal increments or equal increments -c not equal to 1 -c - ix = 1 - iy = 1 - if(incx.lt.0)ix = (-n+1)*incx + 1 - if(incy.lt.0)iy = (-n+1)*incy + 1 - do 10 i = 1,n - dtemp = dtemp + dx(ix)*dy(iy) - ix = ix + incx - iy = iy + incy - 10 continue - ddot = dtemp - return -c -c code for both increments equal to 1 -c -c -c clean-up loop -c - 20 m = mod(n,5) - if( m .eq. 0 ) go to 40 - do 30 i = 1,m - dtemp = dtemp + dx(i)*dy(i) - 30 continue - if( n .lt. 5 ) go to 60 - 40 mp1 = m + 1 - do 50 i = mp1,n,5 - dtemp = dtemp + dx(i)*dy(i) + dx(i + 1)*dy(i + 1) + - * dx(i + 2)*dy(i + 2) + dx(i + 3)*dy(i + 3) + dx(i + 4)*dy(i + 4) - 50 continue - 60 ddot = dtemp - return - end -C ------------------------------------------------------------------ -C -C ************************** -C LINE SEARCH ROUTINE MCSRCH -C ************************** -C - SUBROUTINE MCSRCH(N,X,F,G,S,STP,FTOL,XTOL,MAXFEV,INFO,NFEV,WA) - INTEGER N,MAXFEV,INFO,NFEV - DOUBLE PRECISION F,STP,FTOL,GTOL,XTOL,STPMIN,STPMAX - DOUBLE PRECISION X(N),G(N),S(N),WA(N) - COMMON /LB3/MP,LP,GTOL,STPMIN,STPMAX - SAVE -C -C SUBROUTINE MCSRCH -C -C A slight modification of the subroutine CSRCH of More' and Thuente. -C The changes are to allow reverse communication, and do not affect -C the performance of the routine. -C -C THE PURPOSE OF MCSRCH IS TO FIND A STEP WHICH SATISFIES -C A SUFFICIENT DECREASE CONDITION AND A CURVATURE CONDITION. -C -C AT EACH STAGE THE SUBROUTINE UPDATES AN INTERVAL OF -C UNCERTAINTY WITH ENDPOINTS STX AND STY. THE INTERVAL OF -C UNCERTAINTY IS INITIALLY CHOSEN SO THAT IT CONTAINS A -C MINIMIZER OF THE MODIFIED FUNCTION -C -C F(X+STP*S) - F(X) - FTOL*STP*(GRADF(X)'S). -C -C IF A STEP IS OBTAINED FOR WHICH THE MODIFIED FUNCTION -C HAS A NONPOSITIVE FUNCTION VALUE AND NONNEGATIVE DERIVATIVE, -C THEN THE INTERVAL OF UNCERTAINTY IS CHOSEN SO THAT IT -C CONTAINS A MINIMIZER OF F(X+STP*S). -C -C THE ALGORITHM IS DESIGNED TO FIND A STEP WHICH SATISFIES -C THE SUFFICIENT DECREASE CONDITION -C -C F(X+STP*S) .LE. F(X) + FTOL*STP*(GRADF(X)'S), -C -C AND THE CURVATURE CONDITION -C -C ABS(GRADF(X+STP*S)'S)) .LE. GTOL*ABS(GRADF(X)'S). -C -C IF FTOL IS LESS THAN GTOL AND IF, FOR EXAMPLE, THE FUNCTION -C IS BOUNDED BELOW, THEN THERE IS ALWAYS A STEP WHICH SATISFIES -C BOTH CONDITIONS. IF NO STEP CAN BE FOUND WHICH SATISFIES BOTH -C CONDITIONS, THEN THE ALGORITHM USUALLY STOPS WHEN ROUNDING -C ERRORS PREVENT FURTHER PROGRESS. IN THIS CASE STP ONLY -C SATISFIES THE SUFFICIENT DECREASE CONDITION. -C -C THE SUBROUTINE STATEMENT IS -C -C SUBROUTINE MCSRCH(N,X,F,G,S,STP,FTOL,XTOL, MAXFEV,INFO,NFEV,WA) -C WHERE -C -C N IS A POSITIVE INTEGER INPUT VARIABLE SET TO THE NUMBER -C OF VARIABLES. -C -C X IS AN ARRAY OF LENGTH N. ON INPUT IT MUST CONTAIN THE -C BASE POINT FOR THE LINE SEARCH. ON OUTPUT IT CONTAINS -C X + STP*S. -C -C F IS A VARIABLE. ON INPUT IT MUST CONTAIN THE VALUE OF F -C AT X. ON OUTPUT IT CONTAINS THE VALUE OF F AT X + STP*S. -C -C G IS AN ARRAY OF LENGTH N. ON INPUT IT MUST CONTAIN THE -C GRADIENT OF F AT X. ON OUTPUT IT CONTAINS THE GRADIENT -C OF F AT X + STP*S. -C -C S IS AN INPUT ARRAY OF LENGTH N WHICH SPECIFIES THE -C SEARCH DIRECTION. -C -C STP IS A NONNEGATIVE VARIABLE. ON INPUT STP CONTAINS AN -C INITIAL ESTIMATE OF A SATISFACTORY STEP. ON OUTPUT -C STP CONTAINS THE FINAL ESTIMATE. -C -C FTOL AND GTOL ARE NONNEGATIVE INPUT VARIABLES. (In this reverse -C communication implementation GTOL is defined in a COMMON -C statement.) TERMINATION OCCURS WHEN THE SUFFICIENT DECREASE -C CONDITION AND THE DIRECTIONAL DERIVATIVE CONDITION ARE -C SATISFIED. -C -C XTOL IS A NONNEGATIVE INPUT VARIABLE. TERMINATION OCCURS -C WHEN THE RELATIVE WIDTH OF THE INTERVAL OF UNCERTAINTY -C IS AT MOST XTOL. -C -C STPMIN AND STPMAX ARE NONNEGATIVE INPUT VARIABLES WHICH -C SPECIFY LOWER AND UPPER BOUNDS FOR THE STEP. (In this reverse -C communication implementatin they are defined in a COMMON -C statement). -C -C MAXFEV IS A POSITIVE INTEGER INPUT VARIABLE. TERMINATION -C OCCURS WHEN THE NUMBER OF CALLS TO FCN IS AT LEAST -C MAXFEV BY THE END OF AN ITERATION. -C -C INFO IS AN INTEGER OUTPUT VARIABLE SET AS FOLLOWS: -C -C INFO = 0 IMPROPER INPUT PARAMETERS. -C -C INFO =-1 A RETURN IS MADE TO COMPUTE THE FUNCTION AND GRADIENT. -C -C INFO = 1 THE SUFFICIENT DECREASE CONDITION AND THE -C DIRECTIONAL DERIVATIVE CONDITION HOLD. -C -C INFO = 2 RELATIVE WIDTH OF THE INTERVAL OF UNCERTAINTY -C IS AT MOST XTOL. -C -C INFO = 3 NUMBER OF CALLS TO FCN HAS REACHED MAXFEV. -C -C INFO = 4 THE STEP IS AT THE LOWER BOUND STPMIN. -C -C INFO = 5 THE STEP IS AT THE UPPER BOUND STPMAX. -C -C INFO = 6 ROUNDING ERRORS PREVENT FURTHER PROGRESS. -C THERE MAY NOT BE A STEP WHICH SATISFIES THE -C SUFFICIENT DECREASE AND CURVATURE CONDITIONS. -C TOLERANCES MAY BE TOO SMALL. -C -C NFEV IS AN INTEGER OUTPUT VARIABLE SET TO THE NUMBER OF -C CALLS TO FCN. -C -C WA IS A WORK ARRAY OF LENGTH N. -C -C SUBPROGRAMS CALLED -C -C MCSTEP -C -C FORTRAN-SUPPLIED...ABS,MAX,MIN -C -C ARGONNE NATIONAL LABORATORY. MINPACK PROJECT. JUNE 1983 -C JORGE J. MORE', DAVID J. THUENTE -C -C ********** - INTEGER INFOC,J - LOGICAL BRACKT,STAGE1 - DOUBLE PRECISION DG,DGM,DGINIT,DGTEST,DGX,DGXM,DGY,DGYM, - * FINIT,FTEST1,FM,FX,FXM,FY,FYM,P5,P66,STX,STY, - * STMIN,STMAX,WIDTH,WIDTH1,XTRAPF,ZERO - DATA P5,P66,XTRAPF,ZERO /0.5D0,0.66D0,4.0D0,0.0D0/ - IF(INFO.EQ.-1) GO TO 45 - INFOC = 1 -C -C CHECK THE INPUT PARAMETERS FOR ERRORS. -C - IF (N .LE. 0 .OR. STP .LE. ZERO .OR. FTOL .LT. ZERO .OR. - * GTOL .LT. ZERO .OR. XTOL .LT. ZERO .OR. STPMIN .LT. ZERO - * .OR. STPMAX .LT. STPMIN .OR. MAXFEV .LE. 0) RETURN -C -C COMPUTE THE INITIAL GRADIENT IN THE SEARCH DIRECTION -C AND CHECK THAT S IS A DESCENT DIRECTION. -C - DGINIT = ZERO - DO 10 J = 1, N - DGINIT = DGINIT + G(J)*S(J) - 10 CONTINUE - IF (DGINIT .GE. ZERO) then - write(LP,15) - 15 FORMAT(/' THE SEARCH DIRECTION IS NOT A DESCENT DIRECTION') - RETURN - ENDIF -C -C INITIALIZE LOCAL VARIABLES. -C - BRACKT = .FALSE. - STAGE1 = .TRUE. - NFEV = 0 - FINIT = F - DGTEST = FTOL*DGINIT - WIDTH = STPMAX - STPMIN - WIDTH1 = WIDTH/P5 - DO 20 J = 1, N - WA(J) = X(J) - 20 CONTINUE -C -C THE VARIABLES STX, FX, DGX CONTAIN THE VALUES OF THE STEP, -C FUNCTION, AND DIRECTIONAL DERIVATIVE AT THE BEST STEP. -C THE VARIABLES STY, FY, DGY CONTAIN THE VALUE OF THE STEP, -C FUNCTION, AND DERIVATIVE AT THE OTHER ENDPOINT OF -C THE INTERVAL OF UNCERTAINTY. -C THE VARIABLES STP, F, DG CONTAIN THE VALUES OF THE STEP, -C FUNCTION, AND DERIVATIVE AT THE CURRENT STEP. -C - STX = ZERO - FX = FINIT - DGX = DGINIT - STY = ZERO - FY = FINIT - DGY = DGINIT -C -C START OF ITERATION. -C - 30 CONTINUE -C -C SET THE MINIMUM AND MAXIMUM STEPS TO CORRESPOND -C TO THE PRESENT INTERVAL OF UNCERTAINTY. -C - IF (BRACKT) THEN - STMIN = MIN(STX,STY) - STMAX = MAX(STX,STY) - ELSE - STMIN = STX - STMAX = STP + XTRAPF*(STP - STX) - END IF -C -C FORCE THE STEP TO BE WITHIN THE BOUNDS STPMAX AND STPMIN. -C - STP = MAX(STP,STPMIN) - STP = MIN(STP,STPMAX) -C -C IF AN UNUSUAL TERMINATION IS TO OCCUR THEN LET -C STP BE THE LOWEST POINT OBTAINED SO FAR. -C - IF ((BRACKT .AND. (STP .LE. STMIN .OR. STP .GE. STMAX)) - * .OR. NFEV .GE. MAXFEV-1 .OR. INFOC .EQ. 0 - * .OR. (BRACKT .AND. STMAX-STMIN .LE. XTOL*STMAX)) STP = STX -C -C EVALUATE THE FUNCTION AND GRADIENT AT STP -C AND COMPUTE THE DIRECTIONAL DERIVATIVE. -C We return to main program to obtain F and G. -C - DO 40 J = 1, N - X(J) = WA(J) + STP*S(J) - 40 CONTINUE - INFO=-1 - RETURN -C - 45 INFO=0 - NFEV = NFEV + 1 - DG = ZERO - DO 50 J = 1, N - DG = DG + G(J)*S(J) - 50 CONTINUE - FTEST1 = FINIT + STP*DGTEST -C -C TEST FOR CONVERGENCE. -C - IF ((BRACKT .AND. (STP .LE. STMIN .OR. STP .GE. STMAX)) - * .OR. INFOC .EQ. 0) INFO = 6 - IF (STP .EQ. STPMAX .AND. - * F .LE. FTEST1 .AND. DG .LE. DGTEST) INFO = 5 - IF (STP .EQ. STPMIN .AND. - * (F .GT. FTEST1 .OR. DG .GE. DGTEST)) INFO = 4 - IF (NFEV .GE. MAXFEV) INFO = 3 - IF (BRACKT .AND. STMAX-STMIN .LE. XTOL*STMAX) INFO = 2 - IF (F .LE. FTEST1 .AND. ABS(DG) .LE. GTOL*(-DGINIT)) INFO = 1 -C -C CHECK FOR TERMINATION. -C - IF (INFO .NE. 0) RETURN -C -C IN THE FIRST STAGE WE SEEK A STEP FOR WHICH THE MODIFIED -C FUNCTION HAS A NONPOSITIVE VALUE AND NONNEGATIVE DERIVATIVE. -C - IF (STAGE1 .AND. F .LE. FTEST1 .AND. - * DG .GE. MIN(FTOL,GTOL)*DGINIT) STAGE1 = .FALSE. -C -C A MODIFIED FUNCTION IS USED TO PREDICT THE STEP ONLY IF -C WE HAVE NOT OBTAINED A STEP FOR WHICH THE MODIFIED -C FUNCTION HAS A NONPOSITIVE FUNCTION VALUE AND NONNEGATIVE -C DERIVATIVE, AND IF A LOWER FUNCTION VALUE HAS BEEN -C OBTAINED BUT THE DECREASE IS NOT SUFFICIENT. -C - IF (STAGE1 .AND. F .LE. FX .AND. F .GT. FTEST1) THEN -C -C DEFINE THE MODIFIED FUNCTION AND DERIVATIVE VALUES. -C - FM = F - STP*DGTEST - FXM = FX - STX*DGTEST - FYM = FY - STY*DGTEST - DGM = DG - DGTEST - DGXM = DGX - DGTEST - DGYM = DGY - DGTEST -C -C CALL CSTEP TO UPDATE THE INTERVAL OF UNCERTAINTY -C AND TO COMPUTE THE NEW STEP. -C - CALL MCSTEP(STX,FXM,DGXM,STY,FYM,DGYM,STP,FM,DGM, - * BRACKT,STMIN,STMAX,INFOC) -C -C RESET THE FUNCTION AND GRADIENT VALUES FOR F. -C - FX = FXM + STX*DGTEST - FY = FYM + STY*DGTEST - DGX = DGXM + DGTEST - DGY = DGYM + DGTEST - ELSE -C -C CALL MCSTEP TO UPDATE THE INTERVAL OF UNCERTAINTY -C AND TO COMPUTE THE NEW STEP. -C - CALL MCSTEP(STX,FX,DGX,STY,FY,DGY,STP,F,DG, - * BRACKT,STMIN,STMAX,INFOC) - END IF -C -C FORCE A SUFFICIENT DECREASE IN THE SIZE OF THE -C INTERVAL OF UNCERTAINTY. -C - IF (BRACKT) THEN - IF (ABS(STY-STX) .GE. P66*WIDTH1) - * STP = STX + P5*(STY - STX) - WIDTH1 = WIDTH - WIDTH = ABS(STY-STX) - END IF -C -C END OF ITERATION. -C - GO TO 30 -C -C LAST LINE OF SUBROUTINE MCSRCH. -C - END - SUBROUTINE MCSTEP(STX,FX,DX,STY,FY,DY,STP,FP,DP,BRACKT, - * STPMIN,STPMAX,INFO) - INTEGER INFO - DOUBLE PRECISION STX,FX,DX,STY,FY,DY,STP,FP,DP,STPMIN,STPMAX - LOGICAL BRACKT,BOUND -C -C SUBROUTINE MCSTEP -C -C THE PURPOSE OF MCSTEP IS TO COMPUTE A SAFEGUARDED STEP FOR -C A LINESEARCH AND TO UPDATE AN INTERVAL OF UNCERTAINTY FOR -C A MINIMIZER OF THE FUNCTION. -C -C THE PARAMETER STX CONTAINS THE STEP WITH THE LEAST FUNCTION -C VALUE. THE PARAMETER STP CONTAINS THE CURRENT STEP. IT IS -C ASSUMED THAT THE DERIVATIVE AT STX IS NEGATIVE IN THE -C DIRECTION OF THE STEP. IF BRACKT IS SET TRUE THEN A -C MINIMIZER HAS BEEN BRACKETED IN AN INTERVAL OF UNCERTAINTY -C WITH ENDPOINTS STX AND STY. -C -C THE SUBROUTINE STATEMENT IS -C -C SUBROUTINE MCSTEP(STX,FX,DX,STY,FY,DY,STP,FP,DP,BRACKT, -C STPMIN,STPMAX,INFO) -C -C WHERE -C -C STX, FX, AND DX ARE VARIABLES WHICH SPECIFY THE STEP, -C THE FUNCTION, AND THE DERIVATIVE AT THE BEST STEP OBTAINED -C SO FAR. THE DERIVATIVE MUST BE NEGATIVE IN THE DIRECTION -C OF THE STEP, THAT IS, DX AND STP-STX MUST HAVE OPPOSITE -C SIGNS. ON OUTPUT THESE PARAMETERS ARE UPDATED APPROPRIATELY. -C -C STY, FY, AND DY ARE VARIABLES WHICH SPECIFY THE STEP, -C THE FUNCTION, AND THE DERIVATIVE AT THE OTHER ENDPOINT OF -C THE INTERVAL OF UNCERTAINTY. ON OUTPUT THESE PARAMETERS ARE -C UPDATED APPROPRIATELY. -C -C STP, FP, AND DP ARE VARIABLES WHICH SPECIFY THE STEP, -C THE FUNCTION, AND THE DERIVATIVE AT THE CURRENT STEP. -C IF BRACKT IS SET TRUE THEN ON INPUT STP MUST BE -C BETWEEN STX AND STY. ON OUTPUT STP IS SET TO THE NEW STEP. -C -C BRACKT IS A LOGICAL VARIABLE WHICH SPECIFIES IF A MINIMIZER -C HAS BEEN BRACKETED. IF THE MINIMIZER HAS NOT BEEN BRACKETED -C THEN ON INPUT BRACKT MUST BE SET FALSE. IF THE MINIMIZER -C IS BRACKETED THEN ON OUTPUT BRACKT IS SET TRUE. -C -C STPMIN AND STPMAX ARE INPUT VARIABLES WHICH SPECIFY LOWER -C AND UPPER BOUNDS FOR THE STEP. -C -C INFO IS AN INTEGER OUTPUT VARIABLE SET AS FOLLOWS: -C IF INFO = 1,2,3,4,5, THEN THE STEP HAS BEEN COMPUTED -C ACCORDING TO ONE OF THE FIVE CASES BELOW. OTHERWISE -C INFO = 0, AND THIS INDICATES IMPROPER INPUT PARAMETERS. -C -C SUBPROGRAMS CALLED -C -C FORTRAN-SUPPLIED ... ABS,MAX,MIN,SQRT -C -C ARGONNE NATIONAL LABORATORY. MINPACK PROJECT. JUNE 1983 -C JORGE J. MORE', DAVID J. THUENTE -C - DOUBLE PRECISION GAMMA,P,Q,R,S,SGND,STPC,STPF,STPQ,THETA - INFO = 0 -C -C CHECK THE INPUT PARAMETERS FOR ERRORS. -C - IF ((BRACKT .AND. (STP .LE. MIN(STX,STY) .OR. - * STP .GE. MAX(STX,STY))) .OR. - * DX*(STP-STX) .GE. 0.0 .OR. STPMAX .LT. STPMIN) RETURN -C -C DETERMINE IF THE DERIVATIVES HAVE OPPOSITE SIGN. -C - SGND = DP*(DX/ABS(DX)) -C -C FIRST CASE. A HIGHER FUNCTION VALUE. -C THE MINIMUM IS BRACKETED. IF THE CUBIC STEP IS CLOSER -C TO STX THAN THE QUADRATIC STEP, THE CUBIC STEP IS TAKEN, -C ELSE THE AVERAGE OF THE CUBIC AND QUADRATIC STEPS IS TAKEN. -C - IF (FP .GT. FX) THEN - INFO = 1 - BOUND = .TRUE. - THETA = 3*(FX - FP)/(STP - STX) + DX + DP - S = MAX(ABS(THETA),ABS(DX),ABS(DP)) - GAMMA = S*SQRT((THETA/S)**2 - (DX/S)*(DP/S)) - IF (STP .LT. STX) GAMMA = -GAMMA - P = (GAMMA - DX) + THETA - Q = ((GAMMA - DX) + GAMMA) + DP - R = P/Q - STPC = STX + R*(STP - STX) - STPQ = STX + ((DX/((FX-FP)/(STP-STX)+DX))/2)*(STP - STX) - IF (ABS(STPC-STX) .LT. ABS(STPQ-STX)) THEN - STPF = STPC - ELSE - STPF = STPC + (STPQ - STPC)/2 - END IF - BRACKT = .TRUE. -C -C SECOND CASE. A LOWER FUNCTION VALUE AND DERIVATIVES OF -C OPPOSITE SIGN. THE MINIMUM IS BRACKETED. IF THE CUBIC -C STEP IS CLOSER TO STX THAN THE QUADRATIC (SECANT) STEP, -C THE CUBIC STEP IS TAKEN, ELSE THE QUADRATIC STEP IS TAKEN. -C - ELSE IF (SGND .LT. 0.0) THEN - INFO = 2 - BOUND = .FALSE. - THETA = 3*(FX - FP)/(STP - STX) + DX + DP - S = MAX(ABS(THETA),ABS(DX),ABS(DP)) - GAMMA = S*SQRT((THETA/S)**2 - (DX/S)*(DP/S)) - IF (STP .GT. STX) GAMMA = -GAMMA - P = (GAMMA - DP) + THETA - Q = ((GAMMA - DP) + GAMMA) + DX - R = P/Q - STPC = STP + R*(STX - STP) - STPQ = STP + (DP/(DP-DX))*(STX - STP) - IF (ABS(STPC-STP) .GT. ABS(STPQ-STP)) THEN - STPF = STPC - ELSE - STPF = STPQ - END IF - BRACKT = .TRUE. -C -C THIRD CASE. A LOWER FUNCTION VALUE, DERIVATIVES OF THE -C SAME SIGN, AND THE MAGNITUDE OF THE DERIVATIVE DECREASES. -C THE CUBIC STEP IS ONLY USED IF THE CUBIC TENDS TO INFINITY -C IN THE DIRECTION OF THE STEP OR IF THE MINIMUM OF THE CUBIC -C IS BEYOND STP. OTHERWISE THE CUBIC STEP IS DEFINED TO BE -C EITHER STPMIN OR STPMAX. THE QUADRATIC (SECANT) STEP IS ALSO -C COMPUTED AND IF THE MINIMUM IS BRACKETED THEN THE THE STEP -C CLOSEST TO STX IS TAKEN, ELSE THE STEP FARTHEST AWAY IS TAKEN. -C - ELSE IF (ABS(DP) .LT. ABS(DX)) THEN - INFO = 3 - BOUND = .TRUE. - THETA = 3*(FX - FP)/(STP - STX) + DX + DP - S = MAX(ABS(THETA),ABS(DX),ABS(DP)) -C -C THE CASE GAMMA = 0 ONLY ARISES IF THE CUBIC DOES NOT TEND -C TO INFINITY IN THE DIRECTION OF THE STEP. -C - GAMMA = S*SQRT(MAX(0.0D0,(THETA/S)**2 - (DX/S)*(DP/S))) - IF (STP .GT. STX) GAMMA = -GAMMA - P = (GAMMA - DP) + THETA - Q = (GAMMA + (DX - DP)) + GAMMA - R = P/Q - IF (R .LT. 0.0 .AND. GAMMA .NE. 0.0) THEN - STPC = STP + R*(STX - STP) - ELSE IF (STP .GT. STX) THEN - STPC = STPMAX - ELSE - STPC = STPMIN - END IF - STPQ = STP + (DP/(DP-DX))*(STX - STP) - IF (BRACKT) THEN - IF (ABS(STP-STPC) .LT. ABS(STP-STPQ)) THEN - STPF = STPC - ELSE - STPF = STPQ - END IF - ELSE - IF (ABS(STP-STPC) .GT. ABS(STP-STPQ)) THEN - STPF = STPC - ELSE - STPF = STPQ - END IF - END IF -C -C FOURTH CASE. A LOWER FUNCTION VALUE, DERIVATIVES OF THE -C SAME SIGN, AND THE MAGNITUDE OF THE DERIVATIVE DOES -C NOT DECREASE. IF THE MINIMUM IS NOT BRACKETED, THE STEP -C IS EITHER STPMIN OR STPMAX, ELSE THE CUBIC STEP IS TAKEN. -C - ELSE - INFO = 4 - BOUND = .FALSE. - IF (BRACKT) THEN - THETA = 3*(FP - FY)/(STY - STP) + DY + DP - S = MAX(ABS(THETA),ABS(DY),ABS(DP)) - GAMMA = S*SQRT((THETA/S)**2 - (DY/S)*(DP/S)) - IF (STP .GT. STY) GAMMA = -GAMMA - P = (GAMMA - DP) + THETA - Q = ((GAMMA - DP) + GAMMA) + DY - R = P/Q - STPC = STP + R*(STY - STP) - STPF = STPC - ELSE IF (STP .GT. STX) THEN - STPF = STPMAX - ELSE - STPF = STPMIN - END IF - END IF -C -C UPDATE THE INTERVAL OF UNCERTAINTY. THIS UPDATE DOES NOT -C DEPEND ON THE NEW STEP OR THE CASE ANALYSIS ABOVE. -C - IF (FP .GT. FX) THEN - STY = STP - FY = FP - DY = DP - ELSE - IF (SGND .LT. 0.0) THEN - STY = STX - FY = FX - DY = DX - END IF - STX = STP - FX = FP - DX = DP - END IF -C -C COMPUTE THE NEW STEP AND SAFEGUARD IT. -C - STPF = MIN(STPMAX,STPF) - STPF = MAX(STPMIN,STPF) - STP = STPF - IF (BRACKT .AND. BOUND) THEN - IF (STY .GT. STX) THEN - STP = MIN(STX+0.66*(STY-STX),STP) - ELSE - STP = MAX(STX+0.66*(STY-STX),STP) - END IF - END IF - RETURN -C -C LAST LINE OF SUBROUTINE MCSTEP. -C - END - EOF lbfgs.f .