/******************************************************************* c DRIVER 1 c -------------------------------------------------------------- c SIMPLE DRIVER FOR L-BFGS-B (version 2.1) c -------------------------------------------------------------- c *** MODIFIED to drive in C++ (M. Coahran, 11/21/03) *** c -------------------------------------------------------------- c c L-BFGS-B is a code for solving large nonlinear optimization c problems with simple bounds on the variables. c c The code can also be used for unconstrained problems and is c as efficient for these problems as the earlier limited memory c code L-BFGS. c c This is the simplest driver in the package. It uses all the c default settings of the code. c c c References: c c [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited c memory algorithm for bound constrained optimization'', c SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208. c c [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN c Subroutines for Large Scale Bound Constrained Optimization'' c Tech. Report, NAM-11, EECS Department, Northwestern University, c 1994. c c c (Postscript files of these papers are available via anonymous c ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.) c c * * * c c NEOS, November 1994. (Latest revision June 1996.) c Optimization Technology Center. c Argonne National Laboratory and Northwestern University. c Written by c Ciyou Zhu c in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal. c c NOTE: The user should adapt the subroutine 'timer' if 'etime' is c not available on the system. An example for system c AIX Version 3.2 is available at the end of this driver. c *******************************************************************/ #include #include #include const int SIXTY=60; // function prototype for L-BFGS-B routine // NOTES: All arguments must be passed as pointers. Must add an underscore // to the function name. 'extern "C"' keeps c++ from mangling the function // name. Be aware that fortran indexes 1d arrays [1,n] not [0,n-1], and // expects 2d arrays to be in col-major order not row-major order. extern "C" void setulb_(int* n, int* m, double x[], double l[], double u[], int nbd[], double* f, double g[], double* factr, double* pgtol, double wa[], int iwa[], char task[], int* iprint, char csave[], bool lsave[], int isave[], double dsave[]); int main() { //c This simple driver demonstrates how to call the L-BFGS-B code to //c solve a sample problem (the extended Rosenbrock function //c subject to bounds on the variables). The dimension n of this //c problem is variable. int nmax=1024, mmax=17; //c nmax is the dimension of the largest problem to be solved. //c mmax is the maximum number of limited memory corrections. //c Declare the variables needed by the code. //c A description of all these variables is given at the end of //c the driver. char task[SIXTY], csave[SIXTY]; bool lsave[4]; int n, m, iprint, nbd[nmax], iwa[3*nmax], isave[44]; double f, factr, pgtol, x[nmax], l[nmax], u[nmax], g[nmax], dsave[29], wa[2*mmax*nmax+4*nmax+12*mmax*mmax+12*mmax]; //c Declare a few additional variables for this sample problem. double t1, t2; int i; //c We wish to have output at every iteration. iprint = 1; //c We specify the tolerances in the stopping criteria. factr=1.0e7; pgtol=1.0e-5; //c We specify the dimension n of the sample problem and the number //c m of limited memory corrections stored. (n and m should not //c exceed the limits nmax and mmax respectively.) n=25; m=5; //c We now provide nbd which defines the bounds on the variables: //c l specifies the lower bounds, //c u specifies the upper bounds. //c First set bounds on the odd-numbered variables. (*even-numbered in c*) for (i=0; i= 0 is specified by the user. The iteration c will stop when c c max{|proj g_i | i = 1, ..., n} <= pgtol c c where pg_i is the ith component of the projected gradient. c The user can suppress this termination test by setting pgtol=0. c c wa is a DOUBLE PRECISION array of length c (2mmax + 4)nmax + 12mmax^2 + 12mmax used as workspace. c This array must not be altered by the user. c c iwa is an INTEGER array of length 3nmax used as c workspace. This array must not be altered by the user. c c task is a CHARACTER string of length 60. c On first entry, it must be set to 'START'. c On a return with task(1:2)='FG', the user must evaluate the c function f and gradient g at the returned value of x. c On a return with task(1:5)='NEW_X', an iteration of the c algorithm has concluded, and f and g contain f(x) and g(x) c respectively. The user can decide whether to continue or stop c the iteration. c When c task(1:4)='CONV', the termination test in L-BFGS-B has been c satisfied; c task(1:4)='ABNO', the routine has terminated abnormally c without being able to satisfy the termination conditions, c x contains the best approximation found, c f and g contain f(x) and g(x) respectively; c task(1:5)='ERROR', the routine has detected an error in the c input parameters; c On exit with task = 'CONV', 'ABNO' or 'ERROR', the variable task c contains additional information that the user can print. c This array should not be altered unless the user wants to c stop the run for some reason. See driver2 or driver3 c for a detailed explanation on how to stop the run c by assigning task(1:4)='STOP' in the driver. c c iprint is an INTEGER variable that must be set by the user. c It controls the frequency and type of output generated: c iprint<0 no output is generated; c iprint=0 print only one line at the last iteration; c 0100 print details of every iteration including x and g; c When iprint > 0, the file iterate.dat will be created to c summarize the iteration. c c csave is a CHARACTER working array of length 60. c c lsave is a LOGICAL working array of dimension 4. c On exit with task = 'NEW_X', the following information is c available: c lsave(1) = .true. the initial x did not satisfy the bounds; c lsave(2) = .true. the problem contains bounds; c lsave(3) = .true. each variable has upper and lower bounds. c c isave is an INTEGER working array of dimension 44. c On exit with task = 'NEW_X', it contains information that c the user may want to access: c isave(30) = the current iteration number; c isave(34) = the total number of function and gradient c evaluations; c isave(36) = the number of function value or gradient c evaluations in the current iteration; c isave(38) = the number of free variables in the current c iteration; c isave(39) = the number of active constraints at the current c iteration; c c see the subroutine setulb.f for a description of other c information contained in isave c c dsave is a DOUBLE PRECISION working array of dimension 29. c On exit with task = 'NEW_X', it contains information that c the user may want to access: c dsave(2) = the value of f at the previous iteration; c dsave(5) = the machine precision epsmch generated by the code; c dsave(13) = the infinity norm of the projected gradient; c c see the subroutine setulb.f for a description of other c information contained in dsave c c -------------------------------------------------------------- c END OF THE DESCRIPTION OF THE VARIABLES IN L-BFGS-B c -------------------------------------------------------------- c c << An example of subroutine 'timer' for AIX Version 3.2 >> c c subroutine timer(ttime) c double precision ttime c integer itemp, integer mclock c itemp = mclock() c ttime = dble(itemp)*1.0d-2 c return c end ********************************************************************/