Skip to content

Commit 2a86034

Browse files
authored
Merge pull request #993 from chriscoey/addrelativeentropycone
add relative entropy cone
2 parents c6db50d + 21b9dca commit 2a86034

File tree

17 files changed

+332
-8
lines changed

17 files changed

+332
-8
lines changed

docs/src/apimanual.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ sets recognized by the solver.
9292
``\{ x \in \mathbb{R}^\mbox{dimension} : x \ge 0 \}``
9393
* **[`Nonpositives(dimension)`](@ref MathOptInterface.Nonpositives)**:
9494
``\{ x \in \mathbb{R}^\mbox{dimension} : x \le 0 \}``
95+
* **[`NormInfinityCone(dimension)`](@ref MathOptInterface.NormInfinityCone)**:
96+
``\{ (t,x) \\in \\mathbb{R}^\mbox{dimension} : t \\ge \\lVert x \\rVert_\\infty = \\max_i \\lvert x_i \\rvert \}``
97+
* **[`NormOneCone(dimension)`](@ref MathOptInterface.NormOneCone)**:
98+
``\{ (t,x) \\in \\mathbb{R}^\mbox{dimension} : t \\ge \\lVert x \\rVert_\\infty_1 = \\sum_i \\lvert x_i \\rvert \}``
9599
* **[`SecondOrderCone(dimension)`](@ref MathOptInterface.SecondOrderCone)**:
96100
``\{ (t,x) \in \mathbb{R}^\mbox{dimension} : t \ge ||x||_2 \}``
97101
* **[`RotatedSecondOrderCone(dimension)`](@ref MathOptInterface.RotatedSecondOrderCone)**:
@@ -108,8 +112,10 @@ sets recognized by the solver.
108112
* **[`DualPowerCone(exponent)`](@ref MathOptInterface.DualPowerCone)**:
109113
``\{ (u,v,w) \in \mathbb{R}^3 : \frac{u}{\mbox{exponent}}^\mbox{exponent}
110114
\frac{v}{1-\mbox{exponent}}^{1-\mbox{exponent}} \ge |w|, u,v \ge 0 \}``
115+
* **[`RelativeEntropyCone(dimension)`](@ref MathOptInterface.RelativeEntropyCone)**:
116+
``\{ (u, v, w) \\in \\mathbb{R}^\mbox{dimension} : u \\ge \\sum_i w_i \\log (\\frac{w_i}{v_i}), v_i \\ge 0, w_i \\ge 0 \}``
111117
* **[`NormSpectralCone(row_dim, column_dim)`](@ref MathOptInterface.NormSpectralCone)**:
112-
``\{ (t, X) \in \mathbb{R}^{1 + \mbox{row_dim} \times \mbox{column_dim} : t \ge \sigma_1(X), X \mbox{is a matrix with row_dim rows and column_dim columns} \}``
118+
``\{ (t, X) \in \mathbb{R}^{1 + \mbox{row_dim} \times \mbox{column_dim} : t \ge \sigma_1(X), X \mbox{is a matrix with row_dim rows and column_dim columns} \}``
113119
* **[`NormNuclearCone(row_dim, column_dim)`](@ref MathOptInterface.NormNuclearCone)**:
114120
``\{ (t, X) \in \mathbb{R}^{1 + \mbox{row_dim} \times \mbox{column_dim} : t \ge \sum_i \sigma_i(X), X \mbox{is a matrix with row_dim rows and column_dim columns} \}``
115121
* **[`PositiveSemidefiniteConeTriangle(dimension)`](@ref MathOptInterface.PositiveSemidefiniteConeTriangle)**:

docs/src/apireference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ ExponentialCone
346346
DualExponentialCone
347347
PowerCone
348348
DualPowerCone
349+
RelativeEntropyCone
349350
NormSpectralCone
350351
NormNuclearCone
351352
SOS1
@@ -753,6 +754,7 @@ Bridges.Constraint.QuadtoSOCBridge
753754
Bridges.Constraint.NormInfinityBridge
754755
Bridges.Constraint.NormOneBridge
755756
Bridges.Constraint.GeoMeanBridge
757+
Bridges.Constraint.RelativeEntropyBridge
756758
Bridges.Constraint.NormSpectralBridge
757759
Bridges.Constraint.NormNuclearBridge
758760
Bridges.Constraint.SquareBridge

src/Bridges/Constraint/Constraint.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const NormInfinity{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{NormInfinityBri
4646
const NormOne{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{NormOneBridge{T}, OT}
4747
include("geomean.jl")
4848
const GeoMean{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{GeoMeanBridge{T}, OT}
49+
include("relentr_to_exp.jl")
50+
const RelativeEntropy{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{RelativeEntropyBridge{T}, OT}
4951
include("norm_spec_nuc_to_psd.jl")
5052
const NormSpectral{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{NormSpectralBridge{T}, OT}
5153
const NormNuclear{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{NormNuclearBridge{T}, OT}
@@ -83,6 +85,7 @@ function add_all_bridges(bridged_model, ::Type{T}) where {T}
8385
MOIB.add_bridge(bridged_model, NormInfinityBridge{T})
8486
MOIB.add_bridge(bridged_model, NormOneBridge{T})
8587
MOIB.add_bridge(bridged_model, GeoMeanBridge{T})
88+
MOIB.add_bridge(bridged_model, RelativeEntropyBridge{T})
8689
MOIB.add_bridge(bridged_model, NormSpectralBridge{T})
8790
MOIB.add_bridge(bridged_model, NormNuclearBridge{T})
8891
MOIB.add_bridge(bridged_model, SquareBridge{T})

src/Bridges/Constraint/norm_to_lp.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct NormOneBridge{T, F, G, H} <: AbstractBridge
7575
ge_index::CI{F, MOI.GreaterThan{T}}
7676
nn_index::CI{G, MOI.Nonnegatives}
7777
end
78-
function bridge_constraint(::Type{NormOneBridge{T, F, G, H}}, model::MOI.ModelLike, f::MOI.AbstractVectorFunction, s::MOI.NormOneCone) where {T, F, G, H}
78+
function bridge_constraint(::Type{NormOneBridge{T, F, G, H}}, model::MOI.ModelLike, f::H, s::MOI.NormOneCone) where {T, F, G, H}
7979
f_scalars = MOIU.eachscalar(f)
8080
d = MOI.dimension(s)
8181
y = MOI.add_variables(model, d - 1)
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
"""
2+
RelativeEntropyBridge{T}
3+
4+
The `RelativeEntropyCone` is representable with exponential cone and LP constraints, since
5+
``u \\ge \\sum_{i=1}^n w_i \\log (\\frac{w_i}{v_i})`` if and only if there exists a vector
6+
``y`` such that ``u \\ge \\sum_i y_i`` and ``y_i \\ge w_i \\log (\\frac{w_i}{v_i})`` or
7+
equivalently ``v_i \\ge w_i \\exp (\\frac{-y_i}{w_i})`` or equivalently
8+
``(-y_i, w_i, v_i) \\in ExponentialCone``, for all ``i``.
9+
"""
10+
struct RelativeEntropyBridge{T, F, G, H} <: AbstractBridge
11+
y::Vector{MOI.VariableIndex}
12+
ge_index::CI{F, MOI.GreaterThan{T}}
13+
exp_indices::Vector{CI{G, MOI.ExponentialCone}}
14+
end
15+
function bridge_constraint(::Type{RelativeEntropyBridge{T, F, G, H}}, model::MOI.ModelLike, f::H, s::MOI.RelativeEntropyCone) where {T, F, G, H}
16+
f_scalars = MOIU.eachscalar(f)
17+
d = MOI.dimension(s)
18+
v_dim = div(d - 1, 2)
19+
y = MOI.add_variables(model, v_dim)
20+
ge_index = MOIU.normalize_and_add_constraint(model, MOIU.operate(-, T, f_scalars[1], MOIU.operate(sum, T, y)), MOI.GreaterThan(zero(T)), allow_modify_function=true)
21+
w_start = 1 + v_dim
22+
exp_funcs = [MOIU.operate(vcat, T, MOIU.operate(-, T, MOI.SingleVariable(y[i])), f_scalars[w_start + i], f_scalars[1 + i]) for i in 1:v_dim]
23+
exp_indices = [MOI.add_constraint(model, exp_func_i, MOI.ExponentialCone()) for exp_func_i in exp_funcs]
24+
return RelativeEntropyBridge{T, F, G, H}(y, ge_index, exp_indices)
25+
end
26+
27+
MOI.supports_constraint(::Type{RelativeEntropyBridge{T}}, ::Type{<:MOI.AbstractVectorFunction}, ::Type{MOI.RelativeEntropyCone}) where T = true
28+
MOIB.added_constrained_variable_types(::Type{<:RelativeEntropyBridge}) = Tuple{DataType}[]
29+
MOIB.added_constraint_types(::Type{RelativeEntropyBridge{T, F, G, H}}) where {T, F, G, H} = [(F, MOI.GreaterThan{T}), (G, MOI.ExponentialCone)]
30+
function concrete_bridge_type(::Type{<:RelativeEntropyBridge{T}}, H::Type{<:MOI.AbstractVectorFunction}, ::Type{MOI.RelativeEntropyCone}) where T
31+
S = MOIU.scalar_type(H)
32+
F = MOIU.promote_operation(-, T, S, S)
33+
G = MOIU.promote_operation(vcat, T, MOIU.promote_operation(-, T, MOI.SingleVariable), S)
34+
return RelativeEntropyBridge{T, F, G, H}
35+
end
36+
37+
# Attributes, Bridge acting as a model
38+
MOI.get(bridge::RelativeEntropyBridge, ::MOI.NumberOfVariables) = length(bridge.y)
39+
MOI.get(bridge::RelativeEntropyBridge, ::MOI.ListOfVariableIndices) = bridge.y
40+
MOI.get(bridge::RelativeEntropyBridge{T, F, G, H}, ::MOI.NumberOfConstraints{F, MOI.GreaterThan{T}}) where {T, F, G, H} = 1
41+
MOI.get(bridge::RelativeEntropyBridge{T, F, G, H}, ::MOI.NumberOfConstraints{G, MOI.ExponentialCone}) where {T, F, G, H} = length(bridge.y)
42+
MOI.get(bridge::RelativeEntropyBridge{T, F, G, H}, ::MOI.ListOfConstraintIndices{F, MOI.GreaterThan{T}}) where {T, F, G, H} = [bridge.ge_index]
43+
MOI.get(bridge::RelativeEntropyBridge{T, F, G, H}, ::MOI.ListOfConstraintIndices{G, MOI.ExponentialCone}) where {T, F, G, H} = bridge.exp_indices
44+
45+
# References
46+
function MOI.delete(model::MOI.ModelLike, bridge::RelativeEntropyBridge)
47+
for exp_index_i in bridge.exp_indices
48+
MOI.delete(model, exp_index_i)
49+
end
50+
MOI.delete(model, bridge.ge_index)
51+
MOI.delete(model, bridge.y)
52+
end
53+
54+
# Attributes, Bridge acting as a constraint
55+
function MOI.get(model::MOI.ModelLike, ::MOI.ConstraintFunction, bridge::RelativeEntropyBridge{T, F, G, H}) where {T, F, G, H}
56+
func = MOIU.zero_with_output_dimension(G, 1 + 2 * length(bridge.y))
57+
MOIU.operate_output_index!(+, T, 1, func, MOI.get(model, MOI.ConstraintFunction(), bridge.ge_index))
58+
w_start = 1 + length(bridge.y)
59+
for i in eachindex(bridge.y)
60+
exp_func_i = MOIU.eachscalar(MOI.get(model, MOI.ConstraintFunction(), bridge.exp_indices[i]))
61+
MOIU.operate_output_index!(-, T, 1, func, exp_func_i[1])
62+
MOIU.operate_output_index!(+, T, 1 + i, func, exp_func_i[3])
63+
MOIU.operate_output_index!(+, T, w_start + i, func, exp_func_i[2])
64+
end
65+
return MOIU.convert_approx(H, MOIU.remove_variable(func, bridge.y))
66+
end
67+
MOI.get(model::MOI.ModelLike, ::MOI.ConstraintSet, bridge::RelativeEntropyBridge) = MOI.RelativeEntropyCone(1 + 2 * length(bridge.y))
68+
MOI.supports(::MOI.ModelLike, ::Union{MOI.ConstraintPrimalStart, MOI.ConstraintDualStart}, ::Type{<:RelativeEntropyBridge}) = true
69+
function MOI.get(model::MOI.ModelLike, attr::Union{MOI.ConstraintPrimal, MOI.ConstraintPrimalStart}, bridge::RelativeEntropyBridge{T}) where T
70+
primal = zeros(T, 1 + 2 * length(bridge.y))
71+
primal[1] = MOI.get(model, attr, bridge.ge_index)
72+
w_start = 1 + length(bridge.y)
73+
for i in eachindex(bridge.y)
74+
exp_primal_i = MOI.get(model, attr, bridge.exp_indices[i])
75+
primal[1] -= exp_primal_i[1]
76+
primal[1 + i] = exp_primal_i[3]
77+
primal[w_start + i] = exp_primal_i[2]
78+
end
79+
return primal
80+
end
81+
function MOI.set(model::MOI.ModelLike, attr::MOI.ConstraintPrimalStart, bridge::RelativeEntropyBridge{T}, value) where T
82+
v_dim = length(bridge.y)
83+
v_value = value[2:(v_dim + 1)]
84+
w_value = value[(v_dim + 2):end]
85+
y_value = [w_i * log(w_i / v_i) for (v_i, w_i) in zip(v_value, w_value)]
86+
MOI.set(model, attr, bridge.ge_index, value[1] - reduce(+, y_value, init=zero(T)))
87+
for i in 1:v_dim
88+
MOI.set(model, attr, bridge.exp_indices[i], [-y_value[i], w_value[i], v_value[i]])
89+
MOI.set(model, MOI.VariablePrimalStart(), bridge.y[i], y_value[i])
90+
end
91+
return
92+
end
93+
# Given a is dual on u - sum(y) >= 0 and (b_i, c_i, d_i) is dual on (-y_i, w_i, v_i)
94+
# in ExponentialCone, the dual on (u, v, w) in RelativeEntropyCone is (a, d_i, c_i).
95+
function MOI.get(model::MOI.ModelLike, attr::Union{MOI.ConstraintDual, MOI.ConstraintDualStart}, bridge::RelativeEntropyBridge{T}) where {T}
96+
dual = zeros(T, 1 + 2 * length(bridge.y))
97+
dual[1] = MOI.get(model, attr, bridge.ge_index)[1]
98+
w_start = 1 + length(bridge.y)
99+
for i in eachindex(bridge.y)
100+
exp_dual_i = MOI.get(model, attr, bridge.exp_indices[i])
101+
dual[1 + i] = exp_dual_i[3]
102+
dual[w_start + i] = exp_dual_i[2]
103+
end
104+
return dual
105+
end
106+
# Given constraint dual start of (u, v, w), constraint dual on GreaterThan is u
107+
# and on exponential cone constraint i is (r_i, w_i, v_i), but since y_i is free,
108+
# its dual is 0, so we have -r_i + value[1] == 0 hence r_i = value[1].
109+
# Note: alternatively, we could use the Lambert W function to calculate
110+
# r_i = exp(W(-w_i / (-v_i * e))) * (-v_i * e), but this is more complicated.
111+
function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintDualStart, bridge::RelativeEntropyBridge, value)
112+
MOI.set(model, MOI.ConstraintDualStart(), bridge.ge_index, value[1])
113+
w_start = 1 + length(bridge.y)
114+
for i in eachindex(bridge.y)
115+
MOI.set(model, MOI.ConstraintDualStart(), bridge.exp_indices[i], [value[1], value[w_start + i], value[1 + i]])
116+
end
117+
return
118+
end

src/FileFormats/MOF/MOF.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ MOI.Utilities.@model(InnerModel,
3030
(MOI.EqualTo, MOI.GreaterThan, MOI.LessThan, MOI.Interval,
3131
MOI.Semicontinuous, MOI.Semiinteger),
3232
(MOI.Reals, MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives,
33-
MOI.SecondOrderCone, MOI.RotatedSecondOrderCone, MOI.GeometricMeanCone, MOI.ExponentialCone, MOI.DualExponentialCone, MOI.NormOneCone,
33+
MOI.SecondOrderCone, MOI.RotatedSecondOrderCone, MOI.GeometricMeanCone,
34+
MOI.ExponentialCone, MOI.DualExponentialCone, MOI.NormOneCone,
3435
MOI.NormInfinityCone, MOI.NormSpectralCone, MOI.NormNuclearCone,
35-
MOI.RootDetConeTriangle, MOI.RootDetConeSquare,
36+
MOI.RelativeEntropyCone, MOI.RootDetConeTriangle, MOI.RootDetConeSquare,
3637
MOI.LogDetConeTriangle, MOI.LogDetConeSquare,
3738
MOI.PositiveSemidefiniteConeTriangle, MOI.PositiveSemidefiniteConeSquare),
3839
(MOI.PowerCone, MOI.DualPowerCone, MOI.SOS1, MOI.SOS2),

src/FileFormats/MOF/read.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ end
307307
set_info(::Type{Val{:GeometricMeanCone}}) = (MOI.GeometricMeanCone, "dimension")
308308
set_info(::Type{Val{:NormOneCone}}) = (MOI.NormOneCone, "dimension")
309309
set_info(::Type{Val{:NormInfinityCone}}) = (MOI.NormInfinityCone, "dimension")
310+
set_info(::Type{Val{:RelativeEntropyCone}}) = (MOI.RelativeEntropyCone, "dimension")
310311
set_info(::Type{Val{:NormSpectralCone}}) = (MOI.NormSpectralCone, "row_dim", "column_dim")
311312
set_info(::Type{Val{:NormNuclearCone}}) = (MOI.NormNuclearCone, "row_dim", "column_dim")
312313
function set_info(::Type{Val{:RootDetConeTriangle}})

src/FileFormats/MOF/v0.4.0.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,19 @@
812812
"minimum": 2
813813
}
814814
}
815+
}, {
816+
"description": "(u, v, w) ∈ {R^{dimension}: u ≥ sumᵢ wᵢlog(wᵢ/vᵢ), vᵢ ≥ 0, wᵢ ≥ 0}",
817+
"examples": ["{\"head\": \"RelativeEntropyCone\", \"dimension\": 3}"],
818+
"required": ["dimension"],
819+
"properties": {
820+
"head": {
821+
"const": "RelativeEntropyCone"
822+
},
823+
"dimension": {
824+
"type": "integer",
825+
"minimum": 3
826+
}
827+
}
815828
}, {
816829
"description": "(t, X) ∈ {R^{1+row_dim×column_dim}: t ≥ σ₁(X)}",
817830
"examples": ["{\"head\": \"NormSpectralCone\", \"row_dim\": 1, \"column_dim\": 2}"],

src/FileFormats/MOF/write.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ head_name(::Type{MOI.ExponentialCone}) = "ExponentialCone"
238238
head_name(::Type{MOI.DualExponentialCone}) = "DualExponentialCone"
239239
head_name(::Type{MOI.NormOneCone}) = "NormOneCone"
240240
head_name(::Type{MOI.NormInfinityCone}) = "NormInfinityCone"
241+
head_name(::Type{MOI.RelativeEntropyCone}) = "RelativeEntropyCone"
241242
head_name(::Type{MOI.NormSpectralCone}) = "NormSpectralCone"
242243
head_name(::Type{MOI.NormNuclearCone}) = "NormNuclearCone"
243244
head_name(::Type{MOI.RootDetConeTriangle}) = "RootDetConeTriangle"

src/Test/UnitTests/basic_constraint_tests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const BasicConstraintTests = Dict(
4343
(MOI.VectorOfVariables, MOI.DualExponentialCone) => ( dummy_vectorofvariables, 3, MOI.DualExponentialCone() ),
4444
(MOI.VectorOfVariables, MOI.PowerCone{Float64}) => ( dummy_vectorofvariables, 3, MOI.PowerCone(0.5) ),
4545
(MOI.VectorOfVariables, MOI.DualPowerCone{Float64}) => ( dummy_vectorofvariables, 3, MOI.DualPowerCone(0.5) ),
46+
(MOI.VectorOfVariables, MOI.RelativeEntropyCone) => ( dummy_vectorofvariables, 3, MOI.RelativeEntropyCone(3) ),
4647
(MOI.VectorOfVariables, MOI.NormSpectralCone) => ( dummy_vectorofvariables, 7, MOI.NormSpectralCone(2, 3) ),
4748
(MOI.VectorOfVariables, MOI.NormNuclearCone) => ( dummy_vectorofvariables, 7, MOI.NormNuclearCone(2, 3) ),
4849
(MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle) => ( dummy_vectorofvariables, 6, MOI.PositiveSemidefiniteConeTriangle(3) ),
@@ -72,6 +73,7 @@ const BasicConstraintTests = Dict(
7273
(MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone) => ( dummy_vector_affine, 3, MOI.SecondOrderCone(3) ),
7374
(MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone) => ( dummy_vector_affine, 3, MOI.RotatedSecondOrderCone(3) ),
7475
(MOI.VectorAffineFunction{Float64}, MOI.GeometricMeanCone) => ( dummy_vector_affine, 3, MOI.GeometricMeanCone(3) ),
76+
(MOI.VectorAffineFunction{Float64}, MOI.RelativeEntropyCone) => ( dummy_vector_affine, 3, MOI.RelativeEntropyCone(3) ),
7577
(MOI.VectorAffineFunction{Float64}, MOI.NormSpectralCone) => ( dummy_vector_affine, 7, MOI.NormSpectralCone(2, 3) ),
7678
(MOI.VectorAffineFunction{Float64}, MOI.NormNuclearCone) => ( dummy_vector_affine, 7, MOI.NormNuclearCone(2, 3) ),
7779
(MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeSquare) => ( dummy_vector_affine, 9, MOI.PositiveSemidefiniteConeSquare(3) ),
@@ -88,6 +90,7 @@ const BasicConstraintTests = Dict(
8890
(MOI.VectorQuadraticFunction{Float64}, MOI.SecondOrderCone) => ( dummy_vector_quadratic, 3, MOI.SecondOrderCone(3) ),
8991
(MOI.VectorQuadraticFunction{Float64}, MOI.RotatedSecondOrderCone) => ( dummy_vector_quadratic, 3, MOI.RotatedSecondOrderCone(3) ),
9092
(MOI.VectorQuadraticFunction{Float64}, MOI.GeometricMeanCone) => ( dummy_vector_quadratic, 3, MOI.GeometricMeanCone(3) ),
93+
(MOI.VectorQuadraticFunction{Float64}, MOI.RelativeEntropyCone) => ( dummy_vector_quadratic, 3, MOI.RelativeEntropyCone(3) ),
9194
(MOI.VectorQuadraticFunction{Float64}, MOI.NormSpectralCone) => ( dummy_vector_quadratic, 7, MOI.NormSpectralCone(2, 3) ),
9295
(MOI.VectorQuadraticFunction{Float64}, MOI.NormNuclearCone) => ( dummy_vector_quadratic, 7, MOI.NormNuclearCone(2, 3) ),
9396
(MOI.VectorQuadraticFunction{Float64}, MOI.PositiveSemidefiniteConeSquare) => ( dummy_vector_quadratic, 9, MOI.PositiveSemidefiniteConeSquare(3) )

0 commit comments

Comments
 (0)