⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 example1.html.svn-base

📁 OPT++
💻 SVN-BASE
字号:
/** \page example1 Example 1: Unconstrained Quasi-Newton Without DerivativesThis example is intended to demonstrate how to set up and solve a verysimple problem.  We will show you how to solve (unconstrained)Rosenbrock's function in two dimensions, i.e.,<em> minimize </em> \f[100(x_2 - x_{1}^2)^2 + (1 - x_1)^2 \f]For demonstration purposes, we will assume that there are no analyticderivatives available so we will use finite-difference approximationsto the gradient and a quasi-Newton algorithm with a BFGS approximationto the Hessian.  Recall that it is necessary to write C++ code for themain routine that sets up the problem and the algorithm and for thesubroutines that initialize and evaluate the function.  We stepthrough the specifics below.<ul>  <li> \ref main1 <br>  <li> \ref function1 <br>  <li> \ref run1 <br></ul>\section main1 Main RoutineFirst include the necessary header files.  Start with any C++/C headerfiles that are needed.  In this case, a bit of I/O.  The othertwo header files are OPT++ header files.  NLF contains objects, data,and methods required for setting up the function/problem.  OptQNewtoncontains the objects, data, and methods required for using anunconstrained quasi-Newton optimization method. The last statement <em> using NEWMAT::ColumnVector</em> introduces the data member ColumnVectorfrom the matrix library namespace NEWMAT.  The use of namespaces preventspotential conflicts with third party libraries that may also have a datamember named ColumnVector.<table><tr><td>\code#include <fstream>#include "NLF.h"#include "OptQNewton.h"using NEWMAT::ColumnVector;\endcode</table>The following two lines serve as the declarations of the pointers to thesubroutines that initialize the problem and evaluate the objectivefunction, respectively.<table><tr><td>\codevoid init_rosen(int ndim, ColumnVector& x);void rosen(int ndim, const ColumnVector& x, double& fx, int& result);\endcode</table>The next few lines complete the setup of the problem, which include setting the dimension of the problem and creating the nonliner functionobject.  To create the nonlinear function object usethe dimension of the problem and the pointers to the subroutinesdeclared above.  The FDNLF1 object has built-in finite-differenceapproximations to the gradient.  <table><tr><td>\codeint main(){  int ndim = 2;  FDNLF1 nlp(ndim, rosen, init_rosen);\endcode</table>  Now, let's build a quasi-Newton algorithm object using the nonlinear problem thathas just been created.  The quasi-Newton algorithm will use BFGSupdates to approximate the Hessian.  In addition, set any of thealgorithmic parameters to desired values.  All parameters have defaultvalues, so it is not necessary to set them unless you have specificvalues you wish to use.  In this example, we set the globalizationstrategy, the maximum number of function evaluations allowed, thefunction tolerance (used as a stopping criterion), and the name of theoutput file.<table><tr><td>\code  OptQNewton objfcn(&nlp);  objfcn.setSearchStrategy(TrustRegion);  objfcn.setMaxFeval(200);  objfcn.setFcnTol(1.e-4);// The "0" in the second argument says to create a new file.  A "1"// would signify appending to an existing file.  if (!objfcn.setOutputFile("example1.out", 0))    cerr << "main: output file open failed" << endl;\endcode</table>Now call the algorithm's optimize method to solve the problem.<table><tr><td>\code  objfcn.optimize();\endcode</table>Finally, print out some summary information and clean up before exiting.  Thesummary information is handy, but not necessary.  The cleanup flushesthe I/O buffers.<table><tr><td>\code  objfcn.printStatus("Solution from quasi-newton");  objfcn.cleanup();}\endcode</table>Now that the main routine is in place, we step through the coderequired for the initialization and evaluation of the function.\section function1 User-Defined FunctionsThis section contains examples of the user-defined functions that arerequired.  The first performs the initialization of the problem.  Thesecond performs the evaluation of the function.First, include the necessary header files.  In this case, we need theOPT++ header file, NLP, for some definitions.  Next, we define the scope of themethods using namespace. The first statment introduces the datamember ColumnVector from the namespace NEWMAT.  The second statement allowsus to refer to all the methods in the OPTPP namespace.  These two statementsare crucial for a sucessful compilation.<table><tr><td>\code#include "NLP.h"using NEWMAT::ColumnVector;using namespace::OPTPP;\endcode</table>The subroutine that initializes the problem should perform anyone-time tasks that are needed for the problem.  One part of that ischecking for error conditions in the setup.  In this case, thedimension, <em>ndim</em>, can only take on a value of 2.  Using "exit"is not the ideal way to deal with error conditions, but it serves wellas an example.<table><tr><td>\codevoid init_rosen (int ndim, ColumnVector& x){  if (ndim != 2)    exit (1);\endcode</table>The initialization is also an ideal place to set the initial values ofthe optimization parameters, <em>x</em>.  This can be hard coded, asdone here, or it can be done in some other manner (e.g., reading themin from a file, the code for which should appear here).<table><tr><td>\code// ColumnVectors are indexed from 1, and they use parentheses around// the index.  x(1) = -1.2;  x(2) =  1.0;}\endcode</table>The last piece of code is a subroutine that will evaluate thefunction.  In this problem, we are trying to find the minimum value ofRosenbrock's function, so it is necessary to write the code thatcomputes the value of that function given some set of optimizationparameters.  Mathematically, Rosenbrock's function is:\f[f(x) = 100(x_2 - x_{1}^2)^2 + (1 - x_1)^2 \f]The following code will compute the value of <em>f(x)</em>.First, some error checking and manipulation of the optimizationparameters, <em>x</em>, are done.<table><tr><td>\codevoid rosen(int ndim, const ColumnVector& x, double& fx, int& result){  double f1, f2, x1, x2;  if (ndim != 2)    exit (1);  x1 = x(1);  x2 = x(2);  f1 = (x2 - x1 * x1);  f2 = 1. - x1;\endcode</table>Then the function value, <em>fx</em>, is computed, and the variable,<em>result</em>, is set to indicate that a function evaluation wasperformed.  <table><tr><td>\code  fx  = 100.* f1*f1 + f2*f2;  result = NLPFunction;}\endcode</table>On a more general note, this subroutine could serve as a wrapper to aC or Fortran subroutine.  Similarly, it could make a system call to acompletely independent executable.  As long as the values of<em>fx</em> and <em>result</em> are set when all is said and done, itdoes not matter how the function value is computed.Now that we have all of the code necessary to set up and solveRosenbrock's function, give it a try!\section run1 Building and Running the ExampleBuilding your executable should be fairly straightforward.  Below isthe recommended set of steps to follow.<ol>      <li> Determine which defines you need.  If the C++ compiler you	   are using supports the ANSI standard style of C header	   files, you will need           \verbatim		-DHAVE_STD           \endverbatim	   If the C++ compiler you are using supports namespaces, you	   will need           \verbatim		-DHAVE_NAMESPACES           \endverbatim	   If you are using the parallel version of OPT++, you will	   need           \verbatim		-DWITH_MPI           \endverbatim      <li> Determine the location of the header files.  If you did a	   "make install", they will be located in the "include"	   subdirectory of the directory in which OPT++ is installed.	   If that directory is not one your compiler normally checks,	   you will need           \verbatim		-IOPT++_install_directory/include           \endverbatim	   If you did not do a "make install", the header files will	   almost certainly be in a directory not checked by your	   compiler.  Thus, you will need           \verbatim		-IOPT++_top_directory/include -IOPT++_top_directory/newmat11           \endverbatim	<li> Determine the location of the libraries.  If you did a	   "make install", they will be located in the "lib"	   subdirectory of the directory in which OPT++ is installed.	   If that directory is not one your compiler normally checks,	   you will need           \verbatim		-LOPT++_install_directory/lib           \endverbatim	   If you did not do a "make install", the libraries will	   almost certainly be in a directory not checked by your	   compiler.  Thus, you will need           \verbatim		-LOPT++_top_directory/lib/.libs           \endverbatim	<li> If you configured OPT++ for the default behavior of using	   the BLAS and/or you configure OPT++ to use NPSOL, you will	   need the appropriate Fortran libraries for linking.  The	   easiest way to get these is to look in the Makefile for the	   value of FLIBS.	<li> If all is right in the world, the following format for your	   compilation command should work:           \verbatim		$CXX <defines> <includes> example1.C tstfcn.C <lib \		directory> -lopt -lnewmat -l$BLAS_LIB $FLIBS            \endverbatim	   $CXX is the C++ compiler you are using.  <defines> and	   <includes> are the flags determined in steps 1-2.  example1.C	   is your main routine, and tstfcn.C contains your function	   evaluations.  (Note: If you have put them both in one file,	   you need only list that single file here.)  <lib_directory	   was determined in step 3.  -lopt and -lnewmat are the two	   OPT++ libraries.  $BLAS_LIB is the BLAS library you are	   using, and $FLIBS is the list of Fortran libraries	   determined in step 4.</ol>You should now be able to run the executable (type "./example1").  Youcan compare the results, found in example1.out, to <ahref="example1_out.html">our results</a>.  There may be slightdifferences due to operating system, compiler, etc., but the resultsshould very nearly match.<p> Next Example: \ref example2 | Back to \ref SetUp </p>Last revised <em> April 27, 2007</em>*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -