From d2ec92f189ac668be30a70022833e2214fe3525d Mon Sep 17 00:00:00 2001 From: joaquimg Date: Tue, 29 Apr 2025 03:23:07 -0300 Subject: [PATCH 1/5] [WIP] Improve JuMP API --- docs/src/reference.md | 4 +- src/Dualization.jl | 1 + src/JuMP.jl | 124 +++++++++++++++++++++++++++++++ src/dual_equality_constraints.jl | 10 +-- src/dual_model_variables.jl | 2 +- src/dualize.jl | 59 --------------- src/structures.jl | 55 +++++++++++--- 7 files changed, 177 insertions(+), 78 deletions(-) create mode 100644 src/JuMP.jl diff --git a/docs/src/reference.md b/docs/src/reference.md index e09f1c89..efd7b5cc 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -4,7 +4,7 @@ Dualization.supported_constraints Dualization.supported_objective Dualization.DualNames -Dualization.VariableData -Dualization.ConstraintData +Dualization.PrimalVariableData +Dualization.PrimalConstraintData Dualization.PrimalDualMap ``` \ No newline at end of file diff --git a/src/Dualization.jl b/src/Dualization.jl index 957b7865..7986f518 100644 --- a/src/Dualization.jl +++ b/src/Dualization.jl @@ -23,5 +23,6 @@ include("dual_model_variables.jl") include("dual_equality_constraints.jl") include("dualize.jl") include("MOI_wrapper.jl") +include("JuMP.jl") end # module diff --git a/src/JuMP.jl b/src/JuMP.jl new file mode 100644 index 00000000..bfba8e01 --- /dev/null +++ b/src/JuMP.jl @@ -0,0 +1,124 @@ +function dualize(model::JuMP.Model, optimizer_constructor = nothing; kwargs...) + mode = JuMP.mode(model) + if mode != JuMP.AUTOMATIC + error("Dualization does not support solvers in $(mode) mode") + end + dual_model = JuMP.Model() + dual_problem = DualProblem(JuMP.backend(dual_model)) + dualize(JuMP.backend(model), dual_problem; kwargs...) + _fill_obj_dict_with_variables!(dual_model) + _fill_obj_dict_with_constraints!(dual_model) + if optimizer_constructor !== nothing + JuMP.set_optimizer(dual_model, optimizer_constructor) + end + dual_model.ext[:_Dualization_jl_PrimalDualMap] = + dual_problem.primal_dual_map + return dual_model +end + +function _fill_obj_dict_with_variables!(model::JuMP.Model) + list = MOI.get(model, MOI.ListOfVariableAttributesSet()) + if !(MOI.VariableName() in list) + return + end + for vi in MOI.get(model, MOI.ListOfVariableIndices()) + name = MOI.get(JuMP.backend(model), MOI.VariableName(), vi) + if !isempty(name) + model[Symbol(name)] = JuMP.VariableRef(model, vi) + end + end + return +end + +function _fill_obj_dict_with_constraints!(model::JuMP.Model) + con_types = MOI.get(model, MOI.ListOfConstraintTypesPresent()) + for (F, S) in con_types + _fill_obj_dict_with_constraints!(model, F, S) + end + return +end + +function _fill_obj_dict_with_constraints!( + model::JuMP.Model, + ::Type{F}, + ::Type{S}, +) where {F,S} + list = MOI.get(model, MOI.ListOfConstraintAttributesSet{F,S}()) + if !(MOI.ConstraintName() in list) + return + end + for ci in MOI.get(JuMP.backend(model), MOI.ListOfConstraintIndices{F,S}()) + name = MOI.get(JuMP.backend(model), MOI.ConstraintName(), ci) + if !isempty(name) + model[Symbol(name)] = JuMP.constraint_ref_with_index(model, ci) + end + end + return +end + +function _get_primal_dual_map(model::JuMP.Model) + return model.ext[:_Dualization_jl_PrimalDualMap] +end + +function _get_dual_constraint(dual_model, primal_ref::JuMP.VariableRef) + map = _get_primal_dual_map(dual_model) + moi_primal_vi = JuMP.index(primal_ref) + moi_dual_ci, idx = _get_dual_constraint(map, moi_primal_vi) + # dual_model = nothing # TODO + if idx === nothing + # variables fixed at zero + return nothing, idx + end + return JuMP.constraint_ref_with_index(dual_model, moi_dual_ci), idx +end + +# necessary? +# function get_primal_constraint(primal_vi::JuMP.VariableRef) +# primal_model = JuMP.owner_model(dual_model) +# map = _get_primal_dual_map(primal_model) +# moi_primal_vi = JuMP.index(primal_vi) +# primal_ci, idx = get_primal_constraint(map, moi_primal_vi) +# return JuMP.constraint_ref_with_index(primal_model, primal_ci), idx +# end + +function _get_dual_variables( + dual_model::JuMP.Model, + primal_ref::JuMP.ConstraintRef, +) + map = _get_primal_dual_map(dual_model) + moi_primal_ci = JuMP.index(primal_ref) + moi_dual_vis = _get_dual_variables(map, moi_primal_ci) + if moi_dual_vis === nothing + # main constraint of a constrained variable + return nothing + end + return [JuMP.VariableRef(dual_model, vi) for vi in moi_dual_vis] +end + +# this is a constrained variable constraint +function _get_dual_constraint( + dual_model::JuMP.Model, + primal_ref::JuMP.ConstraintRef, +) + map = _get_primal_dual_map(dual_model) + moi_primal_ci = JuMP.index(primal_ref) + moi_dual_ci = _get_dual_constraint(map, moi_primal_ci) + if moi_dual_ci === nothing + # main constraint of a constrained variable + # or + # primal constraint is equality + return nothing + end + return JuMP.constraint_ref_with_index(dual_model, moi_dual_ci) +end + +function _get_dual_parameter( + dual_model::JuMP.Model, + primal_ref::JuMP.VariableRef, +) + map = _get_primal_dual_map(dual_model) + moi_primal_vi = JuMP.index(primal_ref) + moi_dual_vi = _get_dual_parameter(map, moi_primal_vi) + # the above line might error + return JuMP.VariableRef(dual_model, moi_dual_vi) +end diff --git a/src/dual_equality_constraints.jl b/src/dual_equality_constraints.jl index 098091a7..d5a74ded 100644 --- a/src/dual_equality_constraints.jl +++ b/src/dual_equality_constraints.jl @@ -113,7 +113,7 @@ function _add_dual_equality_constraints( end # Add primal variable to dual contraint to the link dictionary primal_dual_map.primal_variable_data[primal_vi] = - VariableData{T}(nothing, -1, dual_ci, nothing) + PrimalVariableData{T}(nothing, -1, dual_ci, nothing) end return scalar_affine_terms end @@ -139,7 +139,7 @@ function _add_constrained_variable_constraint( sense_change * get(scalar_terms, vi, zero(T)), ) primal_dual_map.primal_variable_data[vi] = - VariableData{T}(ci, i, nothing, dual_function) + PrimalVariableData{T}(ci, i, nothing, dual_function) end return end @@ -172,7 +172,7 @@ function _add_constrained_variable_constraint( dual_ci = MOI.add_constraint(dual_model, func_dual, set_dual) for (i, vi) in enumerate(vis) primal_dual_map.primal_variable_data[vi] = - VariableData{T}(ci, i, dual_ci, nothing) + PrimalVariableData{T}(ci, i, dual_ci, nothing) end if !is_empty(dual_names) @warn( @@ -199,7 +199,7 @@ function _add_constrained_variable_constraint( sense_change * get(scalar_terms, vi, zero(T)), ) primal_dual_map.primal_variable_data[vi] = - VariableData{T}(ci, 0, nothing, dual_function) + PrimalVariableData{T}(ci, 0, nothing, dual_function) return end @@ -226,7 +226,7 @@ function _add_constrained_variable_constraint( set_dual, ) primal_dual_map.primal_variable_data[vi] = - VariableData{T}(ci, 0, dual_ci, nothing) + PrimalVariableData{T}(ci, 0, dual_ci, nothing) if !is_empty(dual_names) _set_dual_constraint_name( dual_model, diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 604c1c80..53358b6d 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -86,7 +86,7 @@ function _add_dual_variable( T[] end primal_dual_map.primal_constraint_data[ci] = - ConstraintData(set_constant, vis, con_index) + PrimalConstraintData(set_constant, vis, con_index) # Get constraint name ci_name = MOI.get(primal_model, MOI.ConstraintName(), ci) # Add each vi to the dictionary diff --git a/src/dualize.jl b/src/dualize.jl index fcc85180..3a3fb98a 100644 --- a/src/dualize.jl +++ b/src/dualize.jl @@ -207,62 +207,3 @@ function dualize( end return dual_problem end - -function dualize(model::JuMP.Model, optimizer_constructor = nothing; kwargs...) - mode = JuMP.mode(model) - if mode != JuMP.AUTOMATIC - error("Dualization does not support solvers in $(mode) mode") - end - dual_model = JuMP.Model() - dualize( - JuMP.backend(model), - DualProblem(JuMP.backend(dual_model)); - kwargs..., - ) - _fill_obj_dict_with_variables!(dual_model) - _fill_obj_dict_with_constraints!(dual_model) - if optimizer_constructor !== nothing - JuMP.set_optimizer(dual_model, optimizer_constructor) - end - return dual_model -end - -function _fill_obj_dict_with_variables!(model::JuMP.Model) - list = MOI.get(model, MOI.ListOfVariableAttributesSet()) - if !(MOI.VariableName() in list) - return - end - for vi in MOI.get(model, MOI.ListOfVariableIndices()) - name = MOI.get(JuMP.backend(model), MOI.VariableName(), vi) - if !isempty(name) - model[Symbol(name)] = JuMP.VariableRef(model, vi) - end - end - return -end - -function _fill_obj_dict_with_constraints!(model::JuMP.Model) - con_types = MOI.get(model, MOI.ListOfConstraintTypesPresent()) - for (F, S) in con_types - _fill_obj_dict_with_constraints!(model, F, S) - end - return -end - -function _fill_obj_dict_with_constraints!( - model::JuMP.Model, - ::Type{F}, - ::Type{S}, -) where {F,S} - list = MOI.get(model, MOI.ListOfConstraintAttributesSet{F,S}()) - if !(MOI.ConstraintName() in list) - return - end - for ci in MOI.get(JuMP.backend(model), MOI.ListOfConstraintIndices{F,S}()) - name = MOI.get(JuMP.backend(model), MOI.ConstraintName(), ci) - if !isempty(name) - model[Symbol(name)] = JuMP.constraint_ref_with_index(model, ci) - end - end - return -end diff --git a/src/structures.jl b/src/structures.jl index 64775fc4..0f57e280 100644 --- a/src/structures.jl +++ b/src/structures.jl @@ -26,7 +26,7 @@ MOI.Utilities.@model( ) """ - VariableData{T} + PrimalVariableData{T} Data structure used in `PrimalDualMap` to hold information about primal variables and their dual counterparts. @@ -55,9 +55,9 @@ variables and their dual counterparts. To got from the constrained variable constraint to the primal variable, use the `primal_constrained_variables` field of `PrimalDualMap`. -See also `PrimalDualMap` and `ConstraintData`. +See also `PrimalDualMap` and `PrimalConstraintData`. """ -struct VariableData{T} +struct PrimalVariableData{T} primal_constrained_variable_constraint::Union{Nothing,MOI.ConstraintIndex} primal_constrained_variable_index::Int dual_constraint::Union{Nothing,MOI.ConstraintIndex} @@ -66,7 +66,7 @@ end # constraints of primal constrained variables are not here """ - ConstraintData{T} + PrimalConstraintData{T} Data structure used in `PrimalDualMap` to hold information about primal constraints and their dual counterparts. @@ -85,7 +85,7 @@ added in the `primal_constrained_variables` field of `PrimalDualMap`. if primal set is `EqualTo` or `Zeros`, then the dual constraint is `Reals` then the dual variable is free (no constraint in the dual model). """ -struct ConstraintData{T} +struct PrimalConstraintData{T} primal_set_constants::Vector{T} dual_variables::Vector{MOI.VariableIndex} dual_constrained_variable_constraint::Union{Nothing,MOI.ConstraintIndex} @@ -98,14 +98,14 @@ Maps information from all structures of the primal to the dual model. Main maps: - * `primal_variable_data::Dict{MOI.VariableIndex,Dualization.VariableData{T}}`: + * `primal_variable_data::Dict{MOI.VariableIndex,Dualization.PrimalVariableData{T}}`: maps primal variable indices to their data. The data is a structure that contains information about the primal variable and its dual counterpart. In particular, it contains the primal constrained variable constraint index, the primal constrained variable index, the dual constraint index and the primal function for the case of constraints that are not added in the dual. - * `primal_constraint_data::Dict{MOI.ConstraintIndex,Dualization.ConstraintData{T}}`: + * `primal_constraint_data::Dict{MOI.ConstraintIndex,Dualization.PrimalConstraintData{T}}`: maps primal constraint indices to their data. The data is a structure that contains information about the primal constraint and its dual counterpart. In particular, it contains the primal set constants, the dual variables and @@ -125,8 +125,8 @@ Addtional maps "slack" variables. These primal variables might appear in other maps. """ mutable struct PrimalDualMap{T} - primal_variable_data::Dict{MOI.VariableIndex,VariableData{T}} - primal_constraint_data::Dict{MOI.ConstraintIndex,ConstraintData{T}} + primal_variable_data::Dict{MOI.VariableIndex,PrimalVariableData{T}} + primal_constraint_data::Dict{MOI.ConstraintIndex,PrimalConstraintData{T}} primal_constrained_variables::Dict{ MOI.ConstraintIndex, Vector{MOI.VariableIndex}, @@ -141,8 +141,8 @@ mutable struct PrimalDualMap{T} } function PrimalDualMap{T}() where {T} return new( - Dict{MOI.VariableIndex,VariableData{T}}(), - Dict{MOI.ConstraintIndex,ConstraintData{T}}(), + Dict{MOI.VariableIndex,PrimalVariableData{T}}(), + Dict{MOI.ConstraintIndex,PrimalConstraintData{T}}(), Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}(), # Dict{MOI.VariableIndex,MOI.VariableIndex}(), @@ -151,6 +151,39 @@ mutable struct PrimalDualMap{T} end end +function _get_dual_constraint(m::PrimalDualMap, vi::MOI.VariableIndex) + data = m.primal_variable_data[vi] + return data.dual_constraint, data.primal_constrained_variable_index +end + +function _get_primal_constraint(m::PrimalDualMap, vi::MOI.VariableIndex) + data = m.primal_variable_data[vi] + return data.primal_constrained_variable_constraint, + data.primal_constrained_variable_index +end + +function _get_dual_variables(m::PrimalDualMap, ci::MOI.ConstraintIndex) + if haskey(m.primal_constrained_variables, ci) + # if the constraint is a constrained variable, then the dual variable + # is the first element of the vector of dual variables + return m.primal_constraint_data[ci].dual_variables + end + return nothing # ci is a constrained variable constraint +end + +function _get_dual_constraint(m::PrimalDualMap, ci::MOI.ConstraintIndex) + if haskey(m.primal_constrained_variables, ci) + # if the constraint is a constrained variable, then the dual variable + # is the first element of the vector of dual variables + return m.primal_constraint_data[ci].dual_constrained_variable_constraint + end + return nothing # ci is a constrained variable constraint +end + +function _get_dual_parameter(m::PrimalDualMap, vi::MOI.VariableIndex) + return m.primal_parameter_to_dual_parameter[vi] +end + function Base.getproperty(m::PrimalDualMap{T}, name::Symbol) where {T} if name === :constrained_var_idx error( From 0a3cddd9dd7b19e89c2217f8c5a41569893ad697 Mon Sep 17 00:00:00 2001 From: joaquimg Date: Sun, 4 May 2025 17:27:45 -0300 Subject: [PATCH 2/5] add tests and fixes --- src/JuMP.jl | 21 ++++++++------ src/structures.jl | 4 +-- test/Tests/test_JuMP_dualize.jl | 51 +++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/JuMP.jl b/src/JuMP.jl index bfba8e01..b6cd60a4 100644 --- a/src/JuMP.jl +++ b/src/JuMP.jl @@ -72,14 +72,19 @@ function _get_dual_constraint(dual_model, primal_ref::JuMP.VariableRef) return JuMP.constraint_ref_with_index(dual_model, moi_dual_ci), idx end -# necessary? -# function get_primal_constraint(primal_vi::JuMP.VariableRef) -# primal_model = JuMP.owner_model(dual_model) -# map = _get_primal_dual_map(primal_model) -# moi_primal_vi = JuMP.index(primal_vi) -# primal_ci, idx = get_primal_constraint(map, moi_primal_vi) -# return JuMP.constraint_ref_with_index(primal_model, primal_ci), idx -# end +function _get_primal_constraint( + dual_model::JuMP.Model, + primal_vi::JuMP.VariableRef, +) + primal_model = JuMP.owner_model(primal_vi) + map = _get_primal_dual_map(dual_model) + moi_primal_vi = JuMP.index(primal_vi) + primal_ci, idx = _get_primal_constraint(map, moi_primal_vi) + if primal_ci === nothing + return nothing, idx + end + return JuMP.constraint_ref_with_index(primal_model, primal_ci), idx +end function _get_dual_variables( dual_model::JuMP.Model, diff --git a/src/structures.jl b/src/structures.jl index 0f57e280..6fc59143 100644 --- a/src/structures.jl +++ b/src/structures.jl @@ -163,7 +163,7 @@ function _get_primal_constraint(m::PrimalDualMap, vi::MOI.VariableIndex) end function _get_dual_variables(m::PrimalDualMap, ci::MOI.ConstraintIndex) - if haskey(m.primal_constrained_variables, ci) + if !haskey(m.primal_constrained_variables, ci) # if the constraint is a constrained variable, then the dual variable # is the first element of the vector of dual variables return m.primal_constraint_data[ci].dual_variables @@ -172,7 +172,7 @@ function _get_dual_variables(m::PrimalDualMap, ci::MOI.ConstraintIndex) end function _get_dual_constraint(m::PrimalDualMap, ci::MOI.ConstraintIndex) - if haskey(m.primal_constrained_variables, ci) + if !haskey(m.primal_constrained_variables, ci) # if the constraint is a constrained variable, then the dual variable # is the first element of the vector of dual variables return m.primal_constraint_data[ci].dual_constrained_variable_constraint diff --git a/test/Tests/test_JuMP_dualize.jl b/test/Tests/test_JuMP_dualize.jl index bb805064..47c1c9a9 100644 --- a/test/Tests/test_JuMP_dualize.jl +++ b/test/Tests/test_JuMP_dualize.jl @@ -60,17 +60,44 @@ end # Test that unnamed objects don't create a key `Symbol("")` in `dual_model`. @variable(model) - @constraint(model, x == y) + @constraint(model, c, x == y) dual_model = dualize(model; dual_names = DualNames("dual", "")) @test typeof(dual_model[:dualeqcon]) == VariableRef @test !haskey(dual_model, Symbol("")) + + for var in (x, y, z) + con = Dualization._get_dual_constraint(dual_model, x) + @test con[1] isa ConstraintRef + @test con[2] isa Int + end + + var = Dualization._get_dual_variables(dual_model, soccon) + @test var === nothing + con = Dualization._get_dual_constraint(dual_model, soccon) + @test con === nothing + + con = Dualization._get_primal_constraint(dual_model, y) + @test con[1] isa ConstraintRef + @test con[2] == 2 + + var = Dualization._get_dual_variables(dual_model, eqcon) + @test length(var) == 1 + @test var[1] isa VariableRef + con = Dualization._get_dual_constraint(dual_model, eqcon) + @test con === nothing + + var = Dualization._get_dual_variables(dual_model, c) + @test length(var) == 1 + @test var[1] isa VariableRef + con = Dualization._get_dual_constraint(dual_model, c) + @test con === nothing end @testset "JuMP_dualize_kwargs" begin model = Model() @variable(model, x >= 0) - @constraint(model, x <= 2) + @constraint(model, c, x <= 2) @objective(model, Max, 2 * x + 1) dual_model = Dualization.dualize( model; @@ -80,5 +107,25 @@ end ) @test dual_model isa Model @test num_variables(dual_model) == 2 + con = Dualization._get_dual_constraint(dual_model, x) + @test con[1] isa ConstraintRef + @test con[2] == -1 + + con = Dualization._get_primal_constraint(dual_model, x) + @test con[1] === nothing + @test con[2] == -1 + + var = Dualization._get_dual_variables(dual_model, c) + @test length(var) == 1 + @test var[] isa VariableRef + con = Dualization._get_dual_constraint(dual_model, c) + @test con isa ConstraintRef + + cv = LowerBoundRef(x) + var = Dualization._get_dual_variables(dual_model, cv) + @test length(var) == 1 + @test var[] isa VariableRef + con = Dualization._get_dual_constraint(dual_model, cv) + @test con isa ConstraintRef end end From e10a22dd606e2c31b3fc93c6cbd2e92a270ae9ca Mon Sep 17 00:00:00 2001 From: joaquimg Date: Sun, 4 May 2025 17:49:43 -0300 Subject: [PATCH 3/5] make JuMP a weakdep --- Project.toml | 7 ++- .../DualizationJuMPExt/DualizationJuMPExt.jl | 46 +++++++++++++------ src/Dualization.jl | 6 +-- 3 files changed, 40 insertions(+), 19 deletions(-) rename src/JuMP.jl => ext/DualizationJuMPExt/DualizationJuMPExt.jl (73%) diff --git a/Project.toml b/Project.toml index 3d9f416b..7c53c197 100644 --- a/Project.toml +++ b/Project.toml @@ -4,10 +4,15 @@ authors = ["guilhermebodin "] version = "0.5.9" [deps] -JuMP = "4076af6c-e467-56ae-b986-b466b2749572" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" +[weakdeps] +JuMP = "4076af6c-e467-56ae-b986-b466b2749572" + +[extensions] +DualizationJuMPExt = "JuMP" + [compat] JuMP = "0.23, 1" MathOptInterface = "1" diff --git a/src/JuMP.jl b/ext/DualizationJuMPExt/DualizationJuMPExt.jl similarity index 73% rename from src/JuMP.jl rename to ext/DualizationJuMPExt/DualizationJuMPExt.jl index b6cd60a4..b59ec671 100644 --- a/src/JuMP.jl +++ b/ext/DualizationJuMPExt/DualizationJuMPExt.jl @@ -1,11 +1,26 @@ -function dualize(model::JuMP.Model, optimizer_constructor = nothing; kwargs...) +# Copyright (c) 2017: Guilherme Bodin, and contributors +# +# Use of this source code is governed by an MIT-style license that can be found +# in the LICENSE.md file or at https://opensource.org/licenses/MIT. + +module DualizationJuMPExt + +import Dualization +import JuMP +import MathOptInterface as MOI + +function Dualization.dualize( + model::JuMP.Model, + optimizer_constructor = nothing; + kwargs..., +) mode = JuMP.mode(model) if mode != JuMP.AUTOMATIC error("Dualization does not support solvers in $(mode) mode") end dual_model = JuMP.Model() - dual_problem = DualProblem(JuMP.backend(dual_model)) - dualize(JuMP.backend(model), dual_problem; kwargs...) + dual_problem = Dualization.DualProblem(JuMP.backend(dual_model)) + Dualization.dualize(JuMP.backend(model), dual_problem; kwargs...) _fill_obj_dict_with_variables!(dual_model) _fill_obj_dict_with_constraints!(dual_model) if optimizer_constructor !== nothing @@ -60,10 +75,13 @@ function _get_primal_dual_map(model::JuMP.Model) return model.ext[:_Dualization_jl_PrimalDualMap] end -function _get_dual_constraint(dual_model, primal_ref::JuMP.VariableRef) +function Dualization._get_dual_constraint( + dual_model, + primal_ref::JuMP.VariableRef, +) map = _get_primal_dual_map(dual_model) moi_primal_vi = JuMP.index(primal_ref) - moi_dual_ci, idx = _get_dual_constraint(map, moi_primal_vi) + moi_dual_ci, idx = Dualization._get_dual_constraint(map, moi_primal_vi) # dual_model = nothing # TODO if idx === nothing # variables fixed at zero @@ -72,27 +90,27 @@ function _get_dual_constraint(dual_model, primal_ref::JuMP.VariableRef) return JuMP.constraint_ref_with_index(dual_model, moi_dual_ci), idx end -function _get_primal_constraint( +function Dualization._get_primal_constraint( dual_model::JuMP.Model, primal_vi::JuMP.VariableRef, ) primal_model = JuMP.owner_model(primal_vi) map = _get_primal_dual_map(dual_model) moi_primal_vi = JuMP.index(primal_vi) - primal_ci, idx = _get_primal_constraint(map, moi_primal_vi) + primal_ci, idx = Dualization._get_primal_constraint(map, moi_primal_vi) if primal_ci === nothing return nothing, idx end return JuMP.constraint_ref_with_index(primal_model, primal_ci), idx end -function _get_dual_variables( +function Dualization._get_dual_variables( dual_model::JuMP.Model, primal_ref::JuMP.ConstraintRef, ) map = _get_primal_dual_map(dual_model) moi_primal_ci = JuMP.index(primal_ref) - moi_dual_vis = _get_dual_variables(map, moi_primal_ci) + moi_dual_vis = Dualization._get_dual_variables(map, moi_primal_ci) if moi_dual_vis === nothing # main constraint of a constrained variable return nothing @@ -101,13 +119,13 @@ function _get_dual_variables( end # this is a constrained variable constraint -function _get_dual_constraint( +function Dualization._get_dual_constraint( dual_model::JuMP.Model, primal_ref::JuMP.ConstraintRef, ) map = _get_primal_dual_map(dual_model) moi_primal_ci = JuMP.index(primal_ref) - moi_dual_ci = _get_dual_constraint(map, moi_primal_ci) + moi_dual_ci = Dualization._get_dual_constraint(map, moi_primal_ci) if moi_dual_ci === nothing # main constraint of a constrained variable # or @@ -117,13 +135,15 @@ function _get_dual_constraint( return JuMP.constraint_ref_with_index(dual_model, moi_dual_ci) end -function _get_dual_parameter( +function Dualization._get_dual_parameter( dual_model::JuMP.Model, primal_ref::JuMP.VariableRef, ) map = _get_primal_dual_map(dual_model) moi_primal_vi = JuMP.index(primal_ref) - moi_dual_vi = _get_dual_parameter(map, moi_primal_vi) + moi_dual_vi = Dualization._get_dual_parameter(map, moi_primal_vi) # the above line might error return JuMP.VariableRef(dual_model, moi_dual_vi) end + +end # module DualizationJuMPExt diff --git a/src/Dualization.jl b/src/Dualization.jl index 7986f518..9d56396c 100644 --- a/src/Dualization.jl +++ b/src/Dualization.jl @@ -5,11 +5,8 @@ module Dualization -import JuMP import LinearAlgebra -import MathOptInterface - -const MOI = MathOptInterface +import MathOptInterface as MOI include("structures.jl") include("utils.jl") @@ -23,6 +20,5 @@ include("dual_model_variables.jl") include("dual_equality_constraints.jl") include("dualize.jl") include("MOI_wrapper.jl") -include("JuMP.jl") end # module From 465f470a011e79aefc8a701b09671a6cbee3221f Mon Sep 17 00:00:00 2001 From: joaquimg Date: Sun, 4 May 2025 17:53:13 -0300 Subject: [PATCH 4/5] bump julia version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 7c53c197..3fe94a91 100644 --- a/Project.toml +++ b/Project.toml @@ -16,4 +16,4 @@ DualizationJuMPExt = "JuMP" [compat] JuMP = "0.23, 1" MathOptInterface = "1" -julia = "1.6" +julia = "1.9" From b7861fb0e3222667de25f5b639a90d5604a1d125 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sun, 4 May 2025 17:54:45 -0300 Subject: [PATCH 5/5] Update ci.yml --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c388053..b8b0d62a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,10 +21,10 @@ jobs: - version: '1' os: ubuntu-latest arch: x64 - - version: '1.6' + - version: '1.9' os: ubuntu-latest arch: x64 - - version: '1.6' + - version: '1.9' os: ubuntu-latest arch: x86 steps: