@@ -6,10 +6,18 @@ import NLPModels.increment!, NLPModels.decrement!
66using JuMP, MathOptInterface
77const MOI = MathOptInterface
88
9+ # VariableIndex
10+ const VI = MOI. VariableIndex # VariableIndex(value)
11+
912# ScalarAffineFunctions and VectorAffineFunctions
10- const SAF = MOI. ScalarAffineFunction{Float64}
11- const VAF = MOI. VectorAffineFunction{Float64}
12- const AF = Union{SAF, VAF}
13+ const SAF = MOI. ScalarAffineFunction{Float64} # ScalarAffineFunction{T}(terms, constant)
14+ const VAF = MOI. VectorAffineFunction{Float64} # VectorAffineFunction{T}(terms, constants)
15+ const AF = Union{SAF, VAF}
16+
17+ # ScalarQuadraticFunctions and VectorQuadraticFunctions
18+ const SQF = MOI. ScalarQuadraticFunction{Float64} # ScalarQuadraticFunction{T}(affine_terms, quadratic_terms, constant)
19+ const VQF = MOI. VectorQuadraticFunction{Float64} # VectorQuadraticFunction{T}(affine_terms, quadratic_terms, constants)
20+ const QF = Union{SQF, VQF}
1321
1422# AffLinSets and VecLinSets
1523const ALS = Union{
@@ -21,10 +29,11 @@ const ALS = Union{
2129const VLS = Union{MOI. Nonnegatives, MOI. Nonpositives, MOI. Zeros}
2230const LS = Union{ALS, VLS}
2331
32+ # Objective
2433const VI = MOI. VariableIndex
25- const SQF = MOI. ScalarQuadraticFunction{Float64}
2634const OBJ = Union{VI, SAF, SQF}
2735
36+ # Coordinate Matrix
2837mutable struct COO
2938 rows:: Vector{Int}
3039 cols:: Vector{Int}
@@ -38,6 +47,21 @@ mutable struct LinearConstraints
3847 nnzj:: Int
3948end
4049
50+ mutable struct QuadraticConstraint
51+ hessian:: COO
52+ b:: SparseVector{Float64}
53+ end
54+
55+ mutable struct QuadraticConstraints
56+ qcons:: Vector{QuadraticConstraint}
57+ nnzj:: Int
58+ jrows:: Vector{Int}
59+ jcols:: Vector{Int}
60+ nnzh:: Int
61+ hrows:: Vector{Int}
62+ hcols:: Vector{Int}
63+ end
64+
4165mutable struct LinearEquations
4266 jacobian:: COO
4367 constants:: Vector{Float64}
@@ -96,6 +120,52 @@ function coo_sym_dot(
96120 return xᵀAy
97121end
98122
123+ """
124+ jacobian_quad(qcons)
125+
126+ `qcons` is a vector of `QuadraticConstraint` where each constraint has the form ½xᵀQᵢx + xᵀbᵢ.
127+ Compute the sparcity pattern of the jacobian [Q₁x + b₁; ...; Qₚx + bₚ]ᵀ of `qcons`.
128+ """
129+ function jacobian_quad (qcons)
130+ jrows = Int[]
131+ jcols = Int[]
132+ nquad = length (qcons)
133+ for i = 1 : nquad
134+ # rows of Qᵢx + bᵢ with nonzeros coefficients
135+ vec = unique (con. hessian. rows ∪ con. b. nzind)
136+ for elt ∈ vec
137+ push! (elt, jcols)
138+ push! (i, jrows)
139+ end
140+ end
141+ nnzj = length (jrows)
142+ return nnzj, jrows, jcols
143+ end
144+
145+ """
146+ hessian_quad(qcons)
147+
148+ `qcons` is a vector of `QuadraticConstraint` where each constraint has the form ½xᵀQᵢx + xᵀbᵢ.
149+ Compute the sparcity pattern of the hessian ΣᵢQᵢ of `qcons`.
150+ """
151+ function hessian_quad (qcons)
152+ set = Set {Tuple{Int,Int}} ()
153+ for con ∈ qcons
154+ for tuple ∈ zip (con. rows, con. vals)
155+ # Only disctinct tuples are stored in the set
156+ push! (tuple, set)
157+ end
158+ end
159+ nnzh = length (set)
160+ hrows = zeros (Int, nnzh)
161+ hcols = zeros (Int, nnzh)
162+ for (index,tuple) in enumerate (set)
163+ hrows[index] = tuple[1 ]
164+ hcols[index] = tuple[2 ]
165+ end
166+ return nnzh, hrows, hcols
167+ end
168+
99169"""
100170 parser_SAF(fun, set, linrows, lincols, linvals, nlin, lin_lcon, lin_ucon)
101171
@@ -157,11 +227,64 @@ function parser_VAF(fun, set, linrows, lincols, linvals, nlin, lin_lcon, lin_uco
157227end
158228
159229"""
160- parser_MOI(moimodel )
230+ parser_SQF(fun, set, qcons, quad_lcon, quad_ucon )
161231
162- Parse linear constraints of a `MOI.ModelLike`.
232+ Parse a `ScalarQuadraticFunction` fun with its associated set.
233+ `qcons`, `quad_lcon`, `quad_ucon` are updated.
163234"""
164- function parser_MOI (moimodel)
235+ function parser_SQF (fun, set, nvar, qcons, quad_lcon, quad_ucon)
236+
237+ b = spzeros (Float64, nvar)
238+ rows = Int[]
239+ cols = Int[]
240+ vals = Float64[]
241+
242+ # Parse a ScalarAffineTerm{Float64}(coefficient, variable_index)
243+ for term in fun. affine_terms
244+ b[term. variable. value] = term. coefficient
245+ end
246+
247+ # Parse a ScalarQuadraticTerm{Float64}(coefficient, variable_index_1, variable_index_2)
248+ for term in fun. quadratic_terms
249+ i = term. variable_1. value
250+ j = term. variable_2. value
251+ if i ≥ j
252+ push! (rows, i)
253+ push! (cols, j)
254+ else
255+ push! (cols, j)
256+ push! (rows, i)
257+ end
258+ push! (vals, term. coefficient)
259+ end
260+
261+ if typeof (set) in (MOI. Interval{Float64}, MOI. GreaterThan{Float64})
262+ push! (quad_lcon, - fun. constant + set. lower)
263+ elseif typeof (set) == MOI. EqualTo{Float64}
264+ push! (quad_lcon, - fun. constant + set. value)
265+ else
266+ push! (quad_lcon, - Inf )
267+ end
268+
269+ if typeof (set) in (MOI. Interval{Float64}, MOI. LessThan{Float64})
270+ push! (quad_ucon, - fun. constant + set. upper)
271+ elseif typeof (set) == MOI. EqualTo{Float64}
272+ push! (quad_ucon, - fun. constant + set. value)
273+ else
274+ push! (quad_ucon, Inf )
275+ end
276+
277+ nnzh = length (vals)
278+ qcon = QuadraticConstraint (COO[rows, cols, vals], b)
279+ push! (qcons, qcon)
280+ end
281+
282+ """
283+ parser_MOI(moimodel, nvar)
284+
285+ Parse linear and quadratic constraints of a `MOI.ModelLike`.
286+ """
287+ function parser_MOI (moimodel, nvar)
165288
166289 # Variables associated to linear constraints
167290 nlin = 0
@@ -171,10 +294,16 @@ function parser_MOI(moimodel)
171294 lin_lcon = Float64[]
172295 lin_ucon = Float64[]
173296
297+ # Variables associated to quadratic constraints
298+ nquad = 0
299+ qcons = QuadraticConstraint[]
300+ quad_lcon = Float64[]
301+ quad_ucon = Float64[]
302+
174303 contypes = MOI. get (moimodel, MOI. ListOfConstraintTypesPresent ())
175304 for (F, S) in contypes
176305 F == VI && continue
177- F <: AF || @warn (" Function $F is not supported." )
306+ F <: AF || F <: SQF || @warn (" Function $F is not supported." )
178307 S <: LS || @warn (" Set $S is not supported." )
179308
180309 conindices = MOI. get (moimodel, MOI. ListOfConstraintIndices {F, S} ())
@@ -189,13 +318,21 @@ function parser_MOI(moimodel)
189318 parser_VAF (fun, set, linrows, lincols, linvals, nlin, lin_lcon, lin_ucon)
190319 nlin += set. dimension
191320 end
321+ if typeof (fun) <: SQF
322+ parser_SQF (fun, set, nvar, qcons, quad_lcon, quad_ucon)
323+ nquad += 1
324+ end
192325 end
193326 end
194327 coo = COO (linrows, lincols, linvals)
195328 nnzj = length (linvals)
196329 lincon = LinearConstraints (coo, nnzj)
197330
198- return nlin, lincon, lin_lcon, lin_ucon
331+ nnzj, jrows, jcols = jacobian_quad (qcons)
332+ nnzh, hrows, hcols = hessian_quad (qcons)
333+ quadcon = QuadraticConstraints (qcons, nnzj, jrows, jcols, nnzh, hrows, hcols)
334+
335+ return nlin, lincon, lin_lcon, lin_ucon, nquad, quadcon, quad_lcon, quad_ucon
199336end
200337
201338"""
0 commit comments