From 2dcfa944b0a25fc0f3becb6912f5df060b624214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 10 May 2019 09:09:25 +0200 Subject: [PATCH] Add bridge_constraint --- docs/src/apireference.md | 22 ++++++++++++++++++++ src/Bridges/bridge.jl | 8 ++++++++ src/Bridges/bridgeoptimizer.jl | 2 +- src/Bridges/detbridge.jl | 27 ++++++++++++++++-------- src/Bridges/flip_sign_bridge.jl | 28 ++++++++++++++----------- src/Bridges/functionize_bridge.jl | 6 ++++-- src/Bridges/geomeanbridge.jl | 5 +++-- src/Bridges/intervalbridge.jl | 3 ++- src/Bridges/quadtosocbridge.jl | 7 ++++--- src/Bridges/rsocbridge.jl | 4 +++- src/Bridges/scalarizebridge.jl | 7 ++++--- src/Bridges/slackbridge.jl | 6 ++++-- src/Bridges/soctopsdbridge.jl | 34 ++++++++++++++++--------------- src/Bridges/squarepsdbridge.jl | 7 +++---- src/Bridges/vectorizebridge.jl | 5 +++-- 15 files changed, 113 insertions(+), 58 deletions(-) diff --git a/docs/src/apireference.md b/docs/src/apireference.md index 7df5cc9f64..253885adbe 100644 --- a/docs/src/apireference.md +++ b/docs/src/apireference.md @@ -391,6 +391,28 @@ Moreover, a `LazyBridgeOptimizer` with all the bridges defined in this package c Bridges.full_bridge_optimizer ``` +### Bridge interface + +A bridge should implement the following functions to be usable by a bridge optimizer: +```@docs +supports_constraint(::Type{<:Bridges.AbstractBridge}, ::Type{<:AbstractFunction}, ::Type{<:AbstractSet}) +Bridges.concrete_bridge_type +Bridges.bridge_constraint +Bridges.added_constraint_types +``` + +When querying the [`NumberOfVariables`](@ref), [`NumberOfConstraints`](@ref) +and [`ListOfConstraintIndices`](@ref), the variables and constraints created +by the bridges in the underlying model are hidden by the bridge optimizer. +For this purpose, the bridge should provide access to the variables and +constraints it has creates by implemented the following methods of +[`get`](@ref): +```@docs +get(::Bridges.AbstractBridge, ::NumberOfVariables) +get(::Bridges.AbstractBridge, ::NumberOfConstraints) +get(::Bridges.AbstractBridge, ::ListOfConstraintIndices) +``` + ## Copy utilities The following utilities can be used to implement [`copy_to`](@ref). See diff --git a/src/Bridges/bridge.jl b/src/Bridges/bridge.jl index ba102a6751..5bc541ee3c 100644 --- a/src/Bridges/bridge.jl +++ b/src/Bridges/bridge.jl @@ -10,6 +10,14 @@ These calls are used by the `AbstractBridgeOptimizer` to communicate with the br """ abstract type AbstractBridge end +""" + bridge_constraint(BT::Type{<:AbstractBridge}, model::MOI.ModelLike, + func::AbstractFunction, set::MOI.AbstractSet) + +Bridge the constraint `func`-in-`set` using bridge `BT` to `model` and returns +a bridge object of type `BT`. +""" +function bridge_constraint end function MOI.get(::MOI.ModelLike, attr::MOI.AbstractConstraintAttribute, bridge::AbstractBridge) diff --git a/src/Bridges/bridgeoptimizer.jl b/src/Bridges/bridgeoptimizer.jl index 53fbaf1f5b..4e4be7195f 100644 --- a/src/Bridges/bridgeoptimizer.jl +++ b/src/Bridges/bridgeoptimizer.jl @@ -370,7 +370,7 @@ function MOI.add_constraint(b::AbstractBridgeOptimizer, f::MOI.AbstractFunction, BridgeType = concrete_bridge_type(b, typeof(f), typeof(s)) # `add_constraint` might throw an `UnsupportedConstraint` but no # modification has been done in the previous line - push!(b.bridges, BridgeType(b, f, s)) + push!(b.bridges, bridge_constraint(BridgeType, b, f, s)) push!(b.constraint_types, (typeof(f), typeof(s))) ci = MOI.ConstraintIndex{typeof(f), typeof(s)}(length(b.bridges)) return ci diff --git a/src/Bridges/detbridge.jl b/src/Bridges/detbridge.jl index 42bd2d9194..74c93b3fcd 100644 --- a/src/Bridges/detbridge.jl +++ b/src/Bridges/detbridge.jl @@ -79,18 +79,22 @@ struct LogDetBridge{T} <: AbstractBridge lcindex::Vector{CI{MOI.VectorAffineFunction{T}, MOI.ExponentialCone}} tlindex::CI{MOI.ScalarAffineFunction{T}, MOI.LessThan{T}} end -function LogDetBridge{T}(model, f::MOI.VectorOfVariables, s::MOI.LogDetConeTriangle) where T - LogDetBridge{T}(model, MOI.VectorAffineFunction{T}(f), s) +function bridge_constraint(::Type{LogDetBridge{T}}, model, + f::MOI.VectorOfVariables, + s::MOI.LogDetConeTriangle) where T + return bridge_constraint(LogDetBridge{T}, model, + MOI.VectorAffineFunction{T}(f), s) end -function LogDetBridge{T}(model, f::MOI.VectorAffineFunction{T}, s::MOI.LogDetConeTriangle) where T +function bridge_constraint(::Type{LogDetBridge{T}}, model, + f::MOI.VectorAffineFunction{T}, + s::MOI.LogDetConeTriangle) where T d = s.side_dimension tu, D, Δ, sdindex = extract_eigenvalues(model, f, d, 2) t, u = tu l = MOI.add_variables(model, d) lcindex = [sublog(model, l[i], u, D[i], T) for i in eachindex(l)] tlindex = subsum(model, t, l, T) - - LogDetBridge(Δ, l, sdindex, lcindex, tlindex) + return LogDetBridge(Δ, l, sdindex, lcindex, tlindex) end MOI.supports_constraint(::Type{LogDetBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.LogDetConeTriangle}) where T = true @@ -170,10 +174,15 @@ struct RootDetBridge{T} <: AbstractBridge sdindex::CI{MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle} gmindex::CI{MOI.VectorAffineFunction{T}, MOI.GeometricMeanCone} end -function RootDetBridge{T}(model, f::MOI.VectorOfVariables, s::MOI.RootDetConeTriangle) where T - RootDetBridge{T}(model, MOI.VectorAffineFunction{T}(f), s) +function bridge_constraint(::Type{RootDetBridge{T}}, model, + f::MOI.VectorOfVariables, + s::MOI.RootDetConeTriangle) where T + return bridge_constraint(RootDetBridge{T}, model, + MOI.VectorAffineFunction{T}(f), s) end -function RootDetBridge{T}(model, f::MOI.VectorAffineFunction{T}, s::MOI.RootDetConeTriangle) where T +function bridge_constraint(::Type{RootDetBridge{T}}, model, + f::MOI.VectorAffineFunction{T}, + s::MOI.RootDetConeTriangle) where T d = s.side_dimension tu, D, Δ, sdindex = extract_eigenvalues(model, f, d, 1) t = tu[1] @@ -181,7 +190,7 @@ function RootDetBridge{T}(model, f::MOI.VectorAffineFunction{T}, s::MOI.RootDetC gmindex = MOI.add_constraint(model, MOIU.operate(vcat, T, t, DF), MOI.GeometricMeanCone(d+1)) - RootDetBridge(Δ, sdindex, gmindex) + return RootDetBridge(Δ, sdindex, gmindex) end MOI.supports_constraint(::Type{RootDetBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RootDetConeTriangle}) where T = true diff --git a/src/Bridges/flip_sign_bridge.jl b/src/Bridges/flip_sign_bridge.jl index 9b43a831ab..373f97e99a 100644 --- a/src/Bridges/flip_sign_bridge.jl +++ b/src/Bridges/flip_sign_bridge.jl @@ -79,9 +79,10 @@ struct GreaterToLessBridge{T, F<:MOI.AbstractScalarFunction} <: FlipSignBridge{T, MOI.GreaterThan{T}, MOI.LessThan{T}, F} flipped_constraint::CI{F, MOI.LessThan{T}} end -function GreaterToLessBridge{T, F}(model::MOI.ModelLike, - g::MOI.AbstractScalarFunction, - s::MOI.GreaterThan) where {T, F} +function bridge_constraint(::Type{GreaterToLessBridge{T, F}}, + model::MOI.ModelLike, + g::MOI.AbstractScalarFunction, + s::MOI.GreaterThan) where {T, F} f = MOIU.operate(-, T, g) flipped_constraint = MOI.add_constraint(model, f, MOI.LessThan(-s.lower)) return GreaterToLessBridge{T, F}(flipped_constraint) @@ -115,9 +116,10 @@ struct LessToGreaterBridge{T, F<:MOI.AbstractScalarFunction} <: FlipSignBridge{T, MOI.LessThan{T}, MOI.GreaterThan{T}, F} flipped_constraint::CI{F, MOI.GreaterThan{T}} end -function LessToGreaterBridge{T, F}(model::MOI.ModelLike, - g::MOI.AbstractScalarFunction, - s::MOI.LessThan) where {T, F} +function bridge_constraint(::Type{LessToGreaterBridge{T, F}}, + model::MOI.ModelLike, + g::MOI.AbstractScalarFunction, + s::MOI.LessThan) where {T, F} f = MOIU.operate(-, T, g) flipped_constraint = MOI.add_constraint(model, f, MOI.GreaterThan(-s.upper)) return LessToGreaterBridge{T, F}(flipped_constraint) @@ -151,9 +153,10 @@ struct NonnegToNonposBridge{T, F<:MOI.AbstractVectorFunction} <: FlipSignBridge{T, MOI.Nonnegatives, MOI.Nonpositives, F} flipped_constraint::CI{F, MOI.Nonpositives} end -function NonnegToNonposBridge{T, F}(model::MOI.ModelLike, - g::MOI.AbstractVectorFunction, - s::MOI.Nonnegatives) where {T, F} +function bridge_constraint(::Type{NonnegToNonposBridge{T, F}}, + model::MOI.ModelLike, + g::MOI.AbstractVectorFunction, + s::MOI.Nonnegatives) where {T, F} f = MOIU.operate(-, T, g) flipped_constraint = MOI.add_constraint(model, f, MOI.Nonpositives(s.dimension)) @@ -177,9 +180,10 @@ struct NonposToNonnegBridge{T, F<:MOI.AbstractVectorFunction} <: FlipSignBridge{T, MOI.Nonpositives, MOI.Nonnegatives, F} flipped_constraint::CI{F, MOI.Nonnegatives} end -function NonposToNonnegBridge{T, F}(model::MOI.ModelLike, - g::MOI.AbstractVectorFunction, - s::MOI.Nonpositives) where {T, F} +function bridge_constraint(::Type{NonposToNonnegBridge{T, F}}, + model::MOI.ModelLike, + g::MOI.AbstractVectorFunction, + s::MOI.Nonpositives) where {T, F} f = MOIU.operate(-, T, g) flipped_constraint = MOI.add_constraint(model, f, MOI.Nonnegatives(s.dimension)) diff --git a/src/Bridges/functionize_bridge.jl b/src/Bridges/functionize_bridge.jl index 900719394c..764b5a4bd5 100644 --- a/src/Bridges/functionize_bridge.jl +++ b/src/Bridges/functionize_bridge.jl @@ -9,7 +9,8 @@ into the constraint `ScalarAffineFunction{T}`-in-`S`. struct ScalarFunctionizeBridge{T, S} <: AbstractBridge constraint::CI{MOI.ScalarAffineFunction{T}, S} end -function ScalarFunctionizeBridge{T, S}(model, f::MOI.SingleVariable, s::S) where {T, S} +function bridge_constraint(::Type{ScalarFunctionizeBridge{T, S}}, model, + f::MOI.SingleVariable, s::S) where {T, S} constraint = MOI.add_constraint(model, MOI.ScalarAffineFunction{T}(f), s) return ScalarFunctionizeBridge{T, S}(constraint) end @@ -81,7 +82,8 @@ into the constraint `VectorAffineFunction{T}`-in-`S`. struct VectorFunctionizeBridge{T, S} <: AbstractBridge constraint::CI{MOI.VectorAffineFunction{T}, S} end -function VectorFunctionizeBridge{T, S}(model, f::MOI.VectorOfVariables, s::S) where {T, S} +function bridge_constraint(::Type{VectorFunctionizeBridge{T, S}}, model, + f::MOI.VectorOfVariables, s::S) where {T, S} constraint = MOI.add_constraint(model, MOI.VectorAffineFunction{T}(f), s) return VectorFunctionizeBridge{T, S}(constraint) end diff --git a/src/Bridges/geomeanbridge.jl b/src/Bridges/geomeanbridge.jl index 7a400d9f0f..cf38a2f204 100644 --- a/src/Bridges/geomeanbridge.jl +++ b/src/Bridges/geomeanbridge.jl @@ -47,8 +47,9 @@ struct GeoMeanBridge{T, F, G} <: AbstractBridge tubc::CI{F, MOI.LessThan{T}} socrc::Vector{CI{G, MOI.RotatedSecondOrderCone}} end -function GeoMeanBridge{T, F, G}(model, f::MOI.AbstractVectorFunction, - s::MOI.GeometricMeanCone) where {T, F, G} +function bridge_constraint(::Type{GeoMeanBridge{T, F, G}}, model, + f::MOI.AbstractVectorFunction, + s::MOI.GeometricMeanCone) where {T, F, G} d = s.dimension n = d-1 l = ilog2(n) diff --git a/src/Bridges/intervalbridge.jl b/src/Bridges/intervalbridge.jl index 3dff98fca5..74c788c6d7 100644 --- a/src/Bridges/intervalbridge.jl +++ b/src/Bridges/intervalbridge.jl @@ -7,7 +7,8 @@ struct SplitIntervalBridge{T, F<:MOI.AbstractScalarFunction} <: AbstractBridge lower::CI{F, MOI.GreaterThan{T}} upper::CI{F, MOI.LessThan{T}} end -function SplitIntervalBridge{T, F}(model, f::F, s::MOI.Interval{T}) where {T, F} +function bridge_constraint(::Type{SplitIntervalBridge{T, F}}, model, f::F, + s::MOI.Interval{T}) where {T, F} lower = MOI.add_constraint(model, f, MOI.GreaterThan(s.lower)) upper = MOI.add_constraint(model, f, MOI.LessThan(s.upper)) return SplitIntervalBridge{T, F}(lower, upper) diff --git a/src/Bridges/quadtosocbridge.jl b/src/Bridges/quadtosocbridge.jl index 07402c6619..bf6fc5daaa 100644 --- a/src/Bridges/quadtosocbridge.jl +++ b/src/Bridges/quadtosocbridge.jl @@ -60,9 +60,10 @@ struct QuadtoSOCBridge{T} <: AbstractBridge less_than::Bool # whether the constraint was ≤ or ≥ set_constant::T # the constant that was on the set end -function QuadtoSOCBridge{T}(model, func::MOI.ScalarQuadraticFunction{T}, - set::Union{MOI.LessThan{T}, - MOI.GreaterThan{T}}) where T +function bridge_constraint(::Type{QuadtoSOCBridge{T}}, model, + func::MOI.ScalarQuadraticFunction{T}, + set::Union{MOI.LessThan{T}, + MOI.GreaterThan{T}}) where T set_constant = MOI.constant(set) less_than = set isa MOI.LessThan Q, index_to_variable_map = matrix_from_quadratic_terms(func.quadratic_terms) diff --git a/src/Bridges/rsocbridge.jl b/src/Bridges/rsocbridge.jl index 5c62f75fae..84edc08e9d 100644 --- a/src/Bridges/rsocbridge.jl +++ b/src/Bridges/rsocbridge.jl @@ -19,7 +19,9 @@ That means in particular that the norm is of constraint primal and duals are pre struct RSOCBridge{T, F} <: AbstractBridge soc::CI{F, MOI.SecondOrderCone} end -function RSOCBridge{T, F}(model, f::MOI.AbstractVectorFunction, s::MOI.RotatedSecondOrderCone) where {T, F} +function bridge_constraint(::Type{RSOCBridge{T, F}}, model, + f::MOI.AbstractVectorFunction, + s::MOI.RotatedSecondOrderCone) where {T, F} d = s.dimension f_scalars = MOIU.eachscalar(f) t = f_scalars[1] diff --git a/src/Bridges/scalarizebridge.jl b/src/Bridges/scalarizebridge.jl index 06eeb93bb8..b3d2c79f39 100644 --- a/src/Bridges/scalarizebridge.jl +++ b/src/Bridges/scalarizebridge.jl @@ -14,9 +14,10 @@ mutable struct ScalarizeBridge{T, F, S} <: AbstractBridge scalar_constraints::Vector{CI{F, S}} constants::Vector{T} end -function ScalarizeBridge{T, F, S}(model::MOI.ModelLike, - f::MOI.AbstractVectorFunction, - set::VectorLinearSet) where {T, F, S} +function bridge_constraint(::Type{ScalarizeBridge{T, F, S}}, + model::MOI.ModelLike, + f::MOI.AbstractVectorFunction, + set::VectorLinearSet) where {T, F, S} dimension = MOI.output_dimension(f) constants = MOI.constant(f, T) new_f = MOIU.scalarize(f, true) diff --git a/src/Bridges/slackbridge.jl b/src/Bridges/slackbridge.jl index 54b9b3cfe2..d0989001e5 100644 --- a/src/Bridges/slackbridge.jl +++ b/src/Bridges/slackbridge.jl @@ -13,7 +13,8 @@ struct ScalarSlackBridge{T, F, S} <: AbstractBridge slack_in_set::CI{MOI.SingleVariable, S} equality::CI{F, MOI.EqualTo{T}} end -function ScalarSlackBridge{T, F, S}(model, f::MOI.AbstractScalarFunction, s::S) where {T, F, S} +function bridge_constraint(::Type{ScalarSlackBridge{T, F, S}}, model, + f::MOI.AbstractScalarFunction, s::S) where {T, F, S} slack = MOI.add_variable(model) new_f = MOIU.operate(-, T, f, MOI.SingleVariable(slack)) slack_in_set = MOI.add_constraint(model, MOI.SingleVariable(slack), s) @@ -115,7 +116,8 @@ struct VectorSlackBridge{T, F, S} <: AbstractBridge slacks_in_set::CI{MOI.VectorOfVariables, S} equality::CI{F, MOI.Zeros} end -function VectorSlackBridge{T, F, S}(model, f::MOI.AbstractVectorFunction, s::S) where {T, F, S} +function bridge_constraint(::Type{VectorSlackBridge{T, F, S}}, model, + f::MOI.AbstractVectorFunction, s::S) where {T, F, S} d = MOI.dimension(s) slacks = MOI.add_variables(model, d) new_f = MOIU.operate(-, T, f, MOI.VectorOfVariables(slacks)) diff --git a/src/Bridges/soctopsdbridge.jl b/src/Bridges/soctopsdbridge.jl index 233e0b842a..ec816cf3bb 100644 --- a/src/Bridges/soctopsdbridge.jl +++ b/src/Bridges/soctopsdbridge.jl @@ -55,9 +55,10 @@ struct SOCtoPSDBridge{T} <: AbstractBridge dim::Int cr::CI{MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle} end -function SOCtoPSDBridge{T}(instance, f, s::MOI.SecondOrderCone) where T +function bridge_constraint(::Type{SOCtoPSDBridge{T}}, model, f, + s::MOI.SecondOrderCone) where T d = MOI.dimension(s) - cr = MOI.add_constraint(instance, _SOCtoPSDaff(f, T), MOI.PositiveSemidefiniteConeTriangle(d)) + cr = MOI.add_constraint(model, _SOCtoPSDaff(f, T), MOI.PositiveSemidefiniteConeTriangle(d)) SOCtoPSDBridge(d, cr) end @@ -67,11 +68,11 @@ _SOCtoPSDaff(f::MOI.VectorAffineFunction, ::Type) = _SOCtoPSDaff(f, MOIU.eachsca MOI.supports_constraint(::Type{SOCtoPSDBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.SecondOrderCone}) where T = true added_constraint_types(::Type{SOCtoPSDBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.SecondOrderCone}) where T = [(MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle)] -function MOI.get(instance::MOI.AbstractOptimizer, a::MOI.ConstraintPrimal, c::SOCtoPSDBridge) - MOI.get(instance, a, c.cr)[trimap.(1:c.dim, 1)] +function MOI.get(model::MOI.AbstractOptimizer, a::MOI.ConstraintPrimal, c::SOCtoPSDBridge) + MOI.get(model, a, c.cr)[trimap.(1:c.dim, 1)] end -function MOI.get(instance::MOI.AbstractOptimizer, a::MOI.ConstraintDual, c::SOCtoPSDBridge) - dual = MOI.get(instance, a, c.cr) +function MOI.get(model::MOI.AbstractOptimizer, a::MOI.ConstraintDual, c::SOCtoPSDBridge) + dual = MOI.get(model, a, c.cr) tdual = sum(i -> dual[trimap(i, i)], 1:c.dim) [tdual; dual[trimap.(2:c.dim, 1)]*2] end @@ -79,8 +80,8 @@ end MOI.get(::SOCtoPSDBridge{T}, ::MOI.NumberOfConstraints{MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle}) where T = 1 MOI.get(b::SOCtoPSDBridge{T}, ::MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle}) where T = [b.cr] -function MOI.delete(instance::MOI.AbstractOptimizer, c::SOCtoPSDBridge) - MOI.delete(instance, c.cr) +function MOI.delete(model::MOI.AbstractOptimizer, c::SOCtoPSDBridge) + MOI.delete(model, c.cr) end """ @@ -114,9 +115,10 @@ end MOI.supports_constraint(::Type{RSOCtoPSDBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RotatedSecondOrderCone}) where T = true added_constraint_types(::Type{RSOCtoPSDBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RotatedSecondOrderCone}) where T = [(MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle)] -function RSOCtoPSDBridge{T}(instance, f, s::MOI.RotatedSecondOrderCone) where T +function bridge_constraint(::Type{RSOCtoPSDBridge{T}}, model, f, + s::MOI.RotatedSecondOrderCone) where T d = MOI.dimension(s)-1 - cr = MOI.add_constraint(instance, _RSOCtoPSDaff(f, T), MOI.PositiveSemidefiniteConeTriangle(d)) + cr = MOI.add_constraint(model, _RSOCtoPSDaff(f, T), MOI.PositiveSemidefiniteConeTriangle(d)) RSOCtoPSDBridge(d, cr) end @@ -128,13 +130,13 @@ function _RSOCtoPSDaff(f::MOI.VectorAffineFunction, ::Type{T}) where T _SOCtoPSDaff(f_scalars[[1; 3:n]], g) end -function MOI.get(instance::MOI.AbstractOptimizer, a::MOI.ConstraintPrimal, c::RSOCtoPSDBridge) - x = MOI.get(instance, MOI.ConstraintPrimal(), c.cr)[[trimap(1, 1); trimap(2, 2); trimap.(2:c.dim, 1)]] +function MOI.get(model::MOI.AbstractOptimizer, a::MOI.ConstraintPrimal, c::RSOCtoPSDBridge) + x = MOI.get(model, MOI.ConstraintPrimal(), c.cr)[[trimap(1, 1); trimap(2, 2); trimap.(2:c.dim, 1)]] x[2] /= 2 # It is (2u*I)[1,1] so it needs to be divided by 2 to get u x end -function MOI.get(instance::MOI.AbstractOptimizer, a::MOI.ConstraintDual, c::RSOCtoPSDBridge) - dual = MOI.get(instance, MOI.ConstraintDual(), c.cr) +function MOI.get(model::MOI.AbstractOptimizer, a::MOI.ConstraintDual, c::RSOCtoPSDBridge) + dual = MOI.get(model, MOI.ConstraintDual(), c.cr) udual = sum(i -> dual[trimap(i, i)], 2:c.dim) [dual[1]; 2udual; dual[trimap.(2:c.dim, 1)]*2] end @@ -142,6 +144,6 @@ end MOI.get(::RSOCtoPSDBridge{T}, ::MOI.NumberOfConstraints{MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle}) where T = 1 MOI.get(b::RSOCtoPSDBridge{T}, ::MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle}) where T = [b.cr] -function MOI.delete(instance::MOI.AbstractOptimizer, c::RSOCtoPSDBridge) - MOI.delete(instance, c.cr) +function MOI.delete(model::MOI.AbstractOptimizer, c::RSOCtoPSDBridge) + MOI.delete(model, c.cr) end diff --git a/src/Bridges/squarepsdbridge.jl b/src/Bridges/squarepsdbridge.jl index d8145ba9dc..5dff132b5a 100644 --- a/src/Bridges/squarepsdbridge.jl +++ b/src/Bridges/squarepsdbridge.jl @@ -70,10 +70,9 @@ struct SquarePSDBridge{T, F<:MOI.AbstractVectorFunction, psd::CI{F, MOI.PositiveSemidefiniteConeTriangle} sym::Vector{Pair{Tuple{Int, Int}, CI{G, MOI.EqualTo{T}}}} end -function SquarePSDBridge{T, F, G}(model::MOI.ModelLike, f::F, - s::MOI.PositiveSemidefiniteConeSquare) where {T, - F <: MOI.AbstractVectorFunction, - G <: MOI.AbstractScalarFunction} +function bridge_constraint(::Type{SquarePSDBridge{T, F, G}}, + model::MOI.ModelLike, f::F, + s::MOI.PositiveSemidefiniteConeSquare) where {T, F, G} f_scalars = MOIU.eachscalar(f) sym = Pair{Tuple{Int, Int}, CI{G, MOI.EqualTo{T}}}[] dim = s.side_dimension diff --git a/src/Bridges/vectorizebridge.jl b/src/Bridges/vectorizebridge.jl index f4896e3dd8..6df37ce04b 100644 --- a/src/Bridges/vectorizebridge.jl +++ b/src/Bridges/vectorizebridge.jl @@ -18,8 +18,9 @@ mutable struct VectorizeBridge{T, F, S, G} <: AbstractBridge vector_constraint::CI{F, S} set_constant::T # constant in scalar set end -function VectorizeBridge{T, F, S, G}(model::MOI.ModelLike, g::G, - set::MOI.AbstractScalarSet) where {T, F, S, G} +function bridge_constraint(::Type{VectorizeBridge{T, F, S, G}}, + model::MOI.ModelLike, g::G, + set::MOI.AbstractScalarSet) where {T, F, S, G} set_constant = MOI.constant(set) h = MOIU.operate(-, T, g, set_constant) if -set_constant != MOI.constant(h)[1]