diff --git a/src/MOI_wrapper.jl b/src/MOI_wrapper.jl index d5ef9173..88bc3e82 100644 --- a/src/MOI_wrapper.jl +++ b/src/MOI_wrapper.jl @@ -519,11 +519,11 @@ function MOI.set( c::MOI.ConstraintIndex{MOI.ScalarQuadraticFunction{T},S}, name::String, ) where {T,S<:MOI.AbstractSet} + c_aux = c if haskey(model.quadratic_outer_to_inner, c) - MOI.set(model.optimizer, attr, model.quadratic_outer_to_inner[c], name) - else - MOI.set(model.optimizer, attr, c, name) + c_aux = model.quadratic_outer_to_inner[c] end + MOI.set(model.optimizer, attr, c_aux, name) return end @@ -533,16 +533,11 @@ function MOI.set( c::MOI.ConstraintIndex{MOI.VectorQuadraticFunction{T},S}, name::String, ) where {T,S<:MOI.AbstractSet} + c_aux = c if haskey(model.vector_quadratic_outer_to_inner, c) - MOI.set( - model.optimizer, - attr, - model.vector_quadratic_outer_to_inner[c], - name, - ) - else - MOI.set(model.optimizer, attr, c, name) + c_aux = model.vector_quadratic_outer_to_inner[c] end + MOI.set(model.optimizer, attr, c_aux, name) return end @@ -565,11 +560,11 @@ function MOI.get( attr::MOI.ConstraintName, c::MOI.ConstraintIndex{MOI.ScalarQuadraticFunction{T},S}, ) where {T,S<:MOI.AbstractSet} + c_aux = c if haskey(model.quadratic_outer_to_inner, c) - return MOI.get(model.optimizer, attr, model.quadratic_outer_to_inner[c]) - else - return MOI.get(model.optimizer, attr, c) + c_aux = model.quadratic_outer_to_inner[c] end + return MOI.get(model.optimizer, attr, c_aux) end function MOI.get( @@ -577,15 +572,11 @@ function MOI.get( attr::MOI.ConstraintName, c::MOI.ConstraintIndex{MOI.VectorQuadraticFunction{T},S}, ) where {T,S<:MOI.AbstractSet} + c_aux = c if haskey(model.vector_quadratic_outer_to_inner, c) - return MOI.get( - model.optimizer, - attr, - model.vector_quadratic_outer_to_inner[c], - ) - else - return MOI.get(model.optimizer, attr, c) + c_aux = model.vector_quadratic_outer_to_inner[c] end + return MOI.get(model.optimizer, attr, c_aux) end function MOI.get( @@ -979,10 +970,6 @@ function _is_vector_affine(f::MOI.VectorQuadraticFunction{T}) where {T} return isempty(f.quadratic_terms) end -function _is_vector_affine(::MOI.VectorAffineFunction{T}) where {T} - return true # VectorAffineFunction is always affine -end - function _add_constraint_with_parameters_on_function( model::Optimizer, f::MOI.VectorQuadraticFunction{T}, @@ -1037,15 +1024,15 @@ function MOI.delete( model::Optimizer, c::MOI.ConstraintIndex{F,S}, ) where {F<:MOI.VectorQuadraticFunction,S<:MOI.AbstractSet} + c_aux = c if haskey(model.vector_quadratic_outer_to_inner, c) ci_inner = model.vector_quadratic_outer_to_inner[c] delete!(model.vector_quadratic_outer_to_inner, c) delete!(model.vector_quadratic_constraint_cache, ci_inner) delete!(model.vector_quadratic_constraint_cache_set, ci_inner) - MOI.delete(model.optimizer, ci_inner) - else - MOI.delete(model.optimizer, c) + c_aux = ci_inner end + MOI.delete(model.optimizer, c_aux) delete!(model.constraint_outer_to_inner, c) return end @@ -1054,15 +1041,15 @@ function MOI.delete( model::Optimizer, c::MOI.ConstraintIndex{F,S}, ) where {F<:MOI.ScalarQuadraticFunction,S<:MOI.AbstractSet} + c_aux = c if haskey(model.quadratic_outer_to_inner, c) ci_inner = model.quadratic_outer_to_inner[c] delete!(model.quadratic_outer_to_inner, c) delete!(model.quadratic_constraint_cache, ci_inner) delete!(model.quadratic_constraint_cache_set, ci_inner) - MOI.delete(model.optimizer, ci_inner) - else - MOI.delete(model.optimizer, c) + c_aux = ci_inner end + MOI.delete(model.optimizer, c_aux) delete!(model.constraint_outer_to_inner, c) return end @@ -1463,6 +1450,19 @@ function MOI.get( return model.parameters[p_idx(v)] end +function MOI.get( + model::Optimizer, + ::MOI.ConstraintPrimalStart, + c::MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{T}}, +) where {T} + v = MOI.VariableIndex(c.value) + if _parameter_in_model(model, v) + return model.parameters[p_idx(v)] + else + error("Variable not in the model") + end +end + function MOI.set( model::Optimizer, ::MOI.ConstraintPrimalStart, diff --git a/test/jump_tests.jl b/test/jump_tests.jl index f3e3f6f3..d36e3ed6 100644 --- a/test/jump_tests.jl +++ b/test/jump_tests.jl @@ -1297,6 +1297,10 @@ function test_jump_psd_cone_with_parameter_pv() con, [0, (p * x - 1), 0] in MOI.PositiveSemidefiniteConeTriangle(2) ) + @test MOI.get(backend(model), MOI.ConstraintFunction(), index(con)) isa + MOI.VectorQuadraticFunction{Float64} + @test MOI.get(backend(model), MOI.ConstraintSet(), index(con)) isa + MOI.PositiveSemidefiniteConeTriangle # the above constraint is equivalent to # - (p * x -1)^2 >=0 -> (p * x -1)^2 <= 0 -> (p * x -1) == 0 -> p*x == 1 @test is_valid(model, con) @@ -1439,13 +1443,13 @@ function test_jump_psd_cone_with_parameter_p_v_pv() con, [p, (2 * x - 3), p * 3 * x] in MOI.PositiveSemidefiniteConeTriangle(2) ) - @objective(model, Min, x) + @objective(model, Min, x * x - p * p) @test is_valid(model, con) optimize!(model) - @test value(x) ≈ 0.7499854 atol = 1e-5 + @test value(x) ≈ 0.7499854 atol = 1e-3 set_parameter_value(p, 3.0) optimize!(model) - @test value(x) ≈ 0.236506 atol = 1e-5 + @test value(x) ≈ 0.236506 atol = 1e-3 return delete(model, con) end @@ -1466,11 +1470,11 @@ function test_jump_psd_cone_with_parameter_p_v_pp() con, [p, (2 * x - 3), p * 3 * p] in MOI.PositiveSemidefiniteConeTriangle(2) ) - @objective(model, Min, x) + @objective(model, Min, x - p) @test is_valid(model, con) optimize!(model) @test value(x) ≈ 0.633969 atol = 1e-5 - set_parameter_value(p, 3.0) + set_parameter_value(p, Float32(3.0)) optimize!(model) @test value(x) ≈ -2.9999734 atol = 1e-5 return delete(model, con) @@ -1561,6 +1565,17 @@ function test_variable_and_constraint_not_registered() MOI.ConstraintSet(), index(ParameterRef(p1)), ) + @test_throws ErrorException("Variable not in the model") MOI.set( + backend(model2), + MOI.ConstraintPrimalStart(), + index(ParameterRef(p1)), + 1.0, + ) + @test_throws ErrorException("Variable not in the model") MOI.get( + backend(model2), + MOI.ConstraintPrimalStart(), + index(ParameterRef(p1)), + ) @test_throws ErrorException("Variable not in the model") MOI.set( backend(model2), MOI.ObjectiveFunction{MOI.VariableIndex}(), diff --git a/test/moi_tests.jl b/test/moi_tests.jl index f5db78c6..9d81adfd 100644 --- a/test/moi_tests.jl +++ b/test/moi_tests.jl @@ -2073,3 +2073,14 @@ function test_psd_cone_with_parameter() MOI.set(model, MOI.ConstraintName(), c_index, "psd_cone") @test MOI.get(model, MOI.ConstraintName(), c_index) == "psd_cone" end + +function test_copy_model() + model = MOI.Utilities.Model{Float64}() + x = MOI.add_variable(model) + c = MOI.add_constraint(model, 1.0 * x, MOI.EqualTo(1.0)) + MOI.set(model, MOI.ConstraintName(), c, "c") + poi = POI.Optimizer(GLPK.Optimizer()) + MOI.copy_to(poi, model) + MOI.optimize!(poi) + @test MOI.get(poi, MOI.VariablePrimal(), x) ≈ 1.0 +end