alpaqa develop
Nonconvex constrained optimization
Loading...
Searching...
No Matches
ipopt-adapter.cpp
Go to the documentation of this file.
2
3#include <IpIpoptCalculatedQuantities.hpp>
4#include <stdexcept>
5
6namespace alpaqa {
7
8IpoptAdapter::IpoptAdapter(const Problem &problem) : problem(problem) {}
9
12 n = static_cast<Index>(problem.get_n());
13 m = static_cast<Index>(problem.get_m());
14 nnz_jac_g = static_cast<Index>(cvt_sparsity_jac_g.get_sparsity().nnz());
15 nnz_h_lag = static_cast<Index>(cvt_sparsity_hess_L.get_sparsity().nnz());
16 auto jac_g_index = cvt_sparsity_jac_g.get_sparsity().first_index;
17 auto hess_L_index = cvt_sparsity_hess_L.get_sparsity().first_index;
19 throw std::invalid_argument(
20 "All problem matrices should use the same index convention");
21 if (jac_g_index != 0 && jac_g_index != 1)
22 throw std::invalid_argument(
23 "Sparse matrix indices should start at 0 or 1");
24 index_style = jac_g_index == 0 ? TNLP::C_STYLE : TNLP::FORTRAN_STYLE;
25 auto hess_L_sym = cvt_sparsity_hess_L.get_sparsity().symmetry;
27 if (hess_L_sym != Upper && hess_L_sym != Lower)
28 throw std::invalid_argument("Hessian matrix should be symmetric");
29 return true;
30}
31
33 Number *g_l, Number *g_u) {
34 const auto &C = problem.get_box_C();
35 mvec{x_l, n} = C.lowerbound;
36 mvec{x_u, n} = C.upperbound;
37 const auto &D = problem.get_box_D();
38 mvec{g_l, m} = D.lowerbound;
39 mvec{g_u, m} = D.upperbound;
40 return true;
41}
42
44 bool init_z, Number *z_L, Number *z_U,
45 Index m, bool init_lambda,
46 Number *lambda) {
47 if (init_x) {
48 if (initial_guess.size() > 0)
49 mvec{x, n} = initial_guess;
50 else
51 mvec{x, n}.setZero();
52 }
53 if (init_z) {
55 mvec{z_L, n} = (initial_guess_bounds_multipliers.array() < 0)
57 else
58 mvec{z_L, n}.setZero();
60 mvec{z_U, n} = (initial_guess_bounds_multipliers.array() > 0)
62 else
63 mvec{z_U, n}.setZero();
64 }
65 if (init_lambda) {
66 if (initial_guess_multipliers.size() > 0)
68 else
69 mvec{lambda, m}.setZero();
70 }
71 return true;
72}
73
77 return true;
78}
79
81 [[maybe_unused]] bool new_x, Number *grad_f) {
82 problem.eval_grad_f(cmvec{x, n}, mvec{grad_f, n});
83 return true;
84}
85
87 Index m, Number *g) {
88 problem.eval_g(cmvec{x, n}, mvec{g, m});
89 return true;
90}
91
93 [[maybe_unused]] bool new_x,
95 Index *iRow, Index *jCol, Number *values) {
97 throw std::logic_error("Missing required function: eval_jac_g");
98 if (values == nullptr) { // Initialize sparsity
99 std::ranges::copy(cvt_sparsity_jac_g.get_sparsity().row_indices, iRow);
100 std::ranges::copy(cvt_sparsity_jac_g.get_sparsity().col_indices, jCol);
101 } else { // Evaluate values
102 auto eval_jac_g = [&](rvec v) { problem.eval_jac_g(cmvec{x, n}, v); };
103 cvt_sparsity_jac_g.convert_values(eval_jac_g, mvec{values, nele_jac});
104 }
105 return true;
106}
107
111 Index *iRow, Index *jCol, Number *values) {
113 throw std::logic_error("Missing required function: eval_hess_L");
114 if (values == nullptr) { // Initialize sparsity
115 std::ranges::copy(cvt_sparsity_hess_L.get_sparsity().row_indices, iRow);
116 std::ranges::copy(cvt_sparsity_hess_L.get_sparsity().col_indices, jCol);
117 } else { // Evaluate values
118 auto eval_hess_L = [&](rvec v) {
120 };
121 cvt_sparsity_hess_L.convert_values(eval_hess_L,
122 mvec{values, nele_hess});
123 }
124 return true;
125}
126void IpoptAdapter::finalize_solution(Ipopt::SolverReturn status, Index n,
127 const Number *x, const Number *z_L,
128 const Number *z_U, Index m,
129 const Number *g, const Number *lambda,
131 const Ipopt::IpoptData *ip_data,
132 Ipopt::IpoptCalculatedQuantities *ip_cq) {
133 results.status = status;
134 results.solution_x = cmvec{x, n};
138 results.solution_g = cmvec{g, m};
140 results.infeasibility = ip_cq->curr_constraint_violation();
141 results.nlp_error = ip_cq->unscaled_curr_nlp_error();
142 results.iter_count = ip_data->iter_count();
143}
144
145} // namespace alpaqa
IpoptAdapter(const Problem &problem)
const Problem & problem
bool eval_g(Index n, const Number *x, bool new_x, Index m, Number *g) override
bool eval_grad_f(Index n, const Number *x, bool new_x, Number *grad_f) override
SparsityConv cvt_sparsity_jac_g
bool eval_h(Index n, const Number *x, bool new_x, Number obj_factor, Index m, const Number *lambda, bool new_lambda, Index nele_hess, Index *iRow, Index *jCol, Number *values) override
bool get_starting_point(Index n, bool init_x, Number *x, bool init_z, Number *z_L, Number *z_U, Index m, bool init_lambda, Number *lambda) override
bool get_bounds_info(Index n, Number *x_l, Number *x_u, Index m, Number *g_l, Number *g_u) override
struct alpaqa::IpoptAdapter::Results results
bool eval_f(Index n, const Number *x, bool new_x, Number &obj_value) override
bool get_nlp_info(Index &n, Index &m, Index &nnz_jac_g, Index &nnz_h_lag, IndexStyleEnum &index_style) override
bool eval_jac_g(Index n, const Number *x, bool new_x, Index m, Index nele_jac, Index *iRow, Index *jCol, Number *values) override
void finalize_solution(Ipopt::SolverReturn status, Index n, const Number *x, const Number *z_L, const Number *z_U, Index m, const Number *g, const Number *lambda, Number obj_value, const Ipopt::IpoptData *ip_data, Ipopt::IpoptCalculatedQuantities *ip_cq) override
SparsityConv cvt_sparsity_hess_L
bool provides_eval_hess_L() const
Returns true if the problem provides an implementation of eval_hess_L.
const Box & get_box_D() const
[Optional] Get the rectangular constraint set of the general constraint function, .
void eval_jac_g(crvec x, rvec J_values) const
[Optional] Function that evaluates the nonzero values of the Jacobian matrix of the constraints,
bool provides_eval_jac_g() const
Returns true if the problem provides an implementation of eval_jac_g.
length_t get_n() const
[Required] Number of decision variables.
length_t get_m() const
[Required] Number of constraints.
void eval_grad_f(crvec x, rvec grad_fx) const
[Required] Function that evaluates the gradient of the cost,
real_t eval_f(crvec x) const
[Required] Function that evaluates the cost,
void eval_g(crvec x, rvec gx) const
[Required] Function that evaluates the constraints,
void eval_hess_L(crvec x, crvec y, real_t scale, rvec H_values) const
[Optional] Function that evaluates the nonzero values of the Hessian of the Lagrangian,
const Box & get_box_C() const
[Optional] Get the rectangular constraint set of the decision variables, .
Symmetry
Describes the symmetry of matrices.
Definition sparsity.hpp:12
typename Conf::mvec mvec
Definition config.hpp:89
typename Conf::cmvec cmvec
Definition config.hpp:90
constexpr const auto inf
Definition config.hpp:112
typename Conf::rvec rvec
Definition config.hpp:91