Skip to content

Commit 584e050

Browse files
authored
Add default fallbacks for head and vexity with MOI sets (#632)
1 parent f2b37dd commit 584e050

File tree

2 files changed

+55
-64
lines changed

2 files changed

+55
-64
lines changed

src/constraints/GenericConstraint.jl

Lines changed: 39 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ end
3232

3333
head(io::IO, c::GenericConstraint) = head(io, c.set)
3434

35+
function head(io::IO, set::MOI.AbstractSet)
36+
return print(io, replace("$(typeof(set))", "MathOptInterface" => "MOI"))
37+
end
38+
3539
AbstractTrees.children(c::GenericConstraint) = (c.child,)
3640

3741
# A fallback. Define a new method if `MOI.Utilities.distance_to_set`
@@ -46,6 +50,40 @@ end
4650

4751
vexity(c::GenericConstraint) = vexity(vexity(c.child), c.set)
4852

53+
function vexity(
54+
vex,
55+
# An enumeration of sets that are most likely to be used by Convex.jl
56+
::Union{
57+
MOI.SecondOrderCone,
58+
MOI.RotatedSecondOrderCone,
59+
MOI.ExponentialCone,
60+
MOI.DualExponentialCone,
61+
MOI.PowerCone,
62+
MOI.DualPowerCone,
63+
MOI.PositiveSemidefiniteConeSquare,
64+
MOI.GeometricMeanCone,
65+
MOI.NormCone,
66+
MOI.NormInfinityCone,
67+
MOI.NormOneCone,
68+
MOI.NormSpectralCone,
69+
MOI.NormNuclearCone,
70+
MOI.RelativeEntropyCone,
71+
MOI.LogDetConeSquare,
72+
MOI.RootDetConeSquare,
73+
},
74+
)
75+
if !(vex == ConstVexity() || vex == AffineVexity())
76+
return NotDcp()
77+
end
78+
return ConvexVexity()
79+
end
80+
81+
function vexity(::Any, set::MOI.AbstractSet)
82+
return error(
83+
"`Convex.vexity(vex, ::$(typeof(set)))`: is not yet implemented. Please open an issue at https://github.com/jump-dev/Convex.jl",
84+
)
85+
end
86+
4987
function _add_constraint!(context::Context, c::GenericConstraint)
5088
if vexity(c.child) == ConstVexity()
5189
if !is_feasible(evaluate(c.child), c.set, CONSTANT_CONSTRAINT_TOL[])
@@ -201,14 +239,7 @@ function set_with_size(
201239
return MOI.PositiveSemidefiniteConeSquare(sz[1])
202240
end
203241

204-
head(io::IO, ::MOI.PositiveSemidefiniteConeSquare) = print(io, "sdp")
205-
206-
function vexity(vex, ::MOI.PositiveSemidefiniteConeSquare)
207-
if !(vex in (AffineVexity(), ConstVexity()))
208-
return NotDcp()
209-
end
210-
return AffineVexity()
211-
end
242+
head(io::IO, ::MOI.PositiveSemidefiniteConeSquare) = print(io, "PSD")
212243

213244
function is_feasible(x, ::MOI.PositiveSemidefiniteConeSquare, tol)
214245
return x transpose(x) && LinearAlgebra.eigmin(x) >= -tol
@@ -244,55 +275,3 @@ end
244275
(x::Value, y::AbstractExpr) = (y, x)
245276

246277
(x::AbstractExpr, y::Value) = (y, x)
247-
248-
# ==============================================================================
249-
# ExponentialCone
250-
# ==============================================================================
251-
252-
head(io::IO, ::MOI.ExponentialCone) = print(io, "exp")
253-
254-
function vexity(vex, ::MOI.ExponentialCone)
255-
if !(vex == ConstVexity() || vex == AffineVexity())
256-
return NotDcp()
257-
end
258-
return ConvexVexity()
259-
end
260-
261-
# ==============================================================================
262-
# SecondOrderCone
263-
# ==============================================================================
264-
265-
head(io::IO, ::MOI.SecondOrderCone) = print(io, "soc")
266-
267-
function vexity(vex, ::MOI.SecondOrderCone)
268-
if !(vex == ConstVexity() || vex == AffineVexity())
269-
return NotDcp()
270-
end
271-
return ConvexVexity()
272-
end
273-
274-
# ==============================================================================
275-
# RotatedSecondOrderCone
276-
# ==============================================================================
277-
278-
head(io::IO, ::MOI.RotatedSecondOrderCone) = print(io, "rsoc")
279-
280-
function vexity(vex, ::MOI.RotatedSecondOrderCone)
281-
if !(vex == ConstVexity() || vex == AffineVexity())
282-
return NotDcp()
283-
end
284-
return ConvexVexity()
285-
end
286-
287-
# ==============================================================================
288-
# RelativeEntropyCone
289-
# ==============================================================================
290-
291-
head(io::IO, ::MOI.RelativeEntropyCone) = print(io, "RelativeEntropyCone")
292-
293-
function vexity(vex, ::MOI.RelativeEntropyCone)
294-
if !(vex == ConstVexity() || vex == AffineVexity())
295-
return NotDcp()
296-
end
297-
return ConvexVexity()
298-
end

test/test_constraints.jl

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ function test_GenericConstraint_SecondOrderCone()
220220
@test isapprox(c.dual, [1, -2 / t_, -3 / t_, -4 / t_]; atol = 1e-3)
221221
c = Convex.GenericConstraint{MOI.SecondOrderCone}(vcat(square(t), x))
222222
@test vexity(c) === Convex.NotDcp()
223-
@test Convex.sprint(Convex.head, c) == "soc"
223+
@test Convex.sprint(Convex.head, c) == "MOI.SecondOrderCone"
224224
return
225225
end
226226

@@ -251,7 +251,7 @@ function test_GenericConstraint_RotatedSecondOrderCone()
251251
@test isapprox(c.dual, [1, 29 / 2, -2, -3, -4]; atol = 1e-3)
252252
c = Convex.GenericConstraint{MOI.RotatedSecondOrderCone}(vcat(square(t), x))
253253
@test vexity(c) === Convex.NotDcp()
254-
@test Convex.sprint(Convex.head, c) == "rsoc"
254+
@test Convex.sprint(Convex.head, c) == "MOI.RotatedSecondOrderCone"
255255
return
256256
end
257257

@@ -275,7 +275,7 @@ function test_GenericConstraint_ExponentialConeConstraint()
275275
@test isapprox(c.dual, [-exp(3 / 2), exp(3 / 2) / 2, 1]; atol = 1e-4)
276276
c = Convex.GenericConstraint{MOI.ExponentialCone}(vcat(square(z), 1, z))
277277
@test vexity(c) === Convex.NotDcp()
278-
@test sprint(Convex.head, c) == "exp"
278+
@test sprint(Convex.head, c) == "MOI.ExponentialCone"
279279
return
280280
end
281281

@@ -293,7 +293,19 @@ function test_GenericConstraint_RelativeEntropyConeConstraint()
293293
@test isapprox(c.dual, [1, 2, 1, -log(2) - 1, -1]; atol = 1e-3)
294294
c = Convex.GenericConstraint{MOI.RelativeEntropyCone}(vcat(square(u), 1, u))
295295
@test vexity(c) === Convex.NotDcp()
296-
@test sprint(Convex.head, c) == "RelativeEntropyCone"
296+
@test sprint(Convex.head, c) == "MOI.RelativeEntropyCone"
297+
return
298+
end
299+
300+
function test_GenericConstraint_NoVexity()
301+
x = Variable(2)
302+
set = MOI.Complements(2)
303+
@test_throws(
304+
ErrorException(
305+
"`Convex.vexity(vex, ::$(typeof(set)))`: is not yet implemented. Please open an issue at https://github.com/jump-dev/Convex.jl",
306+
),
307+
vexity(Convex.GenericConstraint(x, set)),
308+
)
297309
return
298310
end
299311

0 commit comments

Comments
 (0)