| Prev | Next |  |  |  |  |  | ipopt_nlp_get_started.cpp |

Nonlinear Programming Using CppAD and Ipopt: Example and Test
Purpose
This example program demonstrates how to use the class cppad_ipopt_nlp to solve the example problem in the Ipopt documentation; i.e., the problem minimize x 1 * x 4 * ( x 1 + x 2 + x 3 ) + x 3 subject to x 1 * x 2 * x 3 * x 4 ≥ 25 x 1 2 + x 2 2 + x 3 2 + x 4 2 = 40 1 ≤ x 1 , x 2 , x 3 , x 4 ≤ 5
Configuration Requirement
This example will be compiled and tested provided that a value for `ipopt_prefix` is specified on the cmake command line. `

    # include <cppad_ipopt_nlp.hpp>

    namespace {
         using namespace cppad_ipopt;

         class FG_info : public cppad_ipopt_fg_info
         {
         private:
              bool retape_;
         public:
              // derived class part of constructor
              FG_info(bool retape_in)
              : retape_ (retape_in)
              { }
              // Evaluation of the objective f(x), and constraints g(x)
              // using an Algorithmic Differentiation (AD) class.
              ADVector eval_r(size_t k, const ADVector&  x)
              {     ADVector fg(3);

                   // Fortran style indexing
                   ADNumber x1 = x[0];
                   ADNumber x2 = x[1];
                   ADNumber x3 = x[2];
                   ADNumber x4 = x[3];
                   // f(x)
                   fg[0] = x1 * x4 * (x1 + x2 + x3) + x3;
                   // g_1 (x)
                   fg[1] = x1 * x2 * x3 * x4;
                   // g_2 (x)
                   fg[2] = x1 * x1 + x2 * x2 + x3 * x3 + x4 * x4;
                   return fg;
              }
              bool retape(size_t k)
              {     return retape_; }
         };
    }

    bool ipopt_get_started(void)
    {     bool ok = true;
         size_t j;

         // number of independent variables (domain dimension for f and g)
         size_t n = 4;
         // number of constraints (range dimension for g)
         size_t m = 2;
         // initial value of the independent variables
         NumberVector x_i(n);
         x_i[0] = 1.0;
         x_i[1] = 5.0;
         x_i[2] = 5.0;
         x_i[3] = 1.0;
         // lower and upper limits for x
         NumberVector x_l(n);
         NumberVector x_u(n);
         for(j = 0; j < n; j++)
         {     x_l[j] = 1.0;
              x_u[j] = 5.0;
         }
         // lower and upper limits for g
         NumberVector g_l(m);
         NumberVector g_u(m);
         g_l[0] = 25.0;     g_u[0] = 1.0e19;
         g_l[1] = 40.0;     g_u[1] = 40.0;

         size_t icase;
         for(icase = 0; icase <= 1; icase++)
         {     // Should cppad_ipopt_nlp retape the operation sequence for
              // every new x. Can test both true and false cases because
              // the operation sequence does not depend on x (for this case).
              bool retape = icase != 0;

              // object in derived class
              FG_info fg_info(retape);

              // create the Ipopt interface
              cppad_ipopt_solution solution;
              Ipopt::SmartPtr<Ipopt::TNLP> cppad_nlp = new cppad_ipopt_nlp(
              n, m, x_i, x_l, x_u, g_l, g_u, &fg_info, &solution
              );

              // Create an instance of the IpoptApplication
              using Ipopt::IpoptApplication;
              Ipopt::SmartPtr<IpoptApplication> app = new IpoptApplication();

              // turn off any printing
              app->Options()->SetIntegerValue("print_level", 0);
              app->Options()->SetStringValue("sb", "yes");

              // maximum number of iterations
              app->Options()->SetIntegerValue("max_iter", 10);

              // approximate accuracy in first order necessary conditions;
              // see Mathematical Programming, Volume 106, Number 1,
              // Pages 25-57, Equation (6)
              app->Options()->SetNumericValue("tol", 1e-9);

              // derivative testing
              app->Options()->
              SetStringValue("derivative_test", "second-order");
              app->Options()-> SetNumericValue(
                   "point_perturbation_radius", 0.
              );

              // Initialize the IpoptApplication and process the options
              Ipopt::ApplicationReturnStatus status = app->Initialize();
              ok    &= status == Ipopt::Solve_Succeeded;

              // Run the IpoptApplication
              status = app->OptimizeTNLP(cppad_nlp);
              ok    &= status == Ipopt::Solve_Succeeded;

              /*
              Check some of the solution values
              */
              ok &= solution.status == cppad_ipopt_solution::success;
              //
              double check_x[]   = { 1.000000, 4.743000, 3.82115, 1.379408 };
              double check_z_l[] = { 1.087871, 0.,       0.,      0.       };
              double check_z_u[] = { 0.,       0.,       0.,      0.       };
              double rel_tol     = 1e-6;  // relative tolerance
              double abs_tol     = 1e-6;  // absolute tolerance
              for(j = 0; j < n; j++)
              {     ok &= CppAD::NearEqual(
                   check_x[j],   solution.x[j],   rel_tol, abs_tol
                   );
                   ok &= CppAD::NearEqual(
                   check_z_l[j], solution.z_l[j], rel_tol, abs_tol
                   );
                   ok &= CppAD::NearEqual(
                   check_z_u[j], solution.z_u[j], rel_tol, abs_tol
                   );
              }
         }

         return ok;
    }

`

Input File: cppad_ipopt/example/get_started.cpp