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

Commit dc8cce2

Browse files
authored
Updates for MOI v0.3 (#16)
1 parent 15e7a6a commit dc8cce2

File tree

5 files changed

+80
-52
lines changed

5 files changed

+80
-52
lines changed

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
julia 0.6
2-
MathOptInterface 0.2 0.3
2+
MathOptInterface 0.3 0.4

src/constraints/scalaraffine.jl

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@ function addlinearconstraint!(m::LinQuadOptimizer, func::Linear, set::S) where S
2727
end
2828

2929
function addlinearconstraint!(m::LinQuadOptimizer, func::Linear, set::IV)
30-
add_ranged_constraints!(m, [1], getcol.(m, func.variables), func.coefficients, [set.lower], [set.upper])
30+
columns = [getcol(m, term.variable_index) for term in func.terms]
31+
coefficients = [term.coefficient for term in func.terms]
32+
add_ranged_constraints!(m, [1], columns, coefficients, [set.lower], [set.upper])
3133
end
3234

3335
function addlinearconstraint!(m::LinQuadOptimizer, func::Linear, sense::Cchar, rhs)
3436
if abs(func.constant) > eps(Float64)
3537
warn("Constant in scalar function moved into set.")
3638
end
37-
add_linear_constraints!(m, [1], getcol.(m, func.variables), func.coefficients, [sense], [rhs - func.constant])
39+
columns = [getcol(m, term.variable_index) for term in func.terms]
40+
coefficients = [term.coefficient for term in func.terms]
41+
add_linear_constraints!(m, [1], columns, coefficients, [sense], [rhs - func.constant])
3842
end
3943

4044
#=
@@ -77,17 +81,17 @@ function addlinearconstraints!(m::LinQuadOptimizer, func::Vector{Linear}, set::V
7781
lowerbounds[i] -= f.constant
7882
upperbounds[i] -= f.constant
7983
end
80-
nnz += length(f.coefficients)
84+
nnz += length(f.terms)
8185
end
8286
row_starts = Vector{Int}(length(func)) # index of start of each row
8387
column_indices = Vector{Int}(nnz) # flattened columns for each function
8488
coefficients = Vector{Float64}(nnz) # corresponding non-zeros
8589
i = 1
8690
for (fi, f) in enumerate(func)
8791
row_starts[fi] = i
88-
for (var, coef) in zip(f.variables, f.coefficients)
89-
column_indices[i] = getcol(m, var)
90-
coefficients[i] = coef
92+
for term in f.terms
93+
column_indices[i] = getcol(m, term.variable_index)
94+
coefficients[i] = term.coefficient
9195
i += 1
9296
end
9397
end
@@ -102,17 +106,17 @@ function addlinearconstraints!(m::LinQuadOptimizer, func::Vector{Linear}, sense:
102106
warn("Constant in scalar function moved into set.")
103107
rhs[i] -= f.constant
104108
end
105-
nnz += length(f.coefficients)
109+
nnz += length(f.terms)
106110
end
107111
rowbegins = Vector{Int}(length(func)) # index of start of each row
108112
column_indices = Vector{Int}(nnz) # flattened columns for each function
109113
nnz_vals = Vector{Float64}(nnz) # corresponding non-zeros
110114
cnt = 1
111115
for (fi, f) in enumerate(func)
112116
rowbegins[fi] = cnt
113-
for (var, coef) in zip(f.variables, f.coefficients)
114-
column_indices[cnt] = getcol(m, var)
115-
nnz_vals[cnt] = coef
117+
for term in f.terms
118+
column_indices[cnt] = getcol(m, term.variable_index)
119+
nnz_vals[cnt] = term.coefficient
116120
cnt += 1
117121
end
118122
end
@@ -144,7 +148,12 @@ MOI.canget(m::LinQuadOptimizer, ::MOI.ConstraintFunction, ::Type{<:LCI{<: LinSet
144148
function MOI.get(m::LinQuadOptimizer, ::MOI.ConstraintFunction, c::LCI{<: LinSets})
145149
# TODO more efficiently
146150
colidx, coefs = get_linear_constraint(m, m[c])
147-
Linear(m.variable_references[colidx+1], coefs, -m.constraint_constant[m[c]])
151+
terms = map(
152+
(v,c)->MOI.ScalarAffineTerm{Float64}(c,v),
153+
m.variable_references[colidx+1],
154+
coefs
155+
)
156+
Linear(terms, -m.constraint_constant[m[c]])
148157
end
149158

150159
#=

src/constraints/scalarquadratic.jl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,19 @@ function addquadraticconstraint!(m::LinQuadOptimizer, f::Quad, sense::Cchar, rhs
3232
if abs(f.constant) > 0
3333
warn("Constant in quadratic function. Moving into set")
3434
end
35+
quadratic_columns_1 = [getcol(m, term.variable_index_1) for term in f.quadratic_terms]
36+
quadratic_columns_2 = [getcol(m, term.variable_index_2) for term in f.quadratic_terms]
37+
quadratic_coefficients = [term.coefficient for term in f.quadratic_terms]
3538
ri, ci, vi = reduceduplicates(
36-
getcol.(m, f.quadratic_rowvariables),
37-
getcol.(m, f.quadratic_colvariables),
38-
f.quadratic_coefficients
39+
quadratic_columns_1,
40+
quadratic_columns_2,
41+
quadratic_coefficients
3942
)
43+
affine_columns = [getcol(m, term.variable_index) for term in f.affine_terms]
44+
affine_coefficients = [term.coefficient for term in f.affine_terms]
4045
add_quadratic_constraint!(m,
41-
getcol.(m, f.affine_variables),
42-
f.affine_coefficients,
46+
affine_columns,
47+
affine_coefficients,
4348
rhs - f.constant,
4449
sense,
4550
ri, ci, vi

src/constraints/vectoraffine.jl

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ constrdict(m::LinQuadOptimizer, ::VLCI{MOI.Nonpositives}) = cmap(m).nonpositives
66
constrdict(m::LinQuadOptimizer, ::VLCI{MOI.Zeros}) = cmap(m).zeros
77

88
function MOI.addconstraint!(m::LinQuadOptimizer, func::VecLin, set::S) where S <: VecLinSets
9-
@assert MOI.dimension(set) == length(func.constant)
9+
@assert MOI.dimension(set) == length(func.constants)
1010

1111
nrows = get_number_linear_constraints(m)
1212
addlinearconstraint!(m, func, backend_type(m,set))
@@ -20,31 +20,33 @@ function MOI.addconstraint!(m::LinQuadOptimizer, func::VecLin, set::S) where S <
2020
for i in 1:MOI.dimension(set)
2121
push!(m.constraint_primal_solution, NaN)
2222
push!(m.constraint_dual_solution, NaN)
23-
push!(m.constraint_constant, func.constant[i])
23+
push!(m.constraint_constant, func.constants[i])
2424
end
2525
ref
2626
end
2727

2828
function addlinearconstraint!(m::LinQuadOptimizer, func::VecLin, sense::Cchar)
29-
@assert length(func.outputindex) == length(func.variables) == length(func.coefficients)
30-
# get list of unique rows
31-
rows = unique(func.outputindex)
32-
@assert length(rows) == length(func.constant)
29+
outputindex = [term.output_index for term in func.terms]
30+
columns = [getcol(m, term.scalar_term.variable_index) for term in func.terms]
31+
coefficients = [term.scalar_term.coefficient for term in func.terms]
3332
# sort into row order
34-
pidx = sortperm(func.outputindex)
35-
cols = getcol.(m, func.variables)[pidx]
36-
vals = func.coefficients[pidx]
37-
# loop through to gte starting position of each row
38-
rowbegins = Vector{Int}(length(rows))
33+
pidx = sortperm(outputindex)
34+
permute!(columns, pidx)
35+
permute!(coefficients, pidx)
36+
37+
# check that there is at least a RHS for each row
38+
@assert maximum(outputindex) <= length(func.constants)
39+
# loop through to get starting position of each row
40+
rowbegins = Vector{Int}(length(func.constants))
3941
rowbegins[1] = 1
4042
cnt = 1
4143
for i in 2:length(pidx)
42-
if func.outputindex[pidx[i]] != func.outputindex[pidx[i-1]]
44+
if outputindex[pidx[i]] != outputindex[pidx[i-1]]
4345
cnt += 1
4446
rowbegins[cnt] = i
4547
end
4648
end
47-
add_linear_constraints!(m, rowbegins, cols, vals, fill(sense, length(rows)), -func.constant)
49+
add_linear_constraints!(m, rowbegins, columns, coefficients, fill(sense, length(func.constants)), -func.constants)
4850
end
4951

5052
MOI.canmodifyconstraint(m::LinQuadOptimizer, ::VLCI{<: VecLinSets}, ::Type{MOI.VectorConstantChange{Float64}}) = true
@@ -93,16 +95,22 @@ MOI.canget(m::LinQuadOptimizer, ::MOI.ConstraintFunction, ::Type{VLCI{S}}) where
9395
function MOI.get(m::LinQuadOptimizer, ::MOI.ConstraintFunction, c::VLCI{<: VecLinSets})
9496
ctrs = m[c]
9597
n = length(ctrs)
96-
out = MOI.VectorAffineFunction(Int[],VarInd[],Float64[],Float64[])
98+
constants = Float64[]
99+
terms = MOI.VectorAffineTerm{Float64}[]
97100
for i in 1:n
98101
rhs = get_rhs(m, ctrs[i])
99-
push!(out.constant, -rhs)
100-
102+
push!(constants, -rhs)
101103
# TODO more efficiently
102104
colidx, coefs = get_linear_constraint(m, ctrs[i])
103-
append!(out.variables, m.variable_references[colidx+1])
104-
append!(out.coefficients, coefs)
105-
append!(out.outputindex, i*ones(Int,length(coefs)))
105+
for (column, coefficient) in zip(colidx, coefs)
106+
push!(terms, MOI.VectorAffineTerm{Float64}(
107+
i,
108+
MOI.ScalarAffineTerm{Float64}(
109+
coefficient, m.variable_references[column+1]
110+
)
111+
)
112+
)
113+
end
106114
end
107-
return out
115+
return MOI.VectorAffineFunction(terms, constants)
108116
end

src/objective.jl

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function MOI.set!(m::LinQuadOptimizer, ::MOI.ObjectiveSense, sense::MOI.Optimiza
1616
elseif sense == MOI.FeasibilitySense
1717
# we set the objective sense to :min, and the objective to 0.0
1818
change_objective_sense!(m, :min)
19-
unsafe_set!(m, MOI.ObjectiveFunction{Linear}(), MOI.ScalarAffineFunction(VarInd[],Float64[],0.0))
19+
unsafe_set!(m, MOI.ObjectiveFunction{Linear}(), MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}[],0.0))
2020
m.obj_type = AffineObjective
2121
m.obj_sense = MOI.FeasibilitySense
2222
else
@@ -64,28 +64,29 @@ function unsafe_set!(m::LinQuadOptimizer, ::MOI.ObjectiveFunction{F}, objf::Line
6464
end
6565
m.obj_type = AffineObjective
6666
m.single_obj_var = nothing
67-
set_linear_objective!(m, getcol.(m, objf.variables), objf.coefficients)
67+
columns = [getcol(m, term.variable_index) for term in objf.terms]
68+
coefficients = [term.coefficient for term in objf.terms]
69+
set_linear_objective!(m, columns, coefficients)
6870
m.objective_constant = objf.constant
6971
nothing
7072
end
7173

7274
function MOI.set!(m::LinQuadOptimizer, ::MOI.ObjectiveFunction, objf::Quad)
7375
m.obj_type = QuadraticObjective
7476
m.single_obj_var = nothing
75-
set_linear_objective!(m,
76-
getcol.(m, objf.affine_variables),
77-
objf.affine_coefficients
78-
)
77+
columns = [getcol(m, term.variable_index) for term in objf.affine_terms]
78+
coefficients = [term.coefficient for term in objf.affine_terms]
79+
set_linear_objective!(m, columns, coefficients)
80+
81+
quadratic_columns_1 = [getcol(m, term.variable_index_1) for term in objf.quadratic_terms]
82+
quadratic_columns_2 = [getcol(m, term.variable_index_2) for term in objf.quadratic_terms]
83+
quadratic_coefficients = [term.coefficient for term in objf.quadratic_terms]
7984
ri, ci, vi = reduceduplicates(
80-
getcol.(m, objf.quadratic_rowvariables),
81-
getcol.(m, objf.quadratic_colvariables),
82-
objf.quadratic_coefficients
83-
)
84-
set_quadratic_objective!(m,
85-
ri,
86-
ci,
87-
vi
85+
quadratic_columns_1,
86+
quadratic_columns_2,
87+
quadratic_coefficients
8888
)
89+
set_quadratic_objective!(m, ri, ci, vi)
8990
m.objective_constant = objf.constant
9091
nothing
9192
end
@@ -103,7 +104,12 @@ MOI.canget(m::LinQuadOptimizer, ::MOI.ObjectiveFunction{Linear}) = m.obj_type !=
103104
function MOI.get(m::LinQuadOptimizer, ::MOI.ObjectiveFunction{Linear})
104105
variable_coefficients = zeros(length(m.variable_references))
105106
get_linear_objective!(m, variable_coefficients)
106-
Linear(m.variable_references, variable_coefficients, m.objective_constant)
107+
terms = map(
108+
(v,c)->MOI.ScalarAffineTerm{Float64}(c,v),
109+
m.variable_references,
110+
variable_coefficients
111+
)
112+
Linear(terms, m.objective_constant)
107113
end
108114

109115
#=

0 commit comments

Comments
 (0)