@@ -170,25 +170,14 @@ macro product_of_sets(name, set_types...)
170170 mutable struct $ (esc_name){$ (T)} < :
171171 $ MOI. Utilities. OrderedProductOfSets{$ (T)}
172172 """
173- `dimension[i][j]` is the dimension of `ConstraintIndex().value` `j`
174- of set type `i`.
175- """
176- dimension:: Vector{Vector{Int}}
177-
178- """
179- `offset[i][j]` is the 0-indexed row offset of constraint `j` of set
180- type `i`. The rows are therefore `offset[i][j] + 1:dimension[i][j]`.
181-
182- The `offset` vector gets created during `final_touch`.
183- """
184- offset:: Vector{Vector{Int}}
185-
186- """
187- The total number of rows in the sets.
173+ `rows[i][j]` corresponds to constraint `j` of set type `i`.
188174
189- This value gets set during `final_touch`.
175+ The value depends on `final_touch`:
176+ * Before `final_touch`, these are `1:dimension` of the constraint
177+ * After `final_touch`, these are the 1-indexed rows of the full
178+ constraint matrix
190179 """
191- num_rows :: Int
180+ rows :: Vector{Vector{UnitRange{ Int}}}
192181
193182 """
194183 A sanity bit to check that we don't call functions out-of-order.
@@ -197,62 +186,58 @@ macro product_of_sets(name, set_types...)
197186
198187 function $ (esc_name){$ (T)}() where {$ (T)}
199188 n = $ (length (set_types))
200- return new ([Int[] for _ in 1 : n], Vector{Int}[], 0 , false )
189+ return new ([UnitRange{ Int} [] for _ in 1 : n], false )
201190 end
202191 end
203192 )
204193 return _sets_code (esc_name, T, type_def, set_types... )
205194end
206195
207- MOI. is_empty (sets:: OrderedProductOfSets ) = all (isempty, sets. dimension )
196+ MOI. is_empty (sets:: OrderedProductOfSets ) = all (isempty, sets. rows )
208197
209198function MOI. empty! (sets:: OrderedProductOfSets )
210- map (empty!, sets. dimension)
211- empty! (sets. offset)
199+ map (empty!, sets. rows)
212200 sets. final_touch = false
213201 return
214202end
215203
216- function MOI. dimension (sets:: OrderedProductOfSets )
204+ function MOI. dimension (sets:: OrderedProductOfSets ):: Int
217205 @assert sets. final_touch
218- return sets . num_rows
206+ return sum ( num_rows (sets, S) for S in set_types (sets); init = 0 )
219207end
220208
221209function rows (
222210 sets:: OrderedProductOfSets{T} ,
223211 ci:: MOI.ConstraintIndex{MOI.ScalarAffineFunction{T},S} ,
224- ) where {T,S}
212+ ):: Int where {T,S}
225213 @assert sets. final_touch
226214 i = set_index (sets, S):: Int
227- return sets. offset [i][ci. value] + 1
215+ return only ( sets. rows [i][ci. value])
228216end
229217
230218function rows (
231219 sets:: OrderedProductOfSets{T} ,
232220 ci:: MOI.ConstraintIndex{MOI.VectorAffineFunction{T},S} ,
233- ) where {T,S}
221+ ):: UnitRange{Int} where {T,S}
234222 @assert sets. final_touch
235223 i = set_index (sets, S):: Int
236- return sets. offset [i][ci. value] .+ ( 1 : sets . dimension[i][ci . value])
224+ return sets. rows [i][ci. value]
237225end
238226
239- function add_set (sets:: OrderedProductOfSets , i, dim = 1 )
227+ function add_set (sets:: OrderedProductOfSets , i, dim = 1 ):: Int
240228 @assert ! sets. final_touch
241- push! (sets. dimension [i], dim)
242- return length (sets. dimension [i])
229+ push! (sets. rows [i], 1 : dim)
230+ return length (sets. rows [i])
243231end
244232
245- function final_touch (sets:: OrderedProductOfSets )
233+ function final_touch (sets:: OrderedProductOfSets ):: Nothing
246234 @assert ! sets. final_touch
247235 offset = 0
248- for (i, dimension) in enumerate (sets. dimension)
249- offsets = Int[]
250- for d in dimension
251- push! (offsets, offset)
252- offset += d
253- sets. num_rows += d
236+ for (i, rows) in enumerate (sets. rows)
237+ for (j, row) in enumerate (rows)
238+ rows[j] = offset .+ row
239+ offset += length (row)
254240 end
255- push! (sets. offset, offsets)
256241 end
257242 sets. final_touch = true
258243 return
@@ -264,50 +249,55 @@ end
264249Return the number of rows corresponding to a set of type `S`. That is, it is
265250the sum of the dimensions of the sets of type `S`.
266251"""
267- function num_rows (sets:: OrderedProductOfSets , :: Type{S} ) where {S}
252+ function num_rows (sets:: OrderedProductOfSets , :: Type{S} ):: Int where {S}
253+ @assert sets. final_touch
268254 i = set_index (sets, S):: Int
269- return sum (sets. dimension[i])
255+ rows = sets. rows[i]
256+ if isempty (rows)
257+ return 0
258+ end
259+ return max (0 , last (rows[end ]) - first (rows[1 ]) + 1 )
270260end
271261
272262function MOI. get (
273263 sets:: OrderedProductOfSets{T} ,
274264 :: MOI.ListOfConstraintTypesPresent ,
275- ) where {T}
265+ ):: Vector{Tuple{Type,Type}} where {T}
276266 return Tuple{Type,Type}[
277267 (_affine_function_type (T, S), S) for
278- (i, S) in enumerate (set_types (sets)) if ! isempty (sets. dimension [i])
268+ (i, S) in enumerate (set_types (sets)) if ! isempty (sets. rows [i])
279269 ]
280270end
281271
282272function MOI. get (
283273 sets:: OrderedProductOfSets ,
284274 :: MOI.NumberOfConstraints{F,S} ,
285- ) where {F,S}
275+ ):: Int64 where {F,S}
286276 i = set_index (sets, S):: Union{Nothing,Int}
287277 if i == nothing
288278 return 0
289279 end
290- return length (sets. dimension [i])
280+ return length (sets. rows [i])
291281end
292282
293283function MOI. get (
294284 sets:: OrderedProductOfSets ,
295285 :: MOI.ListOfConstraintIndices{F,S} ,
296- ) where {F,S}
286+ ):: Vector{MOI.ConstraintIndex{F,S}} where {F,S}
297287 i = set_index (sets, S):: Union{Nothing,Int}
298288 if i == nothing
299289 return MOI. ConstraintIndex{F,S}[]
300290 end
301- return MOI. ConstraintIndex {F,S} .(1 : length (sets. dimension [i]))
291+ return MOI. ConstraintIndex {F,S} .(1 : length (sets. rows [i]))
302292end
303293
304294function MOI. is_valid (
305295 sets:: OrderedProductOfSets ,
306296 ci:: MOI.ConstraintIndex{F,S} ,
307- ) where {F,S}
297+ ):: Bool where {F,S}
308298 i = set_index (sets, S):: Union{Nothing,Int}
309299 if i == nothing
310300 return false
311301 end
312- return 1 <= ci. value <= length (sets. dimension [i])
302+ return 1 <= ci. value <= length (sets. rows [i])
313303end
0 commit comments