Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/src/submodules/Utilities/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ Utilities.latex_formulation
```@docs
Utilities.automatic_copy_to
Utilities.default_copy_to
Utilities.IndexMap
Utilities.identity_index_map
```

### [Allocate-Load API](@id allocate_load_api_ref)
Expand Down
4 changes: 3 additions & 1 deletion src/Utilities/DoubleDicts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,9 @@ end
end

function initialize_inner!(d::AbstractWithType{F,S,V,D}) where {F,S,V,D}
return d.inner = D()
d.inner = D()
d.dict.dict[(F, S)] = d.inner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. I ran into this with the NL writer, but I assumed it was expected behavior.

return
end

inner_is_empty(d::AbstractWithType)::Bool = d.inner === nothing
Expand Down
37 changes: 37 additions & 0 deletions src/Utilities/copy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ function dense_variable_dict(::Type{V}, n) where {V}
)
end

"""
struct IndexMap <: AbstractDict{MOI.Index,MOI.Index}
varmap::DenseVariableDict{MOI.VariableIndex}
conmap::DoubleDicts.MainIndexDoubleDict
end

Dictionary-like object returned by [`MathOptInterface.copy_to`](@ref) that
contains the mapping between variable indices in `varmap` and between
constraint indices in `conmap`.
"""
struct IndexMap <: AbstractDict{MOI.Index,MOI.Index}
varmap::DenseVariableDict{MOI.VariableIndex}
conmap::DoubleDicts.MainIndexDoubleDict
Expand All @@ -70,6 +80,33 @@ function IndexMap(n = 0)
)
end

function _identity_constraints_map(
model,
index_map::MOIU.DoubleDicts.IndexWithType{F,S},
) where {F,S}
for ci in MOI.get(model, MOI.ListOfConstraintIndices{F,S}())
index_map[ci] = ci
end
end

"""
identity_index_map(model::MOI.ModelLike)

Return an [`IndexMap`](@ref) that maps all variable and constraint indices of
`model` to themselves.
"""
function identity_index_map(model::MOI.ModelLike)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this function needed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is every solver going to need to do this?
https://github.com/jump-dev/Clp.jl/pull/111/files#diff-18c6af231f3facc5ba10dd45231da349efda22ecd8d68a4661dee8027bc413a7R302

If so, it needs a docstring and to be added to the documentation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I expect it to be used a lot. I can add docstring :)

vis = MOI.get(model, MOI.ListOfVariableIndices())
index_map = IndexMap(length(vis))
for vi in vis
index_map[vi] = vi
end
for (F, S) in MOI.get(model, MOI.ListOfConstraints())
_identity_constraints_map(model, index_map.conmap[F, S])
end
return index_map
end

"""
index_map_for_variable_indices(variables)

Expand Down
21 changes: 21 additions & 0 deletions test/Utilities/copy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ function compare_without_moi(x::String, y::String)
@test remove_moi(x) == remove_moi(y)
end

function identity_index_map_test(::Type{T}) where {T}
model = MOI.Utilities.Model{T}()
x, y = MOI.add_variables(model, 2)
fx = MOI.SingleVariable(x)
fy = MOI.SingleVariable(y)
cx = MOI.add_constraint(model, fx, MOI.EqualTo(one(T)))
cy = MOI.add_constraint(model, fy, MOI.EqualTo(zero(T)))
c = MOI.add_constraint(model, one(T) * fx + fy, MOI.LessThan(zero(T)))
index_map = MOI.Utilities.identity_index_map(model)
@test x == index_map[x]
@test y == index_map[y]
@test cx == index_map[cx]
@test cy == index_map[cy]
@test c == index_map[c]
end

@testset "IndexMap" begin
map = MOIU.IndexMap()
@test length(map) == 0
Expand Down Expand Up @@ -695,3 +711,8 @@ end
test_pass_copy(Int)
test_pass_copy(Float64)
end

@testset "identity_index_map" begin
identity_index_map_test(Int)
identity_index_map_test(Float64)
end