44# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
55
66"""
7- GeometricConicForm{T, AT, VT, C} <: MOI.ModelLike
7+ empty_geometric_conic_form
88
99Represents an optimization model of the form:
1010```
@@ -13,246 +13,37 @@ s.t. b_i - A_i x ∈ C_i ∀ i
1313```
1414with each `C_i` a cone defined in MOI.
1515"""
16- mutable struct GeometricConicForm{T,AT,VB,VC,C} <: MOI.ModelLike
17- num_rows:: Vector{Int}
18- dimension:: Dict{Int,Int}
19- sense:: MOI.OptimizationSense
20- objective_constant:: T # The objective
21- A:: Union{Nothing,AT} # The constraints
22- b:: VB # `b - Ax in cones`
23- c:: VC # `sense c'x + objective_constant`
24- cone_types:: C
25- cone_types_dict:: Dict{DataType,Int}
26-
27- function GeometricConicForm {T,AT,VB,VC} (cone_types) where {T,AT,VB,VC}
28- model = new {T,AT,VB,VC,typeof(cone_types)} ()
29- model. cone_types = cone_types
30- model. cone_types_dict =
31- Dict {DataType,Int} (s => i for (i, s) in enumerate (cone_types))
32- model. num_rows = zeros (Int, length (cone_types))
33- model. dimension = Dict {Int,Int} ()
34- model. A = nothing
35- return model
36- end
37- end
38-
39- function GeometricConicForm {T,AT,VT} (cone_types) where {T,AT,VT}
40- return GeometricConicForm {T,AT,VT,VT} (cone_types)
41- end
42-
43- _set_type (:: MOI.ConstraintIndex{F,S} ) where {F,S} = S
44-
45- MOI. is_empty (model:: GeometricConicForm ) = model. A === nothing
46-
47- function MOI. empty! (model:: GeometricConicForm{T} ) where {T}
48- empty! (model. dimension)
49- fill! (model. num_rows, 0 )
50- model. A = nothing
51- model. sense = MOI. FEASIBILITY_SENSE
52- return model. objective_constant = zero (T)
53- end
54-
55- function MOI. supports_constraint (
56- model:: GeometricConicForm{T} ,
57- :: Type{MOI.VectorAffineFunction{T}} ,
58- :: Type{S} ,
59- ) where {T,S<: MOI.AbstractVectorSet }
60- return haskey (model. cone_types_dict, S)
61- end
62-
63- function _allocate_variables (
64- model:: GeometricConicForm{T,AT,VT} ,
65- vis_src,
66- idxmap,
67- ) where {T,AT,VT}
68- model. A = AT (length (vis_src))
69- for (i, vi) in enumerate (vis_src)
70- idxmap[vi] = MOI. VariableIndex (i)
71- end
72- return
73- end
74-
75- function rows (
76- model:: GeometricConicForm{T} ,
77- ci:: CI{MOI.VectorAffineFunction{T}} ,
78- ) where {T}
79- return ci. value .+ (1 : model. dimension[ci. value])
80- end
81-
82- function MOI. set (
83- :: GeometricConicForm ,
84- :: MOI.VariablePrimalStart ,
85- :: MOI.VariableIndex ,
86- :: Nothing ,
87- )
88- return
89- end
90-
91- function MOI. set (
92- model:: GeometricConicForm{T} ,
93- :: MOI.VariablePrimalStart ,
94- vi:: MOI.VariableIndex ,
95- value:: T ,
96- ) where {T}
97- return model. primal[vi. value] = value
98- end
99-
100- function MOI. set (
101- :: GeometricConicForm ,
102- :: MOI.ConstraintPrimalStart ,
103- :: MOI.ConstraintIndex ,
104- :: Nothing ,
105- )
106- return
107- end
108-
109- function MOI. set (
110- model:: GeometricConicForm ,
111- :: MOI.ConstraintPrimalStart ,
112- ci:: MOI.ConstraintIndex ,
113- value,
114- )
115- offset = constroffset (model, ci)
116- return model. slack[rows (model, ci)] .= value
117- end
118-
119- function MOI. set (
120- :: GeometricConicForm ,
121- :: MOI.ConstraintDualStart ,
122- :: MOI.ConstraintIndex ,
123- :: Nothing ,
124- )
125- return
126- end
127-
128- function MOI. set (
129- model:: GeometricConicForm ,
130- :: MOI.ConstraintDualStart ,
131- ci:: MOI.ConstraintIndex ,
132- value,
133- )
134- offset = constroffset (model, ci)
135- return model. dual[rows (model, ci)] .= value
136- end
137-
138- function MOI. set (
139- model:: GeometricConicForm ,
140- :: MOI.ObjectiveSense ,
141- sense:: MOI.OptimizationSense ,
142- )
143- return model. sense = sense
144- end
145-
146- variable_index_value (t:: MOI.ScalarAffineTerm ) = t. variable. value
147-
148- function variable_index_value (t:: MOI.VectorAffineTerm )
149- return variable_index_value (t. scalar_term)
150- end
151-
152- function MOI. set (
153- model:: GeometricConicForm{T} ,
154- :: MOI.ObjectiveFunction ,
155- f:: MOI.ScalarAffineFunction{T} ,
156- ) where {T}
157- c = Vector (
158- sparsevec (
159- variable_index_value .(f. terms),
160- MOI. coefficient .(f. terms),
161- model. A. n,
162- ),
16+ function empty_geometric_conic_form (cones; Tv = Float64, Ti = Int, I = MOI. Utilities. OneBasedIndexing)
17+ return MOI. Utilities. GenericModel {T} (
18+ MOI. Utilities. ObjectiveContainer {T} (),
19+ MOI. Utilities. FreeVariables (),
20+ MOI. Utilities. MatrixOfConstraints{
21+ T,
22+ MOI. Utilities. MutableSparseMatrixCSC{
23+ Tv,
24+ Ti,
25+ I,
26+ },
27+ Vector{T},
28+ ProductOfSets{T},
29+ },
16330 )
164- model. objective_constant = f. constant
165- model. c = c
166- return
167- end
168-
169- function _allocate_constraint (
170- model:: GeometricConicForm ,
171- src,
172- indexmap,
173- cone_id,
174- ci,
175- )
176- # TODO use `CanonicalConstraintFunction`
177- func = MOI. get (src, MOI. ConstraintFunction (), ci)
178- func = MOIU. is_canonical (func) ? func : MOI. Utilities. canonical (func)
179- allocate_terms (model. A, indexmap, func)
180- offset = model. num_rows[cone_id]
181- model. num_rows[cone_id] = offset + MOI. output_dimension (func)
182- return ci, offset, func
18331end
18432
185- function _allocate_constraints (
186- model:: GeometricConicForm{T} ,
187- src,
188- indexmap,
189- cone_id,
190- :: Type{S} ,
191- ) where {T,S}
192- cis = MOI. get (
193- src,
194- MOI. ListOfConstraintIndices {MOI.VectorAffineFunction{T},S} (),
195- )
196- return map (cis) do ci
197- return _allocate_constraint (model, src, indexmap, cone_id, ci)
198- end
33+ function geometric_conic_form (model:: MOI.ModelLike , cones; kws... )
34+ form = empty_geometric_conic_form (cones; kws... )
35+ index_map = MOI. copy_to (form, model)
36+ return form, index_map
19937end
20038
201- function _load_variables (model:: GeometricConicForm , nvars:: Integer )
202- m = sum (model. num_rows)
203- model. A. m = m
204- model. b = zeros (m)
205- model. c = zeros (model. A. n)
206- return allocate_nonzeros (model. A)
207- end
39+ _coef_type (:: MOI.Utilities.AbstractModel{T} ) where {T} = T
20840
209- function _load_constraints (
210- model:: GeometricConicForm ,
211- src,
212- indexmap,
213- cone_offset,
214- i,
215- cache,
216- )
217- for (ci_src, offset_in_cone, func) in cache
218- offset = cone_offset + offset_in_cone
219- set = MOI. get (src, MOI. ConstraintSet (), ci_src)
220- load_terms (model. A, indexmap, func, offset)
221- copyto! (model. b, offset + 1 , func. constants)
222- model. dimension[offset] = MOI. output_dimension (func)
223- indexmap[ci_src] = typeof (ci_src)(offset)
224- end
225- end
226-
227- function MOI. copy_to (dest:: GeometricConicForm{T} , src:: MOI.ModelLike ) where {T}
228- MOI. empty! (dest)
229- vis_src = MOI. get (src, MOI. ListOfVariableIndices ())
230- idxmap = MOIU. IndexMap ()
231- has_constraints = BitSet ()
232- for (F, S) in MOI. get (src, MOI. ListOfConstraintTypesPresent ())
233- i = get (dest. cone_types_dict, S, nothing )
234- if i === nothing || F != MOI. VectorAffineFunction{T}
235- throw (MOI. UnsupportedConstraint {F,S} ())
236- end
237- push! (has_constraints, i)
238- end
239- _allocate_variables (dest, vis_src, idxmap)
240- # Allocate constraints
241- caches = map (collect (has_constraints)) do i
242- return _allocate_constraints (dest, src, idxmap, i, dest. cone_types[i])
243- end
244- # Load variables
245- _load_variables (dest, length (vis_src))
246- # Set variable attributes
247- MOIU. pass_attributes (dest, src, idxmap, vis_src)
248- # Set model attributes
249- MOIU. pass_attributes (dest, src, idxmap)
250- # Load constraints
251- offset = 0
252- for (i, cache) in zip (has_constraints, caches)
253- _load_constraints (dest, src, idxmap, offset, i, cache)
254- offset += dest. num_rows[i]
41+ function objective_vector (model:: MOI.ModelLike ; T = _coef_type (model))
42+ obj = MOI. get (src, MOI. ObjectiveFunction {MOI.ScalarAffineFunction{T}} ())
43+ dest. objective_constant = MOI. constant (obj)
44+ c = zeros (A. n)
45+ for term in obj. terms
46+ c[term. variable. value] += term. coefficient
25547 end
256- final_touch (dest. A)
257- return idxmap
48+ return c
25849end
0 commit comments