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

Commit a916eea

Browse files
authored
Reduce duplicates on the off-diagonal terms (#19)
1 parent 8ce934a commit a916eea

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

src/constraints/scalarquadratic.jl

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function addquadraticconstraint!(m::LinQuadOptimizer, f::Quad, sense::Cchar, rhs
3535
quadratic_columns_1 = [getcol(m, term.variable_index_1) for term in f.quadratic_terms]
3636
quadratic_columns_2 = [getcol(m, term.variable_index_2) for term in f.quadratic_terms]
3737
quadratic_coefficients = [term.coefficient for term in f.quadratic_terms]
38-
ri, ci, vi = reduceduplicates(
38+
ri, ci, vi = reduce_duplicates!(
3939
quadratic_columns_1,
4040
quadratic_columns_2,
4141
quadratic_coefficients
@@ -51,25 +51,36 @@ function addquadraticconstraint!(m::LinQuadOptimizer, f::Quad, sense::Cchar, rhs
5151
)
5252
end
5353

54-
function reduceduplicates(rowi::Vector{T}, coli::Vector{T}, vals::Vector{S}) where T where S
55-
@assert length(rowi) == length(coli) == length(vals)
56-
d = Dict{Tuple{T, T},S}()
57-
for (r,c,v) in zip(rowi, coli, vals)
58-
if haskey(d, (r,c))
59-
d[(r,c)] += v
60-
else
61-
d[(r,c)] = v
54+
"""
55+
reduce_duplicates!(rows::Vector{T}, cols::Vector{T}, vals::Vector{S})
56+
57+
Given a matrix specified by row indices in `rows`, column indices in `cols` and
58+
coefficients in `vals`, return new `rows`, `cols`, and `vals` vectors with
59+
duplicate elements summed and any coefficients in the lower triangle moved to
60+
the upper triangle.
61+
62+
This function swaps element `i` in `rows` and `cols` if `rows[i]>cols[i]`.
63+
64+
# Examples
65+
```jldoctest
66+
julia> reduce_duplicates!(
67+
[1, 2, 2, 2], # rows
68+
[1, 1, 2, 2], # cols
69+
[1, 0.5, 1, 1] # vals
70+
)
71+
([1, 1, 2], [1, 2, 2], [1.0, 0.5, 2.0])
72+
```
73+
"""
74+
function reduce_duplicates!(rows::Vector{T}, cols::Vector{T}, vals::Vector{S}) where T where S
75+
@assert length(rows) == length(cols) == length(vals)
76+
for i in 1:length(rows)
77+
if rows[i] > cols[i]
78+
tmp = rows[i]
79+
rows[i] = cols[i]
80+
cols[i] = tmp
6281
end
6382
end
64-
ri = Vector{T}(length(d))
65-
ci = Vector{T}(length(d))
66-
vi = Vector{S}(length(d))
67-
for (i, (key, val)) in enumerate(d)
68-
ri[i] = key[1]
69-
ci[i] = key[2]
70-
vi[i] = val
71-
end
72-
ri, ci, vi
83+
findnz(sparse(rows, cols, vals))
7384
end
7485

7586

src/objective.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ function MOI.set!(m::LinQuadOptimizer, ::MOI.ObjectiveFunction, objf::Quad)
8181
quadratic_columns_1 = [getcol(m, term.variable_index_1) for term in objf.quadratic_terms]
8282
quadratic_columns_2 = [getcol(m, term.variable_index_2) for term in objf.quadratic_terms]
8383
quadratic_coefficients = [term.coefficient for term in objf.quadratic_terms]
84-
ri, ci, vi = reduceduplicates(
84+
ri, ci, vi = reduce_duplicates!(
8585
quadratic_columns_1,
8686
quadratic_columns_2,
8787
quadratic_coefficients

0 commit comments

Comments
 (0)