Skip to content

Commit 8ad7837

Browse files
authored
Merge pull request #899 from JuliaOpt/bl/square_get_func_set
Implement MOI.get for function/set for SquareBridge
2 parents a1bc289 + c6016e5 commit 8ad7837

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

src/Bridges/Constraint/square.jl

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct SquareBridge{T, F<:MOI.AbstractVectorFunction,
7070
G<:MOI.AbstractScalarFunction,
7171
TT<:MOI.AbstractSymmetricMatrixSetTriangle,
7272
ST<:MOI.AbstractSymmetricMatrixSetSquare} <: AbstractBridge
73-
side_dimension::Int
73+
square_set::ST
7474
triangle::CI{F, TT}
7575
sym::Vector{Pair{Tuple{Int, Int}, CI{G, MOI.EqualTo{T}}}}
7676
end
@@ -113,7 +113,7 @@ function bridge_constraint(::Type{SquareBridge{T, F, G, TT, ST}},
113113
end
114114
@assert length(upper_triangle_indices) == trilen
115115
triangle = MOI.add_constraint(model, f_scalars[upper_triangle_indices], MOI.triangular_form(s))
116-
return SquareBridge{T, F, G, TT, ST}(dim, triangle, sym)
116+
return SquareBridge{T, F, G, TT, ST}(s, triangle, sym)
117117
end
118118

119119
function MOI.supports_constraint(::Type{SquareBridge{T}},
@@ -161,10 +161,38 @@ function MOI.delete(model::MOI.ModelLike, bridge::SquareBridge)
161161
end
162162

163163
# Attributes, Bridge acting as a constraint
164+
function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintFunction,
165+
bridge::SquareBridge{T}) where T
166+
tri = MOIU.eachscalar(MOI.get(model, attr, bridge.triangle))
167+
dim = MOI.side_dimension(bridge.square_set)
168+
sqr = Vector{eltype(tri)}(undef, dim^2)
169+
sqrmap(i, j) = (j - 1) * dim + i
170+
k = 0
171+
for j in 1:dim
172+
for i in 1:j
173+
k += 1
174+
sqr[sqrmap(i, j)] = tri[k]
175+
sqr[sqrmap(j, i)] = tri[k]
176+
end
177+
end
178+
for sym in bridge.sym
179+
i, j = sym.first
180+
diff = MOI.get(model, attr, sym.second)
181+
set = MOI.get(model, MOI.ConstraintSet(), sym.second)
182+
upper = sqr[sqrmap(i, j)]
183+
lower = MOIU.operate(-, T, upper, diff)
184+
lower = MOIU.operate!(-, T, lower, MOI.constant(set))
185+
sqr[sqrmap(j, i)] = MOIU.convert_approx(eltype(tri), lower)
186+
end
187+
return MOIU.vectorize(sqr)
188+
end
189+
function MOI.get(::MOI.ModelLike, ::MOI.ConstraintSet, bridge::SquareBridge)
190+
return bridge.square_set
191+
end
164192
function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal,
165193
bridge::SquareBridge{T}) where T
166194
tri = MOI.get(model, attr, bridge.triangle)
167-
dim = bridge.side_dimension
195+
dim = MOI.side_dimension(bridge.square_set)
168196
sqr = Vector{eltype(tri)}(undef, dim^2)
169197
k = 0
170198
for j in 1:dim
@@ -178,7 +206,7 @@ end
178206
function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintDual,
179207
bridge::SquareBridge)
180208
tri = MOI.get(model, attr, bridge.triangle)
181-
dim = bridge.side_dimension
209+
dim = MOI.side_dimension(bridge.square_set)
182210
sqr = Vector{eltype(tri)}(undef, dim^2)
183211
k = 0
184212
for j in 1:dim

