Subroutine Example 1: Rosenbrock's Function

This example is intended to demonstrate how to set up and solve a very simple problem using the subroutine interface. We will show you how to solve Rosenbrock's function in two dimensions, i.e.,

minimize

\[100(x_2 - x_{1}^2)^2 + (1 - x_1)^2 \]

For this example, we will assume that there are no analytic derivatives and no constraints. We will also assume that the subroutines that initialize and evaluate the function are in the same file. We step through the specifics below.

User-Provided Subroutines

This section contains examples of the user-defined functions that are required. The first performs the initialization of the problem. The second performs the evaluation of the function.

First, include the necessary header files. In this case, we need iostream so we can print error messages and the OPT++ header file, NLP.h, for some definitions. Also, because we are going to great a dynamically loadable library, we need to surround all of our code by an extern "C" statement.

#include <iostream>
#include "NLP.h"

extern "C" {

The subroutine that initializes the problem should perform any one-time tasks that are needed for the problem. One part of that is checking for error conditions in the setup. In this case, the dimension, ndim, can only take on a value of 2. Using "exit" is not the ideal way to deal with error conditions, but it serves well as an example.

void init_rosen(int ndim, ColumnVector& x)
{
  if (ndim != 2) {
    cerr << "Number of variables for Rosenbrock's function should be 2."
         << "  The number of variables given is " << ndim << endl;
    exit (1);
  } //end if
} //end init_rosen

The other required subroutine will evaluate the function. In this problem, we are trying to find the minimum value of Rosenbrock's function, so it is necessary to write the code that compute the value of that function given some set of optimization parameters. Mathematically, Rosenbrock's function is:

\[f(x) = 100(x_2 - x_{1}^2)^2 + (1 - x_1)^2 \]

The following code will compute the value of f(x).

First, some manipulation of the optimization parameters, x, is done.

void rosen0(int ndim, const ColumnVector& x, double& fx, int& result)
{
  double f1, f2, x1, x2;

  x1 = x(1);
  x2 = x(2);
  f1 = (x2 - x1 * x1);
  f2 = 1. - x1;

Then the function value, fx, is computed, and the variable, result, is set to indicate that a function evaluation was performed.

  fx  = 100.* f1*f1 + f2*f2;
  result = NLPFunction;
} //end rosen0
} //end extern "C"

Now that we have all of the code necessary to initialize and evaluate Rosenbrock's function, give it a try!

Building and Running the Example

If you want to try running this example, the following steps should do the trick.

  1. cd into your favorite directory.
  2. Write the code described above. You can organize it however you like, but we recommend putting both subroutines in the same file (e.g., testexample.C).
  3. Copy the Makefile from the tests/xml directory into the directory where your code resides. (WARNING: Since the Makefile contains platform-dependent information, it should be one that was configured for the platform on which you are doing this example.)
  4. Edit the Makefile by replacing the files listed in the existing SOURCES line with your file. For example,
               SOURCES = testexample.C
            
  5. Type "make". This step will create the library, testexample.so.
  6. Set the LD_LIBRARY_PATH environment variable to the directory where your library resides. For us, the directory was /home/pdhough/TooMuchFun, so:
    	   for csh or tcsh, <br>
    	   setenv LD_LIBRARY_PATH /home/pdhough/TooMuchFun
    	
    OR
    	   for bash, <br>
    	   set LD_LIBRARY_PATH=/home/pdhough/TooMuchFun
    	   export LD_LIBRARY_PATH
    	
  7. Create the XML input file for OPT++. The initialization subroutine is init_rosen, the function subroutine is rosen0, and the library is testexample.so. The number or variables is 2, and there are no derivatives or constraints. If you want to duplicate our results, we used an initial guess of -1.2 for the first variable and 1.0 for the second. We used the PDS algorithm with the default values for all of the parameters except for the maximum number of function evaluations, which we set to 10000. We recommend putting the XML file in the same directory as your code so that you have all of your problem information in one place.
  8. If you have set up OPT++ and the various environment variables as described in the documentations, you should now be able to run the problem by issuing the following command:
               ./testexample
            

    If you like, you can compare your output to our results. There may be slight differences, but if you used the same input that we did, the results should look pretty much the same.

Next Example: Subroutine Example 2: Hock-Schittkowski Problem Number 14 | Back to Using the (beta) GUI/XML Interface

Last revised July 25, 2006


Bug Reports    OPT++ Developers    Copyright Information    GNU Lesser General Public License
Documentation, generated by , last revised August 30, 2006.