-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathipopt_model.hpp
185 lines (146 loc) · 6.61 KB
/
ipopt_model.hpp
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#pragma once
#include "solvers/ipopt/IpStdCInterface.h"
#include "pyoptinterface/nleval.hpp"
#include "pyoptinterface/dylib.hpp"
#include "pyoptinterface/solver_common.hpp"
#include <cmath>
#define APILIST \
B(CreateIpoptProblem); \
B(FreeIpoptProblem); \
B(AddIpoptStrOption); \
B(AddIpoptNumOption); \
B(AddIpoptIntOption); \
B(IpoptSolve);
namespace ipopt
{
#define B DYLIB_EXTERN_DECLARE
APILIST
#undef B
bool is_library_loaded();
bool load_library(const std::string &path);
} // namespace ipopt
struct IpoptfreeproblemT
{
void operator()(IpoptProblemInfo *model) const
{
ipopt::FreeIpoptProblem(model);
};
};
struct IpoptResult
{
bool is_valid = false;
// store results
std::vector<double> x, g, mult_g, mult_x_L, mult_x_U;
double obj_val;
};
struct IpoptModel
{
/* Methods */
IpoptModel();
void close();
VariableIndex add_variable(double lb = -INFINITY, double ub = INFINITY, double start = 0.0,
const char *name = nullptr);
double get_variable_lb(const VariableIndex &variable);
double get_variable_ub(const VariableIndex &variable);
void set_variable_lb(const VariableIndex &variable, double lb);
void set_variable_ub(const VariableIndex &variable, double ub);
void set_variable_bounds(const VariableIndex &variable, double lb, double ub);
double get_variable_start(const VariableIndex &variable);
void set_variable_start(const VariableIndex &variable, double start);
std::string get_variable_name(const VariableIndex &variable);
void set_variable_name(const VariableIndex &variable, const std::string &name);
double get_variable_value(const VariableIndex &variable);
std::string pprint_variable(const VariableIndex &variable);
ParameterIndex add_parameter(double value = 0.0);
void set_parameter(const ParameterIndex ¶meter, double value);
double get_obj_value();
double get_constraint_primal(IndexT index);
double get_constraint_dual(IndexT index);
ConstraintIndex add_linear_constraint(const ScalarAffineFunction &f, ConstraintSense sense,
double rhs, const char *name = nullptr);
ConstraintIndex add_linear_constraint(const ScalarAffineFunction &f, ConstraintSense sense,
double lb, double ub, const char *name = nullptr);
ConstraintIndex add_linear_constraint(const ExprBuilder &f, ConstraintSense sense, double rhs,
const char *name = nullptr);
ConstraintIndex add_linear_constraint(const ExprBuilder &f, ConstraintSense sense, double lb,
double ub, const char *name = nullptr);
ConstraintIndex add_linear_constraint(const VariableIndex &f, ConstraintSense sense, double rhs,
const char *name = nullptr);
ConstraintIndex add_linear_constraint(const VariableIndex &f, ConstraintSense sense, double lb,
double ub, const char *name = nullptr);
ConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &f,
ConstraintSense sense, double rhs,
const char *name = nullptr);
ConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &f,
ConstraintSense sense, double lb, double ub,
const char *name = nullptr);
ConstraintIndex add_quadratic_constraint(const ExprBuilder &f, ConstraintSense sense,
double rhs, const char *name = nullptr);
ConstraintIndex add_quadratic_constraint(const ExprBuilder &f, ConstraintSense sense, double lb,
double ub, const char *name = nullptr);
template <typename T>
void add_objective(const T &expr)
{
m_lq_model.add_objective(expr);
}
template <typename T>
void set_objective(const T &expr, ObjectiveSense sense = ObjectiveSense::Minimize,
bool clear_nl = false)
{
if (sense != ObjectiveSense::Minimize)
{
throw std::runtime_error(
"Currently Ipopt only supports ObjectiveSense::Minimize, please negate the "
"objective manually if you intend to maximize the objective");
}
m_lq_model.set_objective(expr);
if (clear_nl)
{
clear_nl_objective();
}
}
FunctionIndex _register_function(const AutodiffSymbolicStructure &structure);
void _set_function_evaluator(const FunctionIndex &k, const AutodiffEvaluator &evaluator);
bool _has_function_evaluator(const FunctionIndex &k);
NLConstraintIndex _add_nl_constraint_bounds(const FunctionIndex &k,
const std::vector<VariableIndex> &xs,
const std::vector<ParameterIndex> &ps,
const std::vector<double> &lbs,
const std::vector<double> &ubs);
NLConstraintIndex _add_nl_constraint_eq(const FunctionIndex &k,
const std::vector<VariableIndex> &xs,
const std::vector<ParameterIndex> &ps,
const std::vector<double> &eqs);
void _add_nl_objective(const FunctionIndex &k, const std::vector<VariableIndex> &xs,
const std::vector<ParameterIndex> &ps);
void clear_nl_objective();
void analyze_structure();
void optimize();
// load current solution as initial guess
void load_current_solution();
// set options
void set_raw_option_int(const std::string &name, int value);
void set_raw_option_double(const std::string &name, double value);
void set_raw_option_string(const std::string &name, const std::string &value);
/* Members */
size_t n_variables = 0;
size_t n_constraints = 0;
std::vector<double> m_var_lb, m_var_ub, m_var_init;
std::vector<double> m_con_lb, m_con_ub;
Hashmap<IndexT, std::string> m_var_names, m_con_names;
size_t m_jacobian_nnz = 0;
std::vector<size_t> m_jacobian_rows, m_jacobian_cols;
size_t m_hessian_nnz = 0;
std::vector<size_t> m_hessian_rows, m_hessian_cols;
Hashmap<VariablePair, size_t> m_hessian_index_map;
NonlinearFunctionEvaluator m_function_model;
LinearQuadraticEvaluator m_lq_model;
// The options of the Ipopt solver, we cache them before constructing the m_problem
Hashmap<std::string, int> m_options_int;
Hashmap<std::string, double> m_options_num;
Hashmap<std::string, std::string> m_options_str;
IpoptResult m_result;
enum ApplicationReturnStatus m_status;
std::unique_ptr<IpoptProblemInfo, IpoptfreeproblemT> m_problem = nullptr;
};
using IpoptModelMixin = CommercialSolverMixin<IpoptModel>;