src/Test/UnitTests/basic_constraint_tests.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const BasicConstraintTests = Dict(
4545
(MOI.VectorOfVariables, MOI.DualPowerCone{Float64}) => ( dummy_vectorofvariables, 3, MOI.DualPowerCone(2.0) ),
4646

4747
(MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle) => ( dummy_vectorofvariables, 7, MOI.PositiveSemidefiniteConeTriangle(3) ),
48-
(MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeSquare) => ( dummy_vectorofvariables, 10, MOI.PositiveSemidefiniteConeSquare(3) ),
48+
(MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeSquare) => ( dummy_vectorofvariables, 9, MOI.PositiveSemidefiniteConeSquare(3) ),
4949
(MOI.VectorOfVariables, MOI.LogDetConeTriangle) => ( dummy_vectorofvariables, 8, MOI.LogDetConeTriangle(3) ),
5050
(MOI.VectorOfVariables, MOI.LogDetConeSquare) => ( dummy_vectorofvariables, 11, MOI.LogDetConeSquare(3) ),
5151
(MOI.VectorOfVariables, MOI.RootDetConeTriangle) => ( dummy_vectorofvariables, 7, MOI.RootDetConeTriangle(3) ),
@@ -70,6 +70,7 @@ const BasicConstraintTests = Dict(
7070
(MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone) => ( dummy_vector_affine, 3, MOI.SecondOrderCone(3) ),
7171
(MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone) => ( dummy_vector_affine, 3, MOI.RotatedSecondOrderCone(3) ),
7272
(MOI.VectorAffineFunction{Float64}, MOI.GeometricMeanCone) => ( dummy_vector_affine, 3, MOI.GeometricMeanCone(3) ),
73+
(MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeSquare) => ( dummy_vector_affine, 9, MOI.GeometricMeanCone(3) ),
7374

7475
(MOI.VectorQuadraticFunction{Float64}, MOI.Zeros) => ( dummy_vector_quadratic, 2, MOI.Zeros(2) ),
7576
(MOI.VectorQuadraticFunction{Float64}, MOI.Nonpositives) => ( dummy_vector_quadratic, 2, MOI.Nonpositives(2) ),
@@ -79,7 +80,8 @@ const BasicConstraintTests = Dict(
7980
(MOI.VectorQuadraticFunction{Float64}, MOI.NormOneCone) => ( dummy_vector_quadratic, 3, MOI.NormOneCone(3) ),
8081
(MOI.VectorQuadraticFunction{Float64}, MOI.SecondOrderCone) => ( dummy_vector_quadratic, 3, MOI.SecondOrderCone(3) ),
8182
(MOI.VectorQuadraticFunction{Float64}, MOI.RotatedSecondOrderCone) => ( dummy_vector_quadratic, 3, MOI.RotatedSecondOrderCone(3) ),
82-
(MOI.VectorQuadraticFunction{Float64}, MOI.GeometricMeanCone) => ( dummy_vector_quadratic, 3, MOI.GeometricMeanCone(3) )
83+
(MOI.VectorQuadraticFunction{Float64}, MOI.GeometricMeanCone) => ( dummy_vector_quadratic, 3, MOI.GeometricMeanCone(3) ),
84+
(MOI.VectorQuadraticFunction{Float64}, MOI.PositiveSemidefiniteConeSquare) => ( dummy_vector_quadratic, 9, MOI.GeometricMeanCone(3) )
8385
)
8486
"""
8587
basic_constraint_tests(model::MOI.ModelLike, config::TestConfig;

test/Bridges/Constraint/square.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ config = MOIT.TestConfig()
1313

1414
@testset "Square" begin
1515
bridged_mock = MOIB.Constraint.Square{Float64}(mock)
16+
17+
MOIT.basic_constraint_tests(
18+
bridged_mock, config,
19+
include = [(F, S)
20+
for F in [MOI.VectorOfVariables, MOI.VectorAffineFunction{Float64},
21+
MOI.VectorQuadraticFunction{Float64}]
22+
for S in [MOI.PositiveSemidefiniteConeSquare]])
23+
24+
1625
mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, ones(4),
1726
(MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}) => [2, 2])
1827
MOIT.psds0vtest(bridged_mock, config)

0 commit comments

Comments
 (0)