-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathproduct_of_sets.jl
More file actions
75 lines (65 loc) · 2.25 KB
/
product_of_sets.jl
File metadata and controls
75 lines (65 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Copyright (c) 2019: Joaquim Dias Garcia, 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.
# Copied from DiffOpt
"""
ProductOfSets{T} <: MOI.Utilities.OrderedProductOfSets{T}
The `MOI.Utilities.@product_of_sets` macro requires to know the list of sets
at compile time. In DiffOpt however, the list depends on what the user is going
to use as set as DiffOpt supports any set as long as it implements the
required function of MathOptSetDistances.
For this type, the list of sets can be given a run-time.
"""
mutable struct ProductOfSets{T} <: MOI.Utilities.OrderedProductOfSets{T}
"""
During the copy, this counts the number of rows corresponding to
each set. At the end of copy, `final_touch` is called, which
converts this list into a cumulative ordering.
"""
num_rows::Vector{Int}
"""
A dictionary which maps the `set_index` and `offset` of a set to the
dimension, i.e., `dimension[(set_index,offset)] → dim`.
"""
dimension::Dict{Tuple{Int,Int},Int}
"""
A sanity bit to check that we don't call functions out-of-order.
"""
final_touch::Bool
set_types::Vector{Type}
set_types_dict::Dict{Type,Int}
function ProductOfSets{T}() where {T}
return new(
Int[],
Dict{Tuple{Int,Int},Int}(),
false,
Type[],
Dict{Type,Int}(),
)
end
end
function MOI.Utilities.set_index(set::ProductOfSets, S::Type{<:MOI.AbstractSet})
return get(set.set_types_dict, S, nothing)
end
MOI.Utilities.set_types(set::ProductOfSets) = set.set_types
function set_set_types(set::ProductOfSets, set_types)
resize!(set.num_rows, length(set_types))
fill!(set.num_rows, 0)
resize!(set.set_types, length(set_types))
copy!(set.set_types, set_types)
empty!(set.set_types_dict)
for i in eachindex(set_types)
set.set_types_dict[set_types[i]] = i
end
return
end
function add_set_types(set::ProductOfSets, S::Type)
if !haskey(set.set_types_dict, S)
push!(set.num_rows, 0)
push!(set.set_types, S)
set.set_types_dict[S] = length(set.set_types)
return true
end
return false
end