diff --git a/.github/workflows/format_check.yml b/.github/workflows/format_check.yml new file mode 100644 index 0000000..a712ef4 --- /dev/null +++ b/.github/workflows/format_check.yml @@ -0,0 +1,31 @@ +name: format-check +on: + push: + branches: + - master + - release-* + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: julia-actions/setup-julia@latest + with: + version: '1' + - uses: actions/checkout@v1 + - name: Format check + shell: julia --color=yes {0} + run: | + using Pkg + Pkg.add(PackageSpec(name="JuliaFormatter", version="0.15.11")) + using JuliaFormatter + format("src", verbose=true) + format("test", verbose=true) + out = String(read(Cmd(`git diff`))) + if isempty(out) + exit(0) + end + @error "Some files have not been formatted !!!" + write(stdout, out) + exit(1) diff --git a/src/Bridges/Constraint/split_zero.jl b/src/Bridges/Constraint/split_zero.jl index 5101051..27e336e 100644 --- a/src/Bridges/Constraint/split_zero.jl +++ b/src/Bridges/Constraint/split_zero.jl @@ -1,54 +1,76 @@ -struct SplitZeroBridge{T, F<:MOI.Utilities.TypedLike{T}, G<:MOI.Utilities.TypedLike{Complex{T}}} <: MOI.Bridges.Constraint.AbstractBridge +struct SplitZeroBridge{ + T, + F<:MOI.Utilities.TypedLike{T}, + G<:MOI.Utilities.TypedLike{Complex{T}}, +} <: MOI.Bridges.Constraint.AbstractBridge dimension::Int - constraint::MOI.ConstraintIndex{F, MOI.Zeros} + constraint::MOI.ConstraintIndex{F,MOI.Zeros} real_indices::Vector{Int} imag_indices::Vector{Int} end function _nonzero_indices(func::MOI.AbstractVectorFunction) - return [i for (i, scalar_func) in enumerate(MOIU.scalarize(func)) if !iszero(scalar_func)] + return [ + i for (i, scalar_func) in enumerate(MOIU.scalarize(func)) if !iszero(scalar_func) + ] end function MOI.Bridges.Constraint.bridge_constraint( - ::Type{SplitZeroBridge{T, F, G}}, model::MOI.ModelLike, + ::Type{SplitZeroBridge{T,F,G}}, + model::MOI.ModelLike, f::G, - set::MOI.Zeros -) where {T, F, G} + set::MOI.Zeros, +) where {T,F,G} real_part = real(f) imag_part = MOI.Utilities.operate(imag, T, f) real_indices = _nonzero_indices(real_part) imag_indices = _nonzero_indices(imag_part) func = MOIU.operate( - vcat, T, + vcat, + T, MOIU.eachscalar(real_part)[real_indices], - MOIU.eachscalar(imag_part)[imag_indices] + MOIU.eachscalar(imag_part)[imag_indices], + ) + constraint = MOI.add_constraint( + model, + func, + MOI.Zeros(length(real_indices) + length(imag_indices)), + ) + return SplitZeroBridge{T,F,G}( + MOI.dimension(set), + constraint, + real_indices, + imag_indices, ) - constraint = MOI.add_constraint(model, func, MOI.Zeros(length(real_indices) + length(imag_indices))) - return SplitZeroBridge{T, F, G}(MOI.dimension(set), constraint, real_indices, imag_indices) end # We don't support `MOI.VectorOfVariables` as it would be a self-loop in the bridge graph function MOI.supports_constraint( - ::Type{SplitZeroBridge{T}}, ::Type{<:MOI.Utilities.TypedLike{Complex{T}}}, - ::Type{MOI.Zeros}) where T + ::Type{SplitZeroBridge{T}}, + ::Type{<:MOI.Utilities.TypedLike{Complex{T}}}, + ::Type{MOI.Zeros}, +) where {T} return true end MOIB.added_constrained_variable_types(::Type{<:SplitZeroBridge}) = Tuple{DataType}[] -function MOIB.added_constraint_types(::Type{SplitZeroBridge{T, F, G}}) where {T, F, G} - return Tuple{DataType, DataType}[(F, MOI.Zeros)] +function MOIB.added_constraint_types(::Type{SplitZeroBridge{T,F,G}}) where {T,F,G} + return Tuple{DataType,DataType}[(F, MOI.Zeros)] end function MOI.Bridges.Constraint.concrete_bridge_type( - ::Type{<:SplitZeroBridge{T}}, G::Type{<:MOI.Utilities.TypedLike}, - ::Type{MOI.Zeros}) where T + ::Type{<:SplitZeroBridge{T}}, + G::Type{<:MOI.Utilities.TypedLike}, + ::Type{MOI.Zeros}, +) where {T} F = MA.promote_operation(imag, G) - return SplitZeroBridge{T, F, G} + return SplitZeroBridge{T,F,G} end # Attributes, Bridge acting as a model -function MOI.get(::SplitZeroBridge{T, F}, - ::MOI.NumberOfConstraints{F, MOI.Zeros}) where {T, F} +function MOI.get(::SplitZeroBridge{T,F}, ::MOI.NumberOfConstraints{F,MOI.Zeros}) where {T,F} return 1 end -function MOI.get(bridge::SplitZeroBridge{T, F}, - ::MOI.ListOfConstraintIndices{F, MOI.Zeros}) where {T, F} +function MOI.get( + bridge::SplitZeroBridge{T,F}, + ::MOI.ListOfConstraintIndices{F,MOI.Zeros}, +) where {T,F} return [bridge.constraint] end @@ -60,31 +82,44 @@ end # Attributes, Bridge acting as a constraint function MOI.supports( ::MOI.ModelLike, - ::Union{MOI.ConstraintPrimalStart, MOI.ConstraintDualStart}, - ::Type{<:SplitZeroBridge}) + ::Union{MOI.ConstraintPrimalStart,MOI.ConstraintDualStart}, + ::Type{<:SplitZeroBridge}, +) return true end -function MOI.get(model::MOI.ModelLike, attr::Union{MOI.ConstraintPrimal, MOI.ConstraintPrimalStart, MOI.ConstraintDual, MOI.ConstraintDualStart}, - bridge::SplitZeroBridge) +function MOI.get( + model::MOI.ModelLike, + attr::Union{ + MOI.ConstraintPrimal, + MOI.ConstraintPrimalStart, + MOI.ConstraintDual, + MOI.ConstraintDualStart, + }, + bridge::SplitZeroBridge, +) values = MOI.get(model, attr, bridge.constraint) output = zeros(Complex{eltype(values)}, bridge.dimension) for (i, idx) in enumerate(bridge.real_indices) output[idx] = values[i] end for (i, idx) in enumerate(bridge.imag_indices) - output[idx] = values[length(bridge.real_indices) + i] * im + output[idx] = values[length(bridge.real_indices)+i] * im end return output end -function MOI.set(model::MOI.ModelLike, attr::Union{MOI.ConstraintPrimalStart, MOI.ConstraintDualStart}, - bridge::SplitZeroBridge{T}, value) where T +function MOI.set( + model::MOI.ModelLike, + attr::Union{MOI.ConstraintPrimalStart,MOI.ConstraintDualStart}, + bridge::SplitZeroBridge{T}, + value, +) where {T} input = Vector{T}(undef, length(bridge.real_indices) + length(bridge.imag_indices)) for (i, idx) in enumerate(bridge.real_indices) input[i] = real(value[idx]) end for (i, idx) in enumerate(bridge.imag_indices) - input[length(bridge.real_indices) + i] = imag(value[idx]) + input[length(bridge.real_indices)+i] = imag(value[idx]) end MOI.set(model, attr, bridge.constraint, input) end diff --git a/src/Bridges/Variable/psd.jl b/src/Bridges/Variable/psd.jl index 94c8d9a..9765440 100644 --- a/src/Bridges/Variable/psd.jl +++ b/src/Bridges/Variable/psd.jl @@ -1,4 +1,4 @@ -const EQ{T} = MOI.ConstraintIndex{MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}} +const EQ{T} = MOI.ConstraintIndex{MOI.ScalarAffineFunction{T},MOI.EqualTo{T}} """ Let `H = HermitianToSymmetricPSDBridge(n)`, `S = PositiveSemidefiniteConeTriangle(2n)` @@ -37,18 +37,24 @@ so we can just ignore them. """ struct HermitianToSymmetricPSDBridge{T} <: MOIB.Variable.AbstractBridge variables::Vector{MOI.VariableIndex} - psd_constraint::MOI.ConstraintIndex{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle} + psd_constraint::MOI.ConstraintIndex{ + MOI.VectorOfVariables, + MOI.PositiveSemidefiniteConeTriangle, + } con_11_22::Vector{EQ{T}} con12diag::Vector{EQ{T}} con_12_21::Vector{EQ{T}} end function MOIB.Variable.bridge_constrained_variable( - ::Type{HermitianToSymmetricPSDBridge{T}}, model::MOI.ModelLike, - set::COI.HermitianPositiveSemidefiniteConeTriangle) where T + ::Type{HermitianToSymmetricPSDBridge{T}}, + model::MOI.ModelLike, + set::COI.HermitianPositiveSemidefiniteConeTriangle, +) where {T} n = set.side_dimension - variables, psd_constraint = MOI.add_constrained_variables(model, MOI.PositiveSemidefiniteConeTriangle(2n)) + variables, psd_constraint = + MOI.add_constrained_variables(model, MOI.PositiveSemidefiniteConeTriangle(2n)) k11 = 0 k12 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(n)) @@ -66,33 +72,62 @@ function MOIB.Variable.bridge_constrained_variable( con_11_22 = EQ{T}[] con12diag = EQ{T}[] con_12_21 = EQ{T}[] - for j in 1:n + for j = 1:n k22 += n - for i in 1:j + for i = 1:j k11 += 1 k12 += 1 k22 += 1 - push!(con_11_22, MOI.add_constraint(model, MOI.Utilities.operate(-, T, X11(), X22()), MOI.EqualTo(zero(T)))) + push!( + con_11_22, + MOI.add_constraint( + model, + MOI.Utilities.operate(-, T, X11(), X22()), + MOI.EqualTo(zero(T)), + ), + ) if i == j - push!(con12diag, MOI.add_constraint(model, convert(MOI.ScalarAffineFunction{T}, X12()), MOI.EqualTo(zero(T)))) + push!( + con12diag, + MOI.add_constraint( + model, + convert(MOI.ScalarAffineFunction{T}, X12()), + MOI.EqualTo(zero(T)), + ), + ) else - push!(con_12_21, MOI.add_constraint(model, MOI.Utilities.operate(+, T, X21(i, j), X12()), MOI.EqualTo(zero(T)))) + push!( + con_12_21, + MOI.add_constraint( + model, + MOI.Utilities.operate(+, T, X21(i, j), X12()), + MOI.EqualTo(zero(T)), + ), + ) end end k12 += n end - return HermitianToSymmetricPSDBridge(variables, psd_constraint, con_11_22, con12diag, con_12_21) + return HermitianToSymmetricPSDBridge( + variables, + psd_constraint, + con_11_22, + con12diag, + con_12_21, + ) end function MOIB.Variable.supports_constrained_variable( - ::Type{<:HermitianToSymmetricPSDBridge}, ::Type{COI.HermitianPositiveSemidefiniteConeTriangle}) + ::Type{<:HermitianToSymmetricPSDBridge}, + ::Type{COI.HermitianPositiveSemidefiniteConeTriangle}, +) return true end function MOIB.added_constrained_variable_types(::Type{<:HermitianToSymmetricPSDBridge}) return [(MOI.PositiveSemidefiniteConeTriangle,)] end -function MOIB.added_constraint_types(::Type{HermitianToSymmetricPSDBridge{T}}) where T +function MOIB.added_constraint_types(::Type{HermitianToSymmetricPSDBridge{T}}) where {T} return [(MOI.ScalarAffineFunction{T}, MOI.EqualTo{T})] end @@ -103,22 +138,31 @@ end function MOI.get(bridge::HermitianToSymmetricPSDBridge, ::MOI.ListOfVariableIndices) return bridge.variables end -function MOI.get(bridge::HermitianToSymmetricPSDBridge, - ::MOI.NumberOfConstraints{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle}) +function MOI.get( + bridge::HermitianToSymmetricPSDBridge, + ::MOI.NumberOfConstraints{MOI.VectorOfVariables,MOI.PositiveSemidefiniteConeTriangle}, +) return 1 end -function MOI.get(bridge::HermitianToSymmetricPSDBridge, - ::MOI.ListOfConstraintIndices{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle}) +function MOI.get( + bridge::HermitianToSymmetricPSDBridge, + ::MOI.ListOfConstraintIndices{ + MOI.VectorOfVariables, + MOI.PositiveSemidefiniteConeTriangle, + }, +) return [bridge.psd_constraint] end -function MOI.get(bridge::HermitianToSymmetricPSDBridge{T}, - ::MOI.NumberOfConstraints{MOI.ScalarAffineFunction{T}, - MOI.EqualTo{T}}) where T +function MOI.get( + bridge::HermitianToSymmetricPSDBridge{T}, + ::MOI.NumberOfConstraints{MOI.ScalarAffineFunction{T},MOI.EqualTo{T}}, +) where {T} return length(bridge.con_11_22) + length(bridge.con12diag) + length(bridge.con_12_21) end -function MOI.get(bridge::HermitianToSymmetricPSDBridge{T}, - ::MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{T}, - MOI.EqualTo{T}}) where T +function MOI.get( + bridge::HermitianToSymmetricPSDBridge{T}, + ::MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{T},MOI.EqualTo{T}}, +) where {T} return [bridge.con_11_22; bridge.con12diag; bridge.con_12_21] end @@ -138,8 +182,11 @@ end # Attributes, Bridge acting as a constraint -function MOI.get(model::MOI.ModelLike, ::MOI.ConstraintSet, - bridge::HermitianToSymmetricPSDBridge) +function MOI.get( + model::MOI.ModelLike, + ::MOI.ConstraintSet, + bridge::HermitianToSymmetricPSDBridge, +) return COI.HermitianPositiveSemidefiniteConeTriangle(length(bridge.con12diag)) end @@ -172,18 +219,24 @@ function _variable(bridge::HermitianToSymmetricPSDBridge, i::MOIB.IndexInVector) return bridge.variables[_variable_map(i, length(bridge.con12diag))] end -function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal, - bridge::HermitianToSymmetricPSDBridge{T}) where T +function MOI.get( + model::MOI.ModelLike, + attr::MOI.ConstraintPrimal, + bridge::HermitianToSymmetricPSDBridge{T}, +) where {T} values = MOI.get(model, attr, bridge.psd_constraint) M = MOI.dimension(MOI.get(model, MOI.ConstraintSet(), bridge)) n = length(bridge.con12diag) - return [values[_variable_map(MOIB.IndexInVector(i), n)] for i in 1:M] + return [values[_variable_map(MOIB.IndexInVector(i), n)] for i = 1:M] end # See docstring of bridge for why we ignore the dual of the constraints # `con_11_22`, `con_12_21` and `con12diag`. -function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintDual, - bridge::HermitianToSymmetricPSDBridge{T}) where T +function MOI.get( + model::MOI.ModelLike, + attr::MOI.ConstraintDual, + bridge::HermitianToSymmetricPSDBridge{T}, +) where {T} dual = MOI.get(model, attr, bridge.psd_constraint) M = MOI.dimension(MOI.get(model, MOI.ConstraintSet(), bridge)) mapped = zeros(T, M) @@ -194,10 +247,10 @@ function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintDual, k21 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(2n)) + 1 k22 = N k = 0 - for j in 1:n + for j = 1:n k21 -= n + 1 - j k22 += n - for i in 1:j + for i = 1:j k11 += 1 k12 += 1 k21 -= 1 @@ -206,8 +259,8 @@ function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintDual, mapped[k11] += dual[k22] if i != j k += 1 - mapped[N + k] += dual[k12] - mapped[N + k] -= dual[k21] + mapped[N+k] += dual[k12] + mapped[N+k] -= dual[k21] end end k12 += n @@ -216,17 +269,27 @@ function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintDual, return mapped end -function MOI.get(model::MOI.ModelLike, attr::MOI.VariablePrimal, - bridge::HermitianToSymmetricPSDBridge{T}, i::MOIB.IndexInVector) where T +function MOI.get( + model::MOI.ModelLike, + attr::MOI.VariablePrimal, + bridge::HermitianToSymmetricPSDBridge{T}, + i::MOIB.IndexInVector, +) where {T} value = MOI.get(model, attr, _variable(bridge, i)) end -function MOIB.bridged_function(bridge::HermitianToSymmetricPSDBridge{T}, i::MOIB.IndexInVector) where T +function MOIB.bridged_function( + bridge::HermitianToSymmetricPSDBridge{T}, + i::MOIB.IndexInVector, +) where {T} func = _variable(bridge, i) return convert(MOI.ScalarAffineFunction{T}, func) end -function MOIB.Variable.unbridged_map(bridge::HermitianToSymmetricPSDBridge{T}, vi::MOI.VariableIndex, - i::MOIB.IndexInVector) where T +function MOIB.Variable.unbridged_map( + bridge::HermitianToSymmetricPSDBridge{T}, + vi::MOI.VariableIndex, + i::MOIB.IndexInVector, +) where {T} func = convert(MOI.ScalarAffineFunction{T}, vi) return (_variable(bridge, i) => func,) end diff --git a/src/ComplexOptInterface.jl b/src/ComplexOptInterface.jl index 04b1706..50f7140 100644 --- a/src/ComplexOptInterface.jl +++ b/src/ComplexOptInterface.jl @@ -11,14 +11,17 @@ struct HermitianPositiveSemidefiniteConeTriangle <: MOI.AbstractVectorSet end function MOI.dimension(set::HermitianPositiveSemidefiniteConeTriangle) return MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(set.side_dimension)) + - MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(set.side_dimension - 1)) + MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(set.side_dimension - 1)) end -function MOI.Utilities.set_dot(x::AbstractVector, y::AbstractVector, - set::HermitianPositiveSemidefiniteConeTriangle) +function MOI.Utilities.set_dot( + x::AbstractVector, + y::AbstractVector, + set::HermitianPositiveSemidefiniteConeTriangle, +) sym = MOI.PositiveSemidefiniteConeTriangle(set.side_dimension) result = MOI.Utilities.set_dot(x, y, sym) - for k in (MOI.dimension(sym) + 1):MOI.dimension(set) + for k = (MOI.dimension(sym)+1):MOI.dimension(set) result = MA.add_mul!!(result, 2, x[k], y[k]) end return result diff --git a/test/runtests.jl b/test/runtests.jl index 4b2b179..25a8cc3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -34,17 +34,28 @@ function projection_test(optimizer, config) x11 = x[1:3] x12 = x[4] t = MOI.add_variable(optimizer) - MOI.add_constraint(optimizer, MOI.Utilities.operate(vcat, Float64, t, x[1] - 1.0, √2 * (x[2] + 1.0), x[3] + 1.0, √2 * (x[4] - 1.0)), - MOI.SecondOrderCone(5)) + MOI.add_constraint( + optimizer, + MOI.Utilities.operate( + vcat, + Float64, + t, + x[1] - 1.0, + √2 * (x[2] + 1.0), + x[3] + 1.0, + √2 * (x[4] - 1.0), + ), + MOI.SecondOrderCone(5), + ) MOI.set(optimizer, MOI.ObjectiveSense(), MOI.MIN_SENSE) MOI.set(optimizer, MOI.ObjectiveFunction{typeof(t)}(), t) MOI.optimize!(optimizer) - primal = [(1 + √3) / 2, -1/2, (-1 + √3)/2, 1/2] + primal = [(1 + √3) / 2, -1 / 2, (-1 + √3) / 2, 1 / 2] dual = [(3 - √3) / 6, 0.2886751198, (3 + √3) / 6, -0.2886751197] - @test MOI.Utilities.set_dot(primal, dual, set) ≈ 0 atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.VariablePrimal(), x) ≈ primal atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintPrimal(), cx) ≈ primal atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintDual(), cx) ≈ dual atol=atol rtol=rtol + @test MOI.Utilities.set_dot(primal, dual, set) ≈ 0 atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.VariablePrimal(), x) ≈ primal atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.ConstraintPrimal(), cx) ≈ primal atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.ConstraintDual(), cx) ≈ dual atol = atol rtol = rtol end function hermitian_psd_test(optimizer, config) @@ -54,12 +65,16 @@ function hermitian_psd_test(optimizer, config) MOI.empty!(optimizer) set = COI.HermitianPositiveSemidefiniteConeTriangle(3) x, cx = MOI.add_constrained_variables(optimizer, set) - MOI.add_constraints(optimizer, x, MOI.EqualTo.([1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0])) + MOI.add_constraints( + optimizer, + x, + MOI.EqualTo.([1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0]), + ) MOI.optimize!(optimizer) primal = [1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0] - @test MOI.get(optimizer, MOI.VariablePrimal(), x) ≈ primal atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintPrimal(), cx) ≈ primal atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintDual(), cx) ≈ zeros(9) atol=atol rtol=rtol + @test MOI.get(optimizer, MOI.VariablePrimal(), x) ≈ primal atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.ConstraintPrimal(), cx) ≈ primal atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.ConstraintDual(), cx) ≈ zeros(9) atol = atol rtol = rtol end function zero_1_test(optimizer, config) @@ -72,15 +87,19 @@ function zero_1_test(optimizer, config) c = MOI.add_constraint( optimizer, MOI.Utilities.operate(vcat, Complex{Float64}, func), - MOI.Zeros(1) + MOI.Zeros(1), ) MOI.optimize!(optimizer) @test MOI.get(optimizer, MOI.TerminationStatus()) == MOI.OPTIMAL - @test MOI.get(optimizer, MOI.VariablePrimal(), x) ≈ [2/3, 1/3] atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintPrimal(), cx) ≈ [2/3, 1/3] atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintDual(), cx) ≈ zeros(2) atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintPrimal(), c) ≈ [0.0 + 0.0im] atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintDual(), c) ≈ [0.0 + 0.0im] atol=atol rtol=rtol + @test MOI.get(optimizer, MOI.VariablePrimal(), x) ≈ [2 / 3, 1 / 3] atol = atol rtol = + rtol + @test MOI.get(optimizer, MOI.ConstraintPrimal(), cx) ≈ [2 / 3, 1 / 3] atol = atol rtol = + rtol + @test MOI.get(optimizer, MOI.ConstraintDual(), cx) ≈ zeros(2) atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.ConstraintPrimal(), c) ≈ [0.0 + 0.0im] atol = atol rtol = + rtol + @test MOI.get(optimizer, MOI.ConstraintDual(), c) ≈ [0.0 + 0.0im] atol = atol rtol = + rtol end function zero_2_test(optimizer, config) @@ -93,31 +112,50 @@ function zero_2_test(optimizer, config) c = MOI.add_constraint( optimizer, MOI.Utilities.operate(vcat, Complex{Float64}, func), - MOI.Zeros(1) + MOI.Zeros(1), ) MOI.optimize!(optimizer) @test MOI.get(optimizer, MOI.TerminationStatus()) == MOI.OPTIMAL - @test MOI.get(optimizer, MOI.VariablePrimal(), x) ≈ [2.0] atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintPrimal(), cx) ≈ [2.0] atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintDual(), cx) ≈ zeros(1) atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintPrimal(), c) ≈ [0.0 + 0.0im] atol=atol rtol=rtol - @test MOI.get(optimizer, MOI.ConstraintDual(), c) ≈ [0.0 + 0.0im] atol=atol rtol=rtol + @test MOI.get(optimizer, MOI.VariablePrimal(), x) ≈ [2.0] atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.ConstraintPrimal(), cx) ≈ [2.0] atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.ConstraintDual(), cx) ≈ zeros(1) atol = atol rtol = rtol + @test MOI.get(optimizer, MOI.ConstraintPrimal(), c) ≈ [0.0 + 0.0im] atol = atol rtol = + rtol + @test MOI.get(optimizer, MOI.ConstraintDual(), c) ≈ [0.0 + 0.0im] atol = atol rtol = + rtol end import CSDP @testset "CSDP" begin - config = MOI.Test.Config(atol=1e-4, rtol=1e-4) - bridged = MOI.instantiate(CSDP.Optimizer, with_bridge_type=Float64) - MOI.Bridges.add_bridge(bridged, COI.Bridges.Variable.HermitianToSymmetricPSDBridge{Float64}) + config = MOI.Test.Config(atol = 1e-4, rtol = 1e-4) + bridged = MOI.instantiate(CSDP.Optimizer, with_bridge_type = Float64) + MOI.Bridges.add_bridge( + bridged, + COI.Bridges.Variable.HermitianToSymmetricPSDBridge{Float64}, + ) projection_test(bridged, config) hermitian_psd_test(bridged, config) - bridged = MOI.Bridges.LazyBridgeOptimizer(MOI.Utilities.CachingOptimizer(MOI.Utilities.Model{Float64}(), CSDP.Optimizer())) + bridged = MOI.Bridges.LazyBridgeOptimizer( + MOI.Utilities.CachingOptimizer(MOI.Utilities.Model{Float64}(), CSDP.Optimizer()), + ) MOI.Bridges.add_bridge(bridged, MOI.Bridges.Constraint.ScalarizeBridge{Float64}) MOI.Bridges.add_bridge(bridged, COI.Bridges.Constraint.SplitZeroBridge{Float64}) zero_1_test(bridged, config) - cis = MOI.get(bridged.model, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}}()) + cis = MOI.get( + bridged.model, + MOI.ListOfConstraintIndices{ + MOI.ScalarAffineFunction{Float64}, + MOI.EqualTo{Float64}, + }(), + ) @test length(cis) == 2 zero_2_test(bridged, config) - cis = MOI.get(bridged.model, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}}()) + cis = MOI.get( + bridged.model, + MOI.ListOfConstraintIndices{ + MOI.ScalarAffineFunction{Float64}, + MOI.EqualTo{Float64}, + }(), + ) @test length(cis) == 1 end