Skip to content

Commit 117d383

Browse files
committed
NLP prototype for IPOPT
1 parent 790307d commit 117d383

File tree

440 files changed

+128495
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

440 files changed

+128495
-3
lines changed

CMakeLists.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(CMAKE_CXX_STANDARD 20)
77
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
88

99
add_subdirectory(thirdparty/fmt)
10+
add_subdirectory(thirdparty/cppad)
1011

1112
set(POI_INSTALL_DIR pyoptinterface/_src)
1213

@@ -37,6 +38,13 @@ target_sources(core PRIVATE
3738
target_include_directories(core PUBLIC include thirdparty)
3839
target_link_libraries(core PUBLIC fmt)
3940

41+
add_library(nlcore STATIC)
42+
target_sources(nlcore PRIVATE
43+
include/pyoptinterface/nlcore.hpp
44+
lib/nlcore.cpp
45+
)
46+
target_link_libraries(nlcore PUBLIC core cppad)
47+
4048
# Build Python extensions
4149
find_package(Python ${PYTHON_VERSION}
4250
REQUIRED COMPONENTS Interpreter Development.Module
@@ -55,6 +63,16 @@ nanobind_add_module(
5563
target_link_libraries(core_ext PUBLIC core)
5664
install(TARGETS core_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})
5765

66+
nanobind_add_module(
67+
nlcore_ext
68+
69+
STABLE_ABI NB_STATIC
70+
71+
lib/nlcore_ext.cpp
72+
)
73+
target_link_libraries(nlcore_ext PUBLIC nlcore)
74+
install(TARGETS nlcore_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})
75+
5876
# Solvers
5977

6078
# Gurobi
@@ -135,6 +153,24 @@ lib/highs_model_ext_constants.cpp
135153
target_link_libraries(highs_model_ext PUBLIC highs_model)
136154
install(TARGETS highs_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})
137155

156+
# IPOPT
157+
add_library(ipopt_model STATIC)
158+
target_sources(ipopt_model PRIVATE
159+
include/pyoptinterface/ipopt_model.hpp
160+
lib/ipopt_model.cpp
161+
)
162+
target_link_libraries(ipopt_model PUBLIC nlcore)
163+
164+
nanobind_add_module(
165+
ipopt_model_ext
166+
167+
STABLE_ABI NB_STATIC
168+
169+
lib/ipopt_model_ext.cpp
170+
)
171+
target_link_libraries(ipopt_model_ext PUBLIC ipopt_model)
172+
install(TARGETS ipopt_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})
173+
138174
set(ENABLE_TEST_MAIN OFF CACHE BOOL "Enable test c++ function with a main.cpp")
139175
if(ENABLE_TEST_MAIN)
140176
add_executable(test_main lib/main.cpp)

include/pyoptinterface/core.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ enum class ConstraintSense
271271
{
272272
LessEqual,
273273
GreaterEqual,
274-
Equal
274+
Equal,
275+
Within
275276
};
276277

277278
struct ConstraintIndex

include/pyoptinterface/highs_model.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class POIHighsModel
168168
std::int64_t get_raw_info_int64(const char *info_name);
169169
double get_raw_info_double(const char *info_name);
170170

171-
// Accessing information of problem
171+
// Accessing information of m_problem
172172
std::string get_variable_name(const VariableIndex &variable);
173173
void set_variable_name(const VariableIndex &variable, const char *name);
174174
VariableDomain get_variable_type(const VariableIndex &variable);
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#pragma once
2+
3+
#include "solvers/ipopt/IpStdCInterface.h"
4+
#include "pyoptinterface/nlcore.hpp"
5+
6+
#define APILIST \
7+
B(CreateIpoptProblem); \
8+
B(FreeIpoptProblem); \
9+
B(AddIpoptStrOption); \
10+
B(AddIpoptNumOption); \
11+
B(AddIpoptIntOption); \
12+
B(OpenIpoptOutputFile); \
13+
B(SetIpoptProblemScaling); \
14+
B(SetIntermediateCallback); \
15+
B(IpoptSolve); \
16+
B(GetIpoptCurrentIterate); \
17+
B(GetIpoptCurrentViolations);
18+
19+
namespace ipopt
20+
{
21+
#define B(f) extern decltype(&::f) f
22+
23+
APILIST
24+
25+
#undef B
26+
27+
bool is_library_loaded();
28+
29+
bool load_library(const std::string &path);
30+
} // namespace ipopt
31+
32+
struct IpoptfreeproblemT
33+
{
34+
void operator()(IpoptProblemInfo *model) const
35+
{
36+
ipopt::FreeIpoptProblem(model);
37+
};
38+
};
39+
40+
struct IpoptResult
41+
{
42+
// store results
43+
std::vector<double> x, g, mult_g, mult_x_L, mult_x_U;
44+
double obj_val;
45+
};
46+
47+
struct IpoptModel
48+
{
49+
/* Methods */
50+
IpoptModel();
51+
52+
VariableIndex add_variable(double lb = -INFINITY, double ub = INFINITY, double start = 0.0);
53+
void change_variable_lb(const VariableIndex &variable, double lb);
54+
void change_variable_ub(const VariableIndex &variable, double ub);
55+
void change_variable_bounds(const VariableIndex &variable, double lb, double ub);
56+
double get_variable_value(const VariableIndex &variable);
57+
58+
ParameterIndex add_parameter(double value = 0.0);
59+
void set_parameter(const ParameterIndex &parameter, double value);
60+
61+
ConstraintIndex add_linear_constraint(const ScalarAffineFunction &f, ConstraintSense sense,
62+
double rhs);
63+
ConstraintIndex add_linear_constraint(const ScalarAffineFunction &f, ConstraintSense sense,
64+
double lb, double ub);
65+
ConstraintIndex add_linear_constraint(const ExprBuilder &f, ConstraintSense sense, double rhs);
66+
ConstraintIndex add_linear_constraint(const ExprBuilder &f, ConstraintSense sense, double lb,
67+
double ub);
68+
ConstraintIndex add_linear_constraint(const VariableIndex &f, ConstraintSense sense,
69+
double rhs);
70+
ConstraintIndex add_linear_constraint(const VariableIndex &f, ConstraintSense sense, double lb,
71+
double ub);
72+
73+
ConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &f,
74+
ConstraintSense sense, double rhs);
75+
ConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &f,
76+
ConstraintSense sense, double lb, double ub);
77+
ConstraintIndex add_quadratic_constraint(const ExprBuilder &f, ConstraintSense sense,
78+
double rhs);
79+
ConstraintIndex add_quadratic_constraint(const ExprBuilder &f, ConstraintSense sense, double lb,
80+
double ub);
81+
82+
template <typename T>
83+
void add_objective(const T &expr)
84+
{
85+
m_lq_model.add_objective(expr);
86+
}
87+
88+
FunctionIndex register_function(ADFunD &f, const std::string &name);
89+
90+
NLConstraintIndex add_empty_nl_constraint(int dim, ConstraintSense sense,
91+
const std::vector<double> &rhss);
92+
NLConstraintIndex add_empty_nl_constraint(int dim, ConstraintSense sense,
93+
const std::vector<double> &lbs,
94+
const std::vector<double> &ubs);
95+
96+
NLConstraintIndex add_nl_constraint(const FunctionIndex &k,
97+
const std::vector<VariableIndex> &xs,
98+
const std::vector<ParameterIndex> &ps,
99+
ConstraintSense sense, const std::vector<double> &rhss);
100+
NLConstraintIndex add_nl_constraint(const FunctionIndex &k,
101+
const std::vector<VariableIndex> &xs, ConstraintSense sense,
102+
const std::vector<double> &rhss);
103+
104+
NLConstraintIndex add_nl_constraint(const FunctionIndex &k,
105+
const std::vector<VariableIndex> &xs,
106+
const std::vector<ParameterIndex> &ps,
107+
ConstraintSense sense, const std::vector<double> &lbs,
108+
const std::vector<double> &ubs);
109+
NLConstraintIndex add_nl_constraint(const FunctionIndex &k,
110+
const std::vector<VariableIndex> &xs, ConstraintSense sense,
111+
const std::vector<double> &lbs,
112+
const std::vector<double> &ubs);
113+
114+
void add_nl_expression(const NLConstraintIndex &constraint, const FunctionIndex &k,
115+
const std::vector<VariableIndex> &xs,
116+
const std::vector<ParameterIndex> &ps);
117+
void add_nl_expression(const NLConstraintIndex &constraint,const FunctionIndex &k,
118+
const std::vector<VariableIndex> &xs);
119+
120+
void add_nl_objective(const FunctionIndex &k, const std::vector<VariableIndex> &xs,
121+
const std::vector<ParameterIndex> &ps);
122+
123+
void optimize();
124+
125+
// set options
126+
void set_option_int(const std::string &name, int value);
127+
void set_option_num(const std::string &name, double value);
128+
void set_option_str(const std::string &name, const std::string &value);
129+
130+
/* Members */
131+
132+
size_t n_variables = 0;
133+
size_t n_constraints = 0;
134+
135+
std::vector<double> m_var_lb, m_var_ub, m_var_init;
136+
std::vector<double> m_con_lb, m_con_ub;
137+
138+
size_t m_jacobian_nnz = 0;
139+
std::vector<size_t> m_jacobian_rows, m_jacobian_cols;
140+
141+
size_t m_hessian_nnz = 0;
142+
std::vector<size_t> m_hessian_rows, m_hessian_cols;
143+
Hashmap<VariablePair, size_t> m_hessian_index_map;
144+
145+
NonlinearFunctionModel m_function_model;
146+
LinearQuadraticModel m_lq_model;
147+
148+
// The options of the Ipopt solver, we cache them before constructing the m_problem
149+
Hashmap<std::string, int> m_options_int;
150+
Hashmap<std::string, double> m_options_num;
151+
Hashmap<std::string, std::string> m_options_str;
152+
153+
IpoptResult m_result;
154+
enum ApplicationReturnStatus m_status;
155+
156+
std::unique_ptr<IpoptProblemInfo, IpoptfreeproblemT> m_problem = nullptr;
157+
};

0 commit comments

Comments
 (0)