Skip to content

Commit 975d0e9

Browse files
committed
Implement creation of constraint with compare operators
1 parent fb7ef45 commit 975d0e9

File tree

12 files changed

+922
-182
lines changed

12 files changed

+922
-182
lines changed

include/pyoptinterface/core.hpp

Lines changed: 156 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -173,18 +173,18 @@ auto operator+(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction;
173173
auto operator+(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction;
174174
auto operator+(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarAffineFunction;
175175
auto operator+(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarAffineFunction;
176-
auto operator+(const ScalarAffineFunction &a, const ScalarAffineFunction &b)
177-
-> ScalarAffineFunction;
176+
auto operator+(const ScalarAffineFunction &a,
177+
const ScalarAffineFunction &b) -> ScalarAffineFunction;
178178
auto operator+(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction;
179179
auto operator+(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
180180
auto operator+(const ScalarQuadraticFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction;
181181
auto operator+(const VariableIndex &a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
182-
auto operator+(const ScalarQuadraticFunction &a, const ScalarAffineFunction &b)
183-
-> ScalarQuadraticFunction;
184-
auto operator+(const ScalarAffineFunction &a, const ScalarQuadraticFunction &b)
185-
-> ScalarQuadraticFunction;
186-
auto operator+(const ScalarQuadraticFunction &a, const ScalarQuadraticFunction &b)
187-
-> ScalarQuadraticFunction;
182+
auto operator+(const ScalarQuadraticFunction &a,
183+
const ScalarAffineFunction &b) -> ScalarQuadraticFunction;
184+
auto operator+(const ScalarAffineFunction &a,
185+
const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
186+
auto operator+(const ScalarQuadraticFunction &a,
187+
const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
188188

189189
auto operator-(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction;
190190
auto operator-(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction;
@@ -193,18 +193,18 @@ auto operator-(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction;
193193
auto operator-(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction;
194194
auto operator-(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarAffineFunction;
195195
auto operator-(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarAffineFunction;
196-
auto operator-(const ScalarAffineFunction &a, const ScalarAffineFunction &b)
197-
-> ScalarAffineFunction;
196+
auto operator-(const ScalarAffineFunction &a,
197+
const ScalarAffineFunction &b) -> ScalarAffineFunction;
198198
auto operator-(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction;
199199
auto operator-(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
200200
auto operator-(const ScalarQuadraticFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction;
201201
auto operator-(const VariableIndex &a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
202-
auto operator-(const ScalarQuadraticFunction &a, const ScalarAffineFunction &b)
203-
-> ScalarQuadraticFunction;
204-
auto operator-(const ScalarAffineFunction &a, const ScalarQuadraticFunction &b)
205-
-> ScalarQuadraticFunction;
206-
auto operator-(const ScalarQuadraticFunction &a, const ScalarQuadraticFunction &b)
207-
-> ScalarQuadraticFunction;
202+
auto operator-(const ScalarQuadraticFunction &a,
203+
const ScalarAffineFunction &b) -> ScalarQuadraticFunction;
204+
auto operator-(const ScalarAffineFunction &a,
205+
const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
206+
auto operator-(const ScalarQuadraticFunction &a,
207+
const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
208208

209209
auto operator*(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction;
210210
auto operator*(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction;
@@ -213,8 +213,8 @@ auto operator*(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction;
213213
auto operator*(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction;
214214
auto operator*(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction;
215215
auto operator*(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarQuadraticFunction;
216-
auto operator*(const ScalarAffineFunction &a, const ScalarAffineFunction &b)
217-
-> ScalarQuadraticFunction;
216+
auto operator*(const ScalarAffineFunction &a,
217+
const ScalarAffineFunction &b) -> ScalarQuadraticFunction;
218218
auto operator*(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction;
219219
auto operator*(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;
220220

@@ -229,7 +229,7 @@ auto operator-(const ScalarQuadraticFunction &a) -> ScalarQuadraticFunction;
229229
auto operator-(const ExprBuilder &a) -> ExprBuilder;
230230

231231
// Operator overloading for ExprBuilder
232-
// Sadly, they are inefficient than the add/sub/mul/div functions but they are important for a
232+
// Sadly, they are inefficient than the +=£¬-=,*=,/= functions but they are important for a
233233
// user-friendly interface
234234
// The functions are like ScalarQuadraticFunction but returns a ExprBuilder
235235
auto operator+(const ExprBuilder &a, CoeffT b) -> ExprBuilder;
@@ -298,6 +298,143 @@ struct ConstraintIndex
298298
}
299299
};
300300

301+
enum class ComparisonConstraintExprKind
302+
{
303+
ScalarAffineFunction,
304+
ScalarQuadraticFunction,
305+
ExprBuilder,
306+
ScalarAffineFunctionPointer,
307+
ScalarQuadraticFunctionPointer,
308+
ExprBuilderPointer,
309+
};
310+
311+
struct ComparisonConstraint
312+
{
313+
ConstraintSense sense;
314+
ComparisonConstraintExprKind expr_kind;
315+
ScalarAffineFunction lhs_saf;
316+
ScalarQuadraticFunction lhs_sqf;
317+
ExprBuilder lhs_eb;
318+
const ScalarAffineFunction *lhs_saf_ptr = nullptr;
319+
const ScalarQuadraticFunction *lhs_sqf_ptr = nullptr;
320+
const ExprBuilder *lhs_eb_ptr = nullptr;
321+
CoeffT rhs = 0.0;
322+
};
323+
324+
// <= Operator
325+
326+
auto operator<=(const VariableIndex &lhs, CoeffT rhs) -> ComparisonConstraint;
327+
auto operator<=(const ScalarAffineFunction &lhs, CoeffT rhs) -> ComparisonConstraint;
328+
auto operator<=(const ScalarQuadraticFunction &lhs, CoeffT rhs) -> ComparisonConstraint;
329+
auto operator<=(const ExprBuilder &lhs, CoeffT rhs) -> ComparisonConstraint;
330+
331+
auto operator<=(CoeffT lhs, const VariableIndex &rhs) -> ComparisonConstraint;
332+
auto operator<=(CoeffT lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
333+
auto operator<=(CoeffT lhs, const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
334+
auto operator<=(CoeffT lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
335+
336+
auto operator<=(const VariableIndex &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
337+
auto operator<=(const ScalarAffineFunction &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
338+
auto operator<=(const ScalarQuadraticFunction &lhs,
339+
const VariableIndex &rhs) -> ComparisonConstraint;
340+
341+
auto operator<=(const VariableIndex &lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
342+
auto operator<=(const ScalarAffineFunction &lhs,
343+
const ScalarAffineFunction &rhs) -> ComparisonConstraint;
344+
auto operator<=(const ScalarQuadraticFunction &lhs,
345+
const ScalarAffineFunction &rhs) -> ComparisonConstraint;
346+
347+
auto operator<=(const VariableIndex &lhs,
348+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
349+
auto operator<=(const ScalarAffineFunction &lhs,
350+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
351+
auto operator<=(const ScalarQuadraticFunction &lhs,
352+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
353+
354+
auto operator<=(const ExprBuilder &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
355+
auto operator<=(const ExprBuilder &lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
356+
auto operator<=(const ExprBuilder &lhs, const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
357+
auto operator<=(const VariableIndex &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
358+
auto operator<=(const ScalarAffineFunction &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
359+
auto operator<=(const ScalarQuadraticFunction &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
360+
auto operator<=(const ExprBuilder &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
361+
362+
// >= Operator
363+
364+
auto operator>=(const VariableIndex &lhs, CoeffT rhs) -> ComparisonConstraint;
365+
auto operator>=(const ScalarAffineFunction &lhs, CoeffT rhs) -> ComparisonConstraint;
366+
auto operator>=(const ScalarQuadraticFunction &lhs, CoeffT rhs) -> ComparisonConstraint;
367+
auto operator>=(const ExprBuilder &lhs, CoeffT rhs) -> ComparisonConstraint;
368+
369+
auto operator>=(CoeffT lhs, const VariableIndex &rhs) -> ComparisonConstraint;
370+
auto operator>=(CoeffT lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
371+
auto operator>=(CoeffT lhs, const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
372+
auto operator>=(CoeffT lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
373+
374+
auto operator>=(const VariableIndex &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
375+
auto operator>=(const ScalarAffineFunction &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
376+
auto operator>=(const ScalarQuadraticFunction &lhs,
377+
const VariableIndex &rhs) -> ComparisonConstraint;
378+
379+
auto operator>=(const VariableIndex &lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
380+
auto operator>=(const ScalarAffineFunction &lhs,
381+
const ScalarAffineFunction &rhs) -> ComparisonConstraint;
382+
auto operator>=(const ScalarQuadraticFunction &lhs,
383+
const ScalarAffineFunction &rhs) -> ComparisonConstraint;
384+
385+
auto operator>=(const VariableIndex &lhs,
386+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
387+
auto operator>=(const ScalarAffineFunction &lhs,
388+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
389+
auto operator>=(const ScalarQuadraticFunction &lhs,
390+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
391+
392+
auto operator>=(const ExprBuilder &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
393+
auto operator>=(const ExprBuilder &lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
394+
auto operator>=(const ExprBuilder &lhs, const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
395+
auto operator>=(const VariableIndex &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
396+
auto operator>=(const ScalarAffineFunction &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
397+
auto operator>=(const ScalarQuadraticFunction &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
398+
auto operator>=(const ExprBuilder &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
399+
400+
// == Operator
401+
402+
auto operator==(const VariableIndex &lhs, CoeffT rhs) -> ComparisonConstraint;
403+
auto operator==(const ScalarAffineFunction &lhs, CoeffT rhs) -> ComparisonConstraint;
404+
auto operator==(const ScalarQuadraticFunction &lhs, CoeffT rhs) -> ComparisonConstraint;
405+
auto operator==(const ExprBuilder &lhs, CoeffT rhs) -> ComparisonConstraint;
406+
407+
auto operator==(CoeffT lhs, const VariableIndex &rhs) -> ComparisonConstraint;
408+
auto operator==(CoeffT lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
409+
auto operator==(CoeffT lhs, const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
410+
auto operator==(CoeffT lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
411+
412+
auto operator==(const VariableIndex &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
413+
auto operator==(const ScalarAffineFunction &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
414+
auto operator==(const ScalarQuadraticFunction &lhs,
415+
const VariableIndex &rhs) -> ComparisonConstraint;
416+
417+
auto operator==(const VariableIndex &lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
418+
auto operator==(const ScalarAffineFunction &lhs,
419+
const ScalarAffineFunction &rhs) -> ComparisonConstraint;
420+
auto operator==(const ScalarQuadraticFunction &lhs,
421+
const ScalarAffineFunction &rhs) -> ComparisonConstraint;
422+
423+
auto operator==(const VariableIndex &lhs,
424+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
425+
auto operator==(const ScalarAffineFunction &lhs,
426+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
427+
auto operator==(const ScalarQuadraticFunction &lhs,
428+
const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
429+
430+
auto operator==(const ExprBuilder &lhs, const VariableIndex &rhs) -> ComparisonConstraint;
431+
auto operator==(const ExprBuilder &lhs, const ScalarAffineFunction &rhs) -> ComparisonConstraint;
432+
auto operator==(const ExprBuilder &lhs, const ScalarQuadraticFunction &rhs) -> ComparisonConstraint;
433+
auto operator==(const VariableIndex &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
434+
auto operator==(const ScalarAffineFunction &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
435+
auto operator==(const ScalarQuadraticFunction &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
436+
auto operator==(const ExprBuilder &lhs, const ExprBuilder &rhs) -> ComparisonConstraint;
437+
301438
// struct LinearConstraint
302439
//{
303440
// ScalarAffineFunction function;

include/pyoptinterface/ipopt_model.hpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "solvers/ipopt/IpStdCInterface.h"
44
#include "pyoptinterface/nleval.hpp"
55
#include "pyoptinterface/dylib.hpp"
6+
#include "pyoptinterface/solver_common.hpp"
67
#include <cmath>
78

89
#define APILIST \
@@ -60,14 +61,8 @@ struct IpoptModel
6061
void set_variable_name(const VariableIndex &variable, const std::string &name);
6162

6263
double get_variable_value(const VariableIndex &variable);
63-
double get_expression_value(const ScalarAffineFunction &function);
64-
double get_expression_value(const ScalarQuadraticFunction &function);
65-
double get_expression_value(const ExprBuilder &function);
6664

6765
std::string pprint_variable(const VariableIndex &variable);
68-
std::string pprint_expression(const ScalarAffineFunction &function, int precision = 4);
69-
std::string pprint_expression(const ScalarQuadraticFunction &function, int precision = 4);
70-
std::string pprint_expression(const ExprBuilder &function, int precision = 4);
7166

7267
ParameterIndex add_parameter(double value = 0.0);
7368
void set_parameter(const ParameterIndex &parameter, double value);
@@ -185,3 +180,5 @@ struct IpoptModel
185180

186181
std::unique_ptr<IpoptProblemInfo, IpoptfreeproblemT> m_problem = nullptr;
187182
};
183+
184+
using IpoptModelMixin = CommercialSolverMixin<IpoptModel>;

include/pyoptinterface/solver_common.hpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class CommercialSolverMixin : public T
4747
ConstraintSense sense, CoeffT rhs,
4848
const char *name = nullptr);
4949

50+
ConstraintIndex add_linear_constraint_from_comparison(const ComparisonConstraint &constraint,
51+
const char *name = nullptr);
52+
ConstraintIndex add_quadratic_constraint_from_comparison(const ComparisonConstraint &constraint,
53+
const char *name = nullptr);
54+
5055
double get_expression_value(const ScalarAffineFunction &function);
5156
double get_expression_value(const ScalarQuadraticFunction &function);
5257
double get_expression_value(const ExprBuilder &function);
@@ -89,6 +94,66 @@ ConstraintIndex CommercialSolverMixin<T>::add_quadratic_constraint_from_expr(
8994
return get_base()->add_quadratic_constraint(f, sense, rhs, name);
9095
}
9196

97+
template <CommercialSolverConstraint T>
98+
inline ConstraintIndex CommercialSolverMixin<T>::add_linear_constraint_from_comparison(
99+
const ComparisonConstraint &constraint, const char *name)
100+
{
101+
auto expr_kind = constraint.expr_kind;
102+
switch (expr_kind)
103+
{
104+
case ComparisonConstraintExprKind::ScalarAffineFunction:
105+
return get_base()->add_linear_constraint(constraint.lhs_saf, constraint.sense,
106+
constraint.rhs, name);
107+
break;
108+
case ComparisonConstraintExprKind::ScalarAffineFunctionPointer:
109+
return get_base()->add_linear_constraint(*constraint.lhs_saf_ptr, constraint.sense,
110+
constraint.rhs, name);
111+
break;
112+
case ComparisonConstraintExprKind::ScalarQuadraticFunction:
113+
case ComparisonConstraintExprKind::ScalarQuadraticFunctionPointer:
114+
throw std::runtime_error("Quadratic expression cannot be added as linear constraints");
115+
break;
116+
case ComparisonConstraintExprKind::ExprBuilder:
117+
return add_linear_constraint_from_expr(constraint.lhs_eb, constraint.sense, constraint.rhs,
118+
name);
119+
break;
120+
case ComparisonConstraintExprKind::ExprBuilderPointer:
121+
return add_linear_constraint_from_expr(*constraint.lhs_eb_ptr, constraint.sense,
122+
constraint.rhs, name);
123+
break;
124+
}
125+
}
126+
127+
template <CommercialSolverConstraint T>
128+
inline ConstraintIndex CommercialSolverMixin<T>::add_quadratic_constraint_from_comparison(
129+
const ComparisonConstraint &constraint, const char *name)
130+
{
131+
auto expr_kind = constraint.expr_kind;
132+
switch (expr_kind)
133+
{
134+
case ComparisonConstraintExprKind::ScalarAffineFunction:
135+
case ComparisonConstraintExprKind::ScalarAffineFunctionPointer:
136+
throw std::runtime_error("Linear expression cannot be added as quadratic constraints");
137+
break;
138+
case ComparisonConstraintExprKind::ScalarQuadraticFunction:
139+
return get_base()->add_quadratic_constraint(constraint.lhs_sqf, constraint.sense,
140+
constraint.rhs, name);
141+
break;
142+
case ComparisonConstraintExprKind::ScalarQuadraticFunctionPointer:
143+
return get_base()->add_quadratic_constraint(*constraint.lhs_sqf_ptr, constraint.sense,
144+
constraint.rhs, name);
145+
break;
146+
case ComparisonConstraintExprKind::ExprBuilder:
147+
return add_quadratic_constraint_from_expr(constraint.lhs_eb, constraint.sense,
148+
constraint.rhs, name);
149+
break;
150+
case ComparisonConstraintExprKind::ExprBuilderPointer:
151+
return add_quadratic_constraint_from_expr(*constraint.lhs_eb_ptr, constraint.sense,
152+
constraint.rhs, name);
153+
break;
154+
}
155+
}
156+
92157
template <typename T>
93158
double get_affine_expression_value(T *model, const ScalarAffineFunction &function)
94159
{

0 commit comments

Comments
 (0)