diff --git a/src/Bridges/Bridges.jl b/src/Bridges/Bridges.jl index 9e742c8517..91f8beff9a 100644 --- a/src/Bridges/Bridges.jl +++ b/src/Bridges/Bridges.jl @@ -299,11 +299,12 @@ function _runtests( variable_start = 1.2, constraint_start = 1.2, eltype = Float64, + model_eltype = eltype, print_inner_model::Bool = false, cannot_unbridge::Bool = false, ) # Load model and bridge it - inner = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{eltype}()) + inner = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{model_eltype}()) model = _bridged_model(Bridge{eltype}, inner) input_fn(model) final_touch(model) @@ -313,7 +314,8 @@ function _runtests( print(inner) end Test.@testset "Test outer bridged model appears like the input" begin # COV_EXCL_LINE - test = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{eltype}()) + test = + MOI.Utilities.UniversalFallback(MOI.Utilities.Model{model_eltype}()) input_fn(test) _test_structural_identical( test, @@ -322,7 +324,8 @@ function _runtests( ) end Test.@testset "Test inner bridged model appears like the target" begin # COV_EXCL_LINE - target = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{eltype}()) + target = + MOI.Utilities.UniversalFallback(MOI.Utilities.Model{model_eltype}()) output_fn(target) _test_structural_identical(target, inner) end diff --git a/src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl b/src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl index d0b9b1ef78..6d91ffe695 100644 --- a/src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl +++ b/src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl @@ -282,7 +282,8 @@ function MOI.supports_constraint( ::Type{G}, ::Type{<:MOI.AbstractSet}, ) where {T,F,G<:MOI.AbstractFunction} - return !MOI.Utilities.is_complex(G) && isfinite(conversion_cost(F, G)) + return MOI.Utilities.is_coefficient_type(G, T) && + isfinite(conversion_cost(F, G)) end function concrete_bridge_type( diff --git a/src/Bridges/Constraint/bridges/InequalityToComplementsBridge.jl b/src/Bridges/Constraint/bridges/InequalityToComplementsBridge.jl index c0850f3bcb..db82ca9afb 100644 --- a/src/Bridges/Constraint/bridges/InequalityToComplementsBridge.jl +++ b/src/Bridges/Constraint/bridges/InequalityToComplementsBridge.jl @@ -71,7 +71,8 @@ function MOI.supports_constraint( ::Type{F}, ::Type{<:Union{MOI.GreaterThan{T},MOI.LessThan{T},MOI.EqualTo{T}}}, ) where {T,F<:MOI.AbstractScalarFunction} - return !MOI.Utilities.is_complex(F) + return MOI.Utilities.is_coefficient_type(F, T) && + !MOI.Utilities.is_complex(F) end function MOI.Bridges.added_constrained_variable_types( diff --git a/src/Bridges/Constraint/bridges/NormOneBridge.jl b/src/Bridges/Constraint/bridges/NormOneBridge.jl index 45872797a4..e0221d5105 100644 --- a/src/Bridges/Constraint/bridges/NormOneBridge.jl +++ b/src/Bridges/Constraint/bridges/NormOneBridge.jl @@ -56,7 +56,8 @@ function MOI.supports_constraint( ::Type{F}, ::Type{MOI.NormOneCone}, ) where {T,F<:MOI.AbstractVectorFunction} - return !MOI.Utilities.is_complex(F) + return MOI.Utilities.is_coefficient_type(F, T) && + !MOI.Utilities.is_complex(F) end function MOI.Bridges.added_constrained_variable_types(::Type{<:NormOneBridge}) diff --git a/src/Bridges/Constraint/bridges/SetDotScalingBridge.jl b/src/Bridges/Constraint/bridges/SetDotScalingBridge.jl index e778d4019b..233f7118b5 100644 --- a/src/Bridges/Constraint/bridges/SetDotScalingBridge.jl +++ b/src/Bridges/Constraint/bridges/SetDotScalingBridge.jl @@ -193,11 +193,11 @@ end # Since the set type is not defined, the default `MOI.supports_constraint` # for `SetMapBridge` does not work function MOI.supports_constraint( - ::Type{<:SetDotScalingBridge}, + ::Type{<:SetDotScalingBridge{T}}, F::Type{<:MOI.AbstractVectorFunction}, S::Type{<:MOI.AbstractVectorSet}, -) - return !MOI.Utilities.is_complex(F) && MOI.is_set_dot_scaled(S) +) where {T} + return MOI.Utilities.is_coefficient_type(F, T) && MOI.is_set_dot_scaled(S) end function MOI.supports_constraint( diff --git a/src/Bridges/Constraint/bridges/VectorizeBridge.jl b/src/Bridges/Constraint/bridges/VectorizeBridge.jl index ee7ae02d11..7d9f7a3601 100644 --- a/src/Bridges/Constraint/bridges/VectorizeBridge.jl +++ b/src/Bridges/Constraint/bridges/VectorizeBridge.jl @@ -64,7 +64,7 @@ function MOI.supports_constraint( ::Type{F}, ::Type{<:MOI.Utilities.ScalarLinearSet{T}}, ) where {T,F<:MOI.AbstractScalarFunction} - return !MOI.Utilities.is_complex(F) + return MOI.Utilities.is_coefficient_type(F, T) end function MOI.Bridges.added_constrained_variable_types(::Type{<:VectorizeBridge}) diff --git a/src/Bridges/Constraint/set_map.jl b/src/Bridges/Constraint/set_map.jl index 52b0b587e4..fed3e8f0d7 100644 --- a/src/Bridges/Constraint/set_map.jl +++ b/src/Bridges/Constraint/set_map.jl @@ -51,7 +51,7 @@ function MOI.supports_constraint( ::Type{F}, ::Type{S1}, ) where {T,S1<:MOI.AbstractScalarSet,F<:MOI.AbstractScalarFunction} - return !MOI.Utilities.is_complex(F) + return MOI.Utilities.is_coefficient_type(F, T) end function MOI.supports_constraint( @@ -59,7 +59,7 @@ function MOI.supports_constraint( ::Type{F}, ::Type{S1}, ) where {T,S1<:MOI.AbstractVectorSet,F<:MOI.AbstractVectorFunction} - return !MOI.Utilities.is_complex(F) + return MOI.Utilities.is_coefficient_type(F, T) end function MOI.Bridges.added_constrained_variable_types( diff --git a/test/Bridges/Constraint/SetDotScalingBridge.jl b/test/Bridges/Constraint/SetDotScalingBridge.jl index 8147e1d113..cec348aeb9 100644 --- a/test/Bridges/Constraint/SetDotScalingBridge.jl +++ b/test/Bridges/Constraint/SetDotScalingBridge.jl @@ -111,6 +111,40 @@ function test_inverse_scaling_quadratic() return end +function test_scaling_complex() + MOI.Bridges.runtests( + MOI.Bridges.Constraint.SetDotScalingBridge, + model -> begin + x, y, z = MOI.add_variables(model, 3) + MOI.add_constraint( + model, + MOI.Utilities.vectorize([ + (1.0 + 0im) * x, + (1.0 * im) * y, + (1.0 + 0im) * z, + ]), + MOI.PositiveSemidefiniteConeTriangle(2), + ) + end, + model -> begin + x, y, z = MOI.add_variables(model, 3) + MOI.add_constraint( + model, + MOI.Utilities.vectorize([ + (1.0 + 0im) * x, + (√2 * im) * y, + (1.0 + 0im) * z, + ]), + MOI.ScaledPositiveSemidefiniteConeTriangle(2), + ) + end, + eltype = ComplexF64, + model_eltype = Float64, + constraint_start = 1.2 * im, + ) + return +end + function test_set_dot_scaling_constraint_dual_start() inner = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()) model = MOI.Bridges.Constraint.SetDotScaling{Float64}(inner) diff --git a/test/Bridges/lazy_bridge_optimizer.jl b/test/Bridges/lazy_bridge_optimizer.jl index 696aff567d..ca8cee0eb1 100644 --- a/test/Bridges/lazy_bridge_optimizer.jl +++ b/test/Bridges/lazy_bridge_optimizer.jl @@ -2253,6 +2253,34 @@ function test_issue_2696() return end +function test_wrong_coefficient() + model = MOI.instantiate( + MOI.Utilities.Model{Float64}, + with_bridge_type = Float64, + ) + @test !MOI.supports_constraint( + model, + MOI.VectorAffineFunction{Int}, + MOI.Nonnegatives, + ) + @test !MOI.supports_constraint( + model, + MOI.VectorAffineFunction{Int}, + MOI.PositiveSemidefiniteConeTriangle, + ) + @test !MOI.supports_constraint( + model, + MOI.ScalarAffineFunction{Int}, + MOI.EqualTo{Int}, + ) + @test !MOI.supports_constraint( + model, + MOI.VectorQuadraticFunction{Int}, + MOI.Zeros, + ) + return +end + end # module TestBridgesLazyBridgeOptimizer.runtests()