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
|
// 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;
// ---------------------------------------------------------------------------
/*
A test case were retaping is required, no constraints, and L[0] > 1.
*/
class FG_info : public cppad_ipopt_fg_info
{
public:
// derived class part of constructor
FG_info (void)
{ }
// r_0 (u) = u if u > 1 and u^2 otherwise.
ADVector eval_r(size_t k, const ADVector& u)
{ ADVector r(1);
if( u[0] > 1 )
r[0] = u[0];
else
r[0] = u[0] * u[0];
return r;
}
// operation sequence depends on u
bool retape(size_t k)
{ return true; }
// K = 1
size_t number_functions(void)
{ return 1; }
// q[k] = 1
size_t domain_size(size_t k)
{ return 1; }
// p[k] = 1
size_t range_size(size_t k)
{ return 1; }
// L[k] = 2
size_t number_terms(size_t k)
{ return 2; }
// I_{k,ell} = 0 // objective function index
// J_{k,ell} = ell // argument index
void index(size_t k, size_t ell, SizeVector& I, SizeVector& J)
{ I[0] = 0;
J[0] = ell;
}
};
} // end empty namespace
bool retape_k1_l2(void)
{ bool ok = true;
size_t j;
// number of independent variables (domain dimension for f and g)
size_t n = 2;
// no constraints (range dimension for g)
size_t m = 0;
// initial value of the independent variables
NumberVector x_i(n);
x_i[0] = 0.0; // below break in eval_r definition
x_i[1] = 2.0; // above break in eval_r definition
// lower and upper limits for x
NumberVector x_l(n);
NumberVector x_u(n);
for(j = 0; j < n; j++)
{ x_l[j] = -5.0;
x_u[j] = +5.0;
}
// lower and upper limits for g
NumberVector g_l;
NumberVector g_u;
// object in derived class
FG_info my_fg_info;
cppad_ipopt_fg_info *fg_info = &my_fg_info;
// 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 the solution values
*/
ok &= solution.status == cppad_ipopt_solution::success;
//
double rel_tol = 1e-6; // relative tolerance
double abs_tol = 1e-6; // absolute tolerance
for(j = 0; j < n; j++)
ok &= CppAD::NearEqual( 0., solution.x[j], rel_tol, abs_tol);
return ok;
}
|