diff --git a/src/constrained_variables.jl b/src/constrained_variables.jl index 681a250..89c1f31 100644 --- a/src/constrained_variables.jl +++ b/src/constrained_variables.jl @@ -89,10 +89,11 @@ function _get_parameter_variables(::PrimalDualMap{T}, primal_model) where {T} primal_model, MOI.ListOfConstraintIndices{MOI.VariableIndex,MOI.Parameter{T}}(), ) - parameters = Set{MOI.VariableIndex}() + parameters = Dict{MOI.VariableIndex,MOI.Parameter{T}}() for ci in cis vi = MOI.get(primal_model, MOI.ConstraintFunction(), ci) - push!(parameters, vi) + set = MOI.get(primal_model, MOI.ConstraintSet(), ci) + parameters[vi] = set end return parameters end diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 980fb65..73280be 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -114,6 +114,7 @@ function _add_primal_parameter_vars( primal_model::MOI.ModelLike, primal_dual_map::PrimalDualMap{T}, dual_names::DualNames, + moi_parameter_sets::Dict{MOI.VariableIndex,MOI.Parameter{T}}, variable_parameters::Vector{MOI.VariableIndex}, primal_objective, ignore_objective::Bool, @@ -134,15 +135,22 @@ function _add_primal_parameter_vars( variable_parameters end vis = MOI.add_variables(dual_model, length(parameters)) + + moi_parameters = keys(moi_parameter_sets) for i in eachindex(vis) - primal_dual_map.primal_parameter_to_dual_parameter[parameters[i]] = - vis[i] + pvi = parameters[i] + dvi = vis[i] + + if pvi in moi_parameters + MOI.add_constraint(dual_model, dvi, moi_parameter_sets[pvi]) + end + primal_dual_map.primal_parameter_to_dual_parameter[pvi] = dvi if !is_empty(dual_names) - vi_name = MOI.get(primal_model, MOI.VariableName(), parameters[i]) + pvi_name = MOI.get(primal_model, MOI.VariableName(), pvi) prefix = dual_names.parameter_name_prefix == "" ? "param_" : dual_names.parameter_name_prefix - MOI.set(dual_model, MOI.VariableName(), vis[i], prefix * vi_name) + MOI.set(dual_model, MOI.VariableName(), dvi, prefix * pvi_name) end end return diff --git a/src/dualize.jl b/src/dualize.jl index f14a5db..d3dcdad 100644 --- a/src/dualize.jl +++ b/src/dualize.jl @@ -87,10 +87,10 @@ function dualize( supported_constraints(con_types) # Errors if constraint cant be dualized # merge user listed parameters and MOI.VariableIndex-in-MOI.Parameter{T} - moi_parameters = + moi_parameter_sets = _get_parameter_variables(dual_problem.primal_dual_map, primal_model) all_parameters = Set{MOI.VariableIndex}(_variable_parameters) - for p in moi_parameters + for p in keys(moi_parameter_sets) push!(all_parameters, p) end variable_parameters = collect(all_parameters) @@ -165,6 +165,7 @@ function dualize( primal_model, dual_problem.primal_dual_map, dual_names, + moi_parameter_sets, variable_parameters, primal_objective, ignore_objective, diff --git a/test/Tests/test_partial_dual_quadratic.jl b/test/Tests/test_partial_dual_quadratic.jl index a064570..14af7ac 100644 --- a/test/Tests/test_partial_dual_quadratic.jl +++ b/test/Tests/test_partial_dual_quadratic.jl @@ -180,6 +180,7 @@ @test Set(list_of_cons) == Set( [ (MOI.VariableIndex, MOI.GreaterThan{Float64}) + (MOI.VariableIndex, MOI.Parameter{Float64}) (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}) ], ) @@ -288,6 +289,18 @@ @test primal_parameter_to_dual_parameter[MOI.VariableIndex(3)] == MOI.VariableIndex(2 + 1) + @test MOI.get( + dual_model, + MOI.ConstraintSet(), + MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{Float64}}( + primal_parameter_to_dual_parameter[MOI.VariableIndex(3)].value, + ), + ) == MOI.get( + primal_model, + MOI.ConstraintSet(), + MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{Float64}}(3), + ) + primal_var_in_quad_obj_to_dual_slack_var = primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var @test primal_var_in_quad_obj_to_dual_slack_var[MOI.VariableIndex(1)] ==