From 493c72de3036196b7da74e6b24e4a220ae6d536c Mon Sep 17 00:00:00 2001 From: odow Date: Thu, 21 Sep 2023 11:08:39 +1200 Subject: [PATCH 1/3] Fix various JET errors --- .../Constraint/bridges/indicator_sos.jl | 9 ++++--- .../bridges/split_hyperrectangle.jl | 20 +++++++++----- src/Bridges/set_map.jl | 4 ++- src/Utilities/copy.jl | 26 ++++++++++--------- src/Utilities/product_of_sets.jl | 13 ++++++---- src/Utilities/variables_container.jl | 11 +++++--- 6 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/Bridges/Constraint/bridges/indicator_sos.jl b/src/Bridges/Constraint/bridges/indicator_sos.jl index e1750df50c..19425f9ad1 100644 --- a/src/Bridges/Constraint/bridges/indicator_sos.jl +++ b/src/Bridges/Constraint/bridges/indicator_sos.jl @@ -82,9 +82,12 @@ function MOI.get( b::IndicatorSOS1Bridge{T}, ) where {T} f = MOI.get(model, attr, b.affine_index) - terms = MOI.VectorAffineTerm{T}[ - MOI.VectorAffineTerm(2, t) for t in f.terms if t.variable != b.slack - ] + terms = MOI.VectorAffineTerm{T}[] + for t in f.terms + if t.variable != b.slack + push!(terms, MOI.VectorAffineTerm(2, t)) + end + end push!(terms, MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(one(T), b.z))) return MOI.VectorAffineFunction(terms, [zero(T), f.constant]) end diff --git a/src/Bridges/Constraint/bridges/split_hyperrectangle.jl b/src/Bridges/Constraint/bridges/split_hyperrectangle.jl index 0a573f0b4f..e9e5aa0309 100644 --- a/src/Bridges/Constraint/bridges/split_hyperrectangle.jl +++ b/src/Bridges/Constraint/bridges/split_hyperrectangle.jl @@ -167,10 +167,17 @@ function MOI.set( bridge::SplitHyperRectangleBridge{T}, value::AbstractVector{T}, ) where {T} - new_values = vcat( - T[v - l for (v, l) in zip(value, bridge.set.lower) if isfinite(l)], - T[u - v for (v, u) in zip(value, bridge.set.upper) if isfinite(u)], - ) + new_values = T[] + for (v, l) in zip(value, bridge.set.lower) + if isfinite(l) + push!(new_values, v - l) + end + end + for (v, u) in zip(value, bridge.set.upper) + if isfinite(u) + push!(new_values, u - v) + end + end MOI.set(model, attr, bridge.ci, new_values) return end @@ -207,10 +214,9 @@ function MOI.set( bridge::SplitHyperRectangleBridge{T}, values::AbstractVector{T}, ) where {T} - set = bridge.set new_values = vcat( - T[max(T(0), v) for (v, l) in zip(values, set.lower) if isfinite(l)], - T[min(T(0), v) for (v, u) in zip(values, set.upper) if isfinite(u)], + max.(T(0), values[isfinite.(bridge.set.lower)]), + min.(T(0), values[isfinite.(bridge.set.upper)]), ) MOI.set(model, attr, bridge.ci, new_values) return diff --git a/src/Bridges/set_map.jl b/src/Bridges/set_map.jl index d43796105b..def51a5f7e 100644 --- a/src/Bridges/set_map.jl +++ b/src/Bridges/set_map.jl @@ -21,7 +21,9 @@ Return the preimage of `set` through the linear map `A` defined in [`Variable.SetMapBridge`](@ref) and [`Constraint.SetMapBridge`](@ref). This is used for getting the [`MOI.ConstraintSet`](@ref). """ -function inverse_map_set end +function inverse_map_set(BT::Type, set::MOI.AbstractSet) + return throw(MethodError(inverse_map_set, (typeof(BT), typeof(set)))) +end """ map_function(::Type{BT}, func) where {BT} diff --git a/src/Utilities/copy.jl b/src/Utilities/copy.jl index 11a76c3ba9..2dd4c12e8e 100644 --- a/src/Utilities/copy.jl +++ b/src/Utilities/copy.jl @@ -453,8 +453,12 @@ Unfortunately, we don't have a good way of computing the updated costs for other constraints if a variable bridge is chosen. """ function sorted_variable_sets_by_cost(dest::MOI.ModelLike, src::MOI.ModelLike) - constraint_types = MOI.get(src, MOI.ListOfConstraintTypesPresent()) - sets = Type[S for (F, S) in constraint_types if _is_variable_function(F)] + sets = Type[] + for (F, S) in MOI.get(src, MOI.ListOfConstraintTypesPresent()) + if _is_variable_function(F) + push!(sets, S) + end + end sort!(sets; by = S::Type -> _cost_of_bridging(dest, S)) return sets end @@ -486,17 +490,15 @@ function default_copy_to(dest::MOI.ModelLike, src::MOI.ModelLike) # Therefore, all VariableIndex and VectorOfVariable constraints are added # seprately, and no variables constrained-on-creation are added. has_nlp = MOI.NLPBlock() in MOI.get(src, MOI.ListOfModelAttributesSet()) - constraints_not_added = if has_nlp - Any[ - MOI.get(src, MOI.ListOfConstraintIndices{F,S}()) for - (F, S) in MOI.get(src, MOI.ListOfConstraintTypesPresent()) if - _is_variable_function(F) - ] - else - Any[ + constraints_not_added = Any[] + for S in sorted_variable_sets_by_cost(dest, src) + ret = if has_nlp + F = variable_function_type(S) + MOI.get(src, MOI.ListOfConstraintIndices{F,S}()) + else _try_constrain_variables_on_creation(dest, src, index_map, S) - for S in sorted_variable_sets_by_cost(dest, src) - ] + end + push!(constraints_not_added, ret) end _copy_free_variables(dest, index_map, vis_src) # Copy variable attributes diff --git a/src/Utilities/product_of_sets.jl b/src/Utilities/product_of_sets.jl index 15afce75a9..483fe61506 100644 --- a/src/Utilities/product_of_sets.jl +++ b/src/Utilities/product_of_sets.jl @@ -118,11 +118,14 @@ function MOI.get( sets::MixOfScalarSets, ::MOI.ListOfConstraintIndices{F,S}, ) where {F,S} - i = set_index(sets, S) - return MOI.ConstraintIndex{F,S}[ - MOI.ConstraintIndex{F,S}(ci) for - (ci, set_type) in enumerate(sets.set_ids) if set_type == i - ] + index = set_index(sets, S) + ret = MOI.ConstraintIndex{F,S}[] + for (i, set_type) in enumerate(sets.set_ids) + if set_type == index + push!(ret, MOI.ConstraintIndex{F,S}(i)) + end + end + return ret end function MOI.is_valid( diff --git a/src/Utilities/variables_container.jl b/src/Utilities/variables_container.jl index 585f85492e..70df775969 100644 --- a/src/Utilities/variables_container.jl +++ b/src/Utilities/variables_container.jl @@ -231,10 +231,13 @@ function MOI.add_variable(b::VariablesContainer{T}) where {T} end function MOI.get(b::VariablesContainer, ::MOI.ListOfVariableIndices) - return MOI.VariableIndex[ - MOI.VariableIndex(i) for - i in 1:length(b.set_mask) if b.set_mask[i] != _DELETED_VARIABLE - ] + ret = MOI.VariableIndex[] + for (i, mask) in enumerate(b.set_mask) + if mask != _DELETED_VARIABLE + push!(ret, MOI.VariableIndex(i)) + end + end + return ret end function MOI.is_valid(b::VariablesContainer, x::MOI.VariableIndex) From 754854dbb6b876a1532b81fd13697f9d4136006f Mon Sep 17 00:00:00 2001 From: odow Date: Thu, 21 Sep 2023 11:27:58 +1200 Subject: [PATCH 2/3] Update --- src/Bridges/Constraint/bridges/set_dot_scaling.jl | 2 +- src/Bridges/set_map.jl | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Bridges/Constraint/bridges/set_dot_scaling.jl b/src/Bridges/Constraint/bridges/set_dot_scaling.jl index 36cee0f65f..c4e99e931a 100644 --- a/src/Bridges/Constraint/bridges/set_dot_scaling.jl +++ b/src/Bridges/Constraint/bridges/set_dot_scaling.jl @@ -151,7 +151,7 @@ end function MOI.Bridges.map_set( ::Type{<:SetDotInverseScalingBridge{T,S}}, set::MOI.Scaled{S}, -) where {T,S} +) where {T,S<:MOI.AbstractVectorSet} return set.set end diff --git a/src/Bridges/set_map.jl b/src/Bridges/set_map.jl index def51a5f7e..d43796105b 100644 --- a/src/Bridges/set_map.jl +++ b/src/Bridges/set_map.jl @@ -21,9 +21,7 @@ Return the preimage of `set` through the linear map `A` defined in [`Variable.SetMapBridge`](@ref) and [`Constraint.SetMapBridge`](@ref). This is used for getting the [`MOI.ConstraintSet`](@ref). """ -function inverse_map_set(BT::Type, set::MOI.AbstractSet) - return throw(MethodError(inverse_map_set, (typeof(BT), typeof(set)))) -end +function inverse_map_set end """ map_function(::Type{BT}, func) where {BT} From 395055a4f2b558f50a3214bee54fe0f2b4829089 Mon Sep 17 00:00:00 2001 From: odow Date: Thu, 21 Sep 2023 11:40:13 +1200 Subject: [PATCH 3/3] Update --- src/FileFormats/MPS/MPS.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/FileFormats/MPS/MPS.jl b/src/FileFormats/MPS/MPS.jl index 9fc47035f0..2d11aa8066 100644 --- a/src/FileFormats/MPS/MPS.jl +++ b/src/FileFormats/MPS/MPS.jl @@ -1235,10 +1235,13 @@ function _add_objective(model, data, variable_map) else MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) end - affine_terms = MOI.ScalarAffineTerm{Float64}[ - MOI.ScalarAffineTerm(data.c[i], variable_map[v]) for - (i, v) in enumerate(data.col_to_name) if !iszero(data.c[i]) - ] + affine_terms = MOI.ScalarAffineTerm{Float64}[] + for (i, v) in enumerate(data.col_to_name) + if !iszero(data.c[i]) + term = MOI.ScalarAffineTerm(data.c[i], variable_map[v]) + push!(affine_terms, term) + end + end q_terms = MOI.ScalarQuadraticTerm{Float64}[] for (i, j, q) in data.quad_obj x = variable_map[i]