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
|
// 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
// ----------------------------------------------------------------------------
/*
Testing ipopt::solve
*/
// CPPAD_HAS_* defines
# include <cppad/configure.hpp>
# if CPPAD_HAS_IPOPT
# 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 ipopt_solve(void)
{ bool ok = true;
size_t i, j;
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(j = 0; j < nx; j++)
{ xl[j] = 1.0;
xu[j] = 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 base_options;
// turn off any printing
base_options += "Integer print_level 0\n";
base_options += "String sb yes\n";
// maximum number of iterations
base_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)
base_options += "Numeric tol 1e-6\n";
// derivative testing
base_options += "String derivative_test second-order\n";
// maximum amount of random perturbation; e.g.,
// when evaluation finite diff
base_options += "Numeric point_perturbation_radius 0.\n";
// place to return solution
CppAD::ipopt::solve_result<Dvector> solution;
// solution values and tolerances
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 < 3; i++)
{ std::string options( base_options );
if( i == 1 )
options += "Sparse true forward\n";
if( i == 2 )
options += "Sparse true reverse\n";
// solve the problem
CppAD::ipopt::solve<Dvector, FG_eval>(
options, xi, xl, xu, gl, gu, fg_eval, solution
);
ok &= solution.status==CppAD::ipopt::solve_result<Dvector>::success;
//
// Check some of the solution values
for(j = 0; j < nx; j++)
{ ok &= CppAD::NearEqual(
check_x[j], solution.x[j], rel_tol, abs_tol
);
ok &= CppAD::NearEqual(
check_zl[j], solution.zl[j], rel_tol, abs_tol
);
ok &= CppAD::NearEqual(
check_zu[j], solution.zu[j], rel_tol, abs_tol
);
}
}
return ok;
}
# endif
|