File: get_started.cpp

package info (click to toggle)
cppad 2026.00.00.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,584 kB
  • sloc: cpp: 112,960; sh: 6,146; ansic: 179; python: 71; sed: 12; makefile: 10
file content (152 lines) | stat: -rw-r--r-- 4,235 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-24 Bradley M. Bell
// ----------------------------------------------------------------------------

/*

{xrst_begin ipopt_solve_get_started.cpp}
{xrst_spell
   lc
}

Nonlinear Programming Using CppAD and Ipopt: Example and Test
#############################################################

Purpose
*******
This example program demonstrates how to use :ref:`ipopt_solve-name` to
solve the example problem in the Ipopt documentation; i.e., the problem

.. math::

   \begin{array}{lc}
   {\rm minimize \; }      &  x_1 * x_4 * (x_1 + x_2 + x_3) + x_3
   \\
   {\rm subject \; to \; } &  x_1 * x_2 * x_3 * x_4  \geq 25
   \\
                     &  x_1^2 + x_2^2 + x_3^2 + x_4^2 = 40
   \\
                     &  1 \leq x_1, x_2, x_3, x_4 \leq 5
   \end{array}

Configuration Requirement
*************************
This example will be compiled and tested provided
:ref:`cmake@include_ipopt` is on the cmake command line.

{xrst_literal
   // BEGIN C++
   // END C++
}

{xrst_end ipopt_solve_get_started.cpp}
*/
// BEGIN C++
# include <cppad/ipopt/solve.hpp>

namespace {
   using CppAD::AD;

   class FG_eval {
   public:
      typedef CPPAD_TESTVECTOR( AD<double> ) ADvector;
      void operator()(ADvector& fg, const ADvector& x)
      {  assert( fg.size() == 3 );
         assert( x.size()  == 4 );

         // Fortran style indexing
         AD<double> x1 = x[0];
         AD<double> x2 = x[1];
         AD<double> x3 = x[2];
         AD<double> 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;
      }
   };
}

bool get_started(void)
{  bool ok = true;
   size_t i;
   typedef CPPAD_TESTVECTOR( double ) Dvector;

   // number of independent variables (domain dimension for f and g)
   size_t nx = 4;
   // number of constraints (range dimension for g)
   size_t ng = 2;
   // initial value of the independent variables
   Dvector xi(nx);
   xi[0] = 1.0;
   xi[1] = 5.0;
   xi[2] = 5.0;
   xi[3] = 1.0;
   // lower and upper limits for x
   Dvector xl(nx), xu(nx);
   for(i = 0; i < nx; i++)
   {  xl[i] = 1.0;
      xu[i] = 5.0;
   }
   // lower and upper limits for g
   Dvector gl(ng), gu(ng);
   gl[0] = 25.0;     gu[0] = 1.0e19;
   gl[1] = 40.0;     gu[1] = 40.0;

   // object that computes objective and constraints
   FG_eval fg_eval;

   // options
   std::string options;
   // turn off any printing
   options += "Integer print_level  0\n";
   options += "String  sb           yes\n";
   // maximum number of iterations
   options += "Integer max_iter     10\n";
   // approximate accuracy in first order necessary conditions;
   // see Mathematical Programming, Volume 106, Number 1,
   // Pages 25-57, Equation (6)
   options += "Numeric tol          1e-6\n";
   // derivative testing
   options += "String  derivative_test            second-order\n";
   // maximum amount of random perturbation; e.g.,
   // when evaluation finite diff
   options += "Numeric point_perturbation_radius  0.\n";

   // place to return solution
   CppAD::ipopt::solve_result<Dvector> solution;

   // solve the problem
   CppAD::ipopt::solve<Dvector, FG_eval>(
      options, xi, xl, xu, gl, gu, fg_eval, solution
   );
   //
   // Check some of the solution values
   //
   ok &= solution.status == CppAD::ipopt::solve_result<Dvector>::success;
   //
   double check_x[]  = { 1.000000, 4.743000, 3.82115, 1.379408 };
   double check_zl[] = { 1.087871, 0.,       0.,      0.       };
   double check_zu[] = { 0.,       0.,       0.,      0.       };
   double rel_tol    = 1e-6;  // relative tolerance
   double abs_tol    = 1e-6;  // absolute tolerance
   for(i = 0; i < nx; i++)
   {  ok &= CppAD::NearEqual(
         check_x[i],  solution.x[i],   rel_tol, abs_tol
      );
      ok &= CppAD::NearEqual(
         check_zl[i], solution.zl[i], rel_tol, abs_tol
      );
      ok &= CppAD::NearEqual(
         check_zu[i], solution.zu[i], rel_tol, abs_tol
      );
   }

   return ok;
}
// END C++