Skip to content

Commit

Permalink
Mosek, COPT: enable convex QCP with rotated SOC #229 #192
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Jan 15, 2024
1 parent af15c5d commit 87bedd9
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
29 changes: 26 additions & 3 deletions include/mp/flat/redef/conic/qcones2qc.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class QConeConverter :
GetMC().NarrowVarBounds(x[0], 0.0, GetMC().Infty());
auto qc {QuadConLE{ {{}, {c, x, x}}, {0.0} }};
GetMC().AddConstraint(std::move(qc));
} else { // produce fixed RHS, better for Mosek
} else {
// Reproduce fixed RHS, better for Mosek & COPT. conic/socp_10
auto rhs = -c[0] * GetMC().fixed_value(x[0]);
c.erase(c.begin());
auto x0 = x;
Expand Down Expand Up @@ -85,8 +86,30 @@ class RQConeConverter :
c12[0] *= -2.0*c[0];
for (auto i=c12.size(); --i; )
c12[i] *= c12[i];
auto qc = QuadConLE{ {{}, {c12, x1, x2}}, {0.0} };
GetMC().AddConstraint(std::move(qc));
// Reproduce linear term, for Mosek & COPT. conic/socp_11.
if (GetMC().is_fixed(x1[0])) {
std::vector<double> clin
= { c12[0] * GetMC().fixed_value(x1[0]) };
std::vector<int> xlin = { x2[0] };
x1.erase(x1.begin());
x2.erase(x2.begin());
c12.erase(c12.begin());
GetMC().AddConstraint(
QuadConLE{ {{clin, xlin}, {c12, x1, x2}}, {0.0} });
} else
if (GetMC().is_fixed(x2[0])) {
std::vector<double> clin
= { c12[0] * GetMC().fixed_value(x2[0]) };
std::vector<int> xlin = { x1[0] };
x1.erase(x1.begin());
x2.erase(x2.begin());
c12.erase(c12.begin());
GetMC().AddConstraint(
QuadConLE{ {{clin, xlin}, {c12, x1, x2}}, {0.0} });
} else {
auto qc = QuadConLE{ {{}, {c12, x1, x2}}, {0.0} };
GetMC().AddConstraint(std::move(qc));
}
}

/// Reuse the stored ModelConverter
Expand Down
8 changes: 8 additions & 0 deletions test/end2end/cases/categorized/fast/conic/modellist.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@
"solve_result_num": 0
}
},
{
"name" : "socp_11_qpobj__RSOC",
"tags" : ["quadratic"],
"objective" : 27777.7949,
"values": {
"solve_result_num": 0
}
},
{
"name" : "expcones_01__plain",
"objective" : 0.7821882953,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This is actually convex quadratic, not conic,
# but we'd first conify, then QC-fy.
# Test that this works for Mosek 10:
# the linear term must be restored.

var x {1..7} >= 0;
minimize qobj: sum {j in 1..7} x[j]^2;
subj to qconstr: sum {j in 1..6} x[j]^2 <= 6*x[7] - 1000;
2 changes: 1 addition & 1 deletion test/end2end/scripts/python/Solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ def __init__(self, exeName, timeout=None, nthreads=None, otherOptions=None):
ModelTags.socp, ## MP transforms cones to quadratics
ModelTags.socp_hard_to_recognize,

ModelTags.writelp, ModelTags.writesol,
ModelTags.writelp,

}
super().__init__(exeName, timeout, nthreads, otherOptions, stags)
Expand Down

0 comments on commit 87bedd9

Please sign in to comment.