File: multiple_solution.cpp

package info (click to toggle)
cppad 2025.00.00.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,552 kB
  • sloc: cpp: 112,594; sh: 5,972; ansic: 179; python: 71; sed: 12; makefile: 10
file content (138 lines) | stat: -rw-r--r-- 3,607 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
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-22 Bradley M. Bell
// ----------------------------------------------------------------------------

# include <cppad_ipopt_nlp.hpp>

namespace { // Begin empty namespace
using namespace cppad_ipopt;

// ---------------------------------------------------------------------------
/*
f(x)    = x[1]; k=0, ell=0, I[0] = 0, J[0] = 1
g_0 (x) = x[0]; k=0, ell=1, I[0] = 1, J[0] = 0
g_1 (x) = x[1]; k=0, ell=2, I[0] = 2, J[0] = 1

minimize   f(x)
subject to -1 <= g_0(x)  <= 0
         0 <= g_1 (x) <= 1

The solution is x[1] = 0 and x[0] arbitrary.
*/

class FG_J_changes : public cppad_ipopt_fg_info
{
private:
   bool retape_;
public:
   // constructor
   FG_J_changes(bool retape_in)
   : retape_ (retape_in)
   { }
   size_t number_functions(void)
   {  return 1; }
   size_t domain_size(size_t k)
   {  size_t q = 1;
      assert(k == 0);
      return q;
   }
   size_t range_size(size_t k)
   {  size_t p = 1;
      assert(k == 0);
      return p;
   }
   size_t number_terms(size_t k)
   {  size_t L = 3;
      assert(k == 0);
      return L;
   }
   void index(size_t k, size_t ell, SizeVector&I, SizeVector& J)
   {  assert( I.size() >= 1 );
      assert( J.size() >= 1 );
      I[0] = ell;
      if( ell == 0 )
      {  J[0] = 1;
         return;
      }
      J[0] = ell - 1;
      return;
   }
   // retape function
   bool retape(size_t k)
   {  return retape_; }
   ADVector eval_r(size_t k, const ADVector&  u)
   {
      assert( u.size() == 1 );
      ADVector r(1);
      r[0] = u[0] ;
      return r;
   }
};
} // end empty namespace

bool multiple_solution(void)
{
   bool ok = true;
   // number of independent variables (domain dimension for f and g)
   size_t n = 2;
   // number of constraints (range dimension for g)
   size_t m = 2;
   // initial value of the independent variables
   NumberVector x_i(n);
   NumberVector x_l(n);
   NumberVector x_u(n);

   size_t i = 0;
   for(i = 0; i < n; i++)
   {  x_i[i] = 0.;
      x_l[i] = -1.0;
      x_u[i] = +1.0;
   }

   // lower and upper limits for g
   NumberVector g_l(m);
   NumberVector g_u(m);
   g_l[0] = -1; g_u[0] = 0.;
   g_l[1] = 0.; g_u[1] = 1.;

   // object for evaluating function
   bool retape = false;
   FG_J_changes my_fg_info(retape);
   cppad_ipopt_fg_info *fg_info = &my_fg_info;

   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");

   // 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);
   app->Options()-> SetStringValue("derivative_test", "second-order");

   // 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 solution status
     */
   ok &= solution.status == cppad_ipopt_solution::success;
   ok &= CppAD::NearEqual(solution.x[1], 0., 1e-6, 1e-6);

   return ok;
}