/*******************************************************************
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
********************************************************************/