Skip to content
This repository was archived by the owner on Jun 14, 2020. It is now read-only.

Commit e1b43ed

Browse files
joaquimgodow
authored andcommitted
Add quadratics and interval features (#23)
1 parent f5a69c5 commit e1b43ed

File tree

4 files changed

+97
-11
lines changed

4 files changed

+97
-11
lines changed

src/constraints/scalaraffine.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,18 +131,17 @@ end
131131
Constraint set of Linear function
132132
=#
133133

134-
MOI.canget(m::LinQuadOptimizer, ::MOI.ConstraintSet, ::Type{LCI{S}}) where S <: Union{LE, GE, EQ} = true
134+
MOI.canget(::LinQuadOptimizer, ::MOI.ConstraintSet, ::Type{LCI{S}}) where S <: Union{LE, GE, EQ} = true
135135
function MOI.get(m::LinQuadOptimizer, ::MOI.ConstraintSet, c::LCI{S}) where S <: Union{LE, GE, EQ}
136136
rhs = get_rhs(m, m[c])
137137
S(rhs+m.constraint_constant[m[c]])
138138
end
139139

140-
MOI.canget(m::LinQuadOptimizer, ::MOI.ConstraintSet, ::Type{LCI{IV}}) = false
141-
# TODO(odow): get constraint sets for ranged constraints.
142-
# function MOI.get(m::LinQuadOptimizer, ::MOI.ConstraintSet, c::LCI{IV})
143-
# ???
144-
# IV(lowerbound+m.constraint_constant[m[c]], upperbound + m.constraint_constant[m[c]])
145-
# end
140+
MOI.canget(::LinQuadOptimizer, ::MOI.ConstraintSet, ::Type{LCI{IV}}) = false
141+
function MOI.get(m::LinQuadOptimizer, ::MOI.ConstraintSet, c::LCI{IV})
142+
lowerbound, upperbound = get_range(m, m[c])
143+
IV(lowerbound+m.constraint_constant[m[c]], upperbound + m.constraint_constant[m[c]])
144+
end
146145

147146
#=
148147
Constraint function of Linear function

src/constraints/scalarquadratic.jl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,43 @@ function MOI.delete!(m::LinQuadOptimizer, c::QCI{<: LinSets})
9696
shift_references_after_delete_quadratic!(m, row)
9797
delete!(dict, c)
9898
end
99+
100+
#=
101+
Constraint set of Linear function
102+
=#
103+
104+
MOI.canget(m::LinQuadOptimizer, ::MOI.ConstraintSet, ::Type{QCI{S}}) where S <: Union{LE, GE, EQ} = true
105+
function MOI.get(m::LinQuadOptimizer, ::MOI.ConstraintSet, c::QCI{S}) where S <: Union{LE, GE, EQ}
106+
rhs = get_rhs(m, m[c])
107+
S(rhs)
108+
end
109+
110+
MOI.canget(m::LinQuadOptimizer, ::MOI.ConstraintSet, ::Type{QCI{IV}}) = false
111+
112+
#=
113+
Constraint function of Linear function
114+
=#
115+
116+
MOI.canget(m::LinQuadOptimizer, ::MOI.ConstraintFunction, ::Type{<:QCI{<: LinSets}}) = true
117+
function MOI.get(m::LinQuadOptimizer, ::MOI.ConstraintFunction, c::QCI{<: LinSets})
118+
# TODO more efficiently
119+
colidx, coefs, Q = get_quadratic_constraint(m, m[c])
120+
affine_terms = map(
121+
(v,c)->MOI.ScalarAffineTerm{Float64}(c,v),
122+
m.variable_references[colidx+1],
123+
coefs
124+
)
125+
rows = rowvals(Q)
126+
vals = nonzeros(Q)
127+
nrows, ncols = size(Q)
128+
quadratic_terms = MOI.ScalarQuadraticTerm{Float64}[]
129+
sizehint!(quadratic_terms, length(vals))
130+
for i = 1:ncols
131+
for j in nzrange(Q, i)
132+
row = rows[j]
133+
val = vals[j]
134+
push!(quadratic_terms, MOI.ScalarQuadraticTerm{Float64}(2*val, m.variable_references[row], m.variable_references[i]))
135+
end
136+
end
137+
Quad(affine_terms, quadratic_terms, 0.0) # constant was moved into set
138+
end

src/objective.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,31 @@ function MOI.get(m::LinQuadOptimizer, ::MOI.ObjectiveFunction{Linear})
112112
Linear(terms, m.objective_constant)
113113
end
114114

115+
MOI.canget(m::LinQuadOptimizer, ::MOI.ObjectiveFunction{Quad}) = m.obj_type == QuadraticObjective
116+
function MOI.get(m::LinQuadOptimizer, ::MOI.ObjectiveFunction{Quad})
117+
variable_coefficients = zeros(length(m.variable_references))
118+
get_linear_objective!(m, variable_coefficients)
119+
affine_terms = map(
120+
(v,c)->MOI.ScalarAffineTerm{Float64}(c,v),
121+
m.variable_references,
122+
variable_coefficients
123+
)
124+
Q = get_quadratic_terms_objective(m)
125+
rows = rowvals(Q)
126+
vals = nonzeros(Q)
127+
nrows, ncols = size(Q)
128+
quadratic_terms = MOI.ScalarQuadraticTerm{Float64}[]
129+
sizehint!(quadratic_terms, length(vals))
130+
for i = 1:ncols
131+
for j in nzrange(Q, i)
132+
row = rows[j]
133+
val = vals[j]
134+
push!(quadratic_terms, MOI.ScalarQuadraticTerm{Float64}(0.5*val, m.variable_references[row], m.variable_references[i]))
135+
end
136+
end
137+
Quad(affine_terms, quadratic_terms, m.objective_constant)
138+
end
139+
115140
#=
116141
Modify objective function
117142
=#

src/solver_interface.jl

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ is often implemented via multiple API calls.
172172
function add_ranged_constraints! end
173173

174174
"""
175-
modify_ranged_constraint!(m, rows::Vector{Int}, lowerbound::Vector{Float64}, upperbound::Vector{Float64})
175+
modify_ranged_constraints!(m, rows::Vector{Int}, lowerbound::Vector{Float64}, upperbound::Vector{Float64})
176176
177177
Modify the lower and upperbounds of a ranged constraint in the model `m`.
178178
@@ -181,7 +181,6 @@ is often implemented via multiple API calls.
181181
"""
182182
function modify_ranged_constraints! end
183183

184-
185184
"""
186185
get_rhs(m, row::Int)::Float64
187186
@@ -191,6 +190,13 @@ the model `m`.
191190
function get_rhs end
192191
@deprecate lqs_getrhs get_rhs
193192

193+
"""
194+
get_range(m, row::Int)::Tuple{Float64,Float64}
195+
196+
Get the range which the constraint `row` belongs to. The output of the function is the tuple `lowerbound, upperbound` of bounds: `lowerbound <= a'x < = upperbound`
197+
"""
198+
function get_range end
199+
194200
"""
195201
get_linear_constraint(m, row::Int)::Tuple{Vector{Int}, Vector{Float64}}
196202
@@ -241,7 +247,7 @@ the model `m`.
241247
function delete_quadratic_constraints! end
242248

243249
"""
244-
lqs_chgctype(m, cols::Vector{Int}, types):Void
250+
change_variable_types(m, cols::Vector{Int}, types):Void
245251
246252
Change the variable types. Type is the output of one of:
247253
- `backend_type(m, ::ZeroOne)`, for binary variables;
@@ -336,6 +342,15 @@ for the Q matrix in `0.5 x' Q x`.
336342
function set_quadratic_objective! end
337343
@deprecate lqs_copyquad! set_quadratic_objective!
338344

345+
"""
346+
get_quadratic_constraint(m, row::Int)::Tuple{Vector{Int}, Vector{Float64}, SparseMatrixCSC{Float64,Int64}}
347+
348+
Get the linear and quadratic components of the constraint in the 1-indexed row `row` in
349+
the model `m`. Returns a tuple of `(lin_cols, lin_vals, Q)`.
350+
Where `Q` represents the matrix in CSC format.
351+
"""
352+
function get_quadratic_constraint end
353+
339354
"""
340355
set_linear_objective!(m, cols::Vector{Int}, coefs::Vector{Float64})::Void
341356
@@ -356,12 +371,19 @@ function change_objective_sense! end
356371
"""
357372
get_linear_objective!(m, x::Vector{Float64})
358373
359-
Change the linear coefficients of the objective and store
374+
Get the linear coefficients of the objective and store
360375
in `x`.
361376
"""
362377
function get_linear_objective! end
363378
@deprecate lqs_getobj get_linear_objective!
364379

380+
"""
381+
get_quadratic_terms_objective(m)::SparseMatrixCSC{Float64,Int64}
382+
383+
Get quadratic terms of the objective function returned in sparse CSC format.
384+
"""
385+
function get_quadratic_terms_objective end
386+
365387
"""
366388
get_objectivesense(m)::MOI.OptimizationSense
367389

0 commit comments

Comments
 (0)