Skip to content

Commit a8aa282

Browse files
committed
Ensure extract_function is canonical
1 parent 53860d2 commit a8aa282

2 files changed

Lines changed: 29 additions & 15 deletions

File tree

src/Utilities/sparse_matrix.jl

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ function extract_function(
239239
continue
240240
end
241241
r = _shift(A.rowval[idx], _indexing(A), OneBasedIndexing())
242-
if r == row
242+
# `modify_coefficients` can create zeros
243+
if r == row && !iszero(A.nzval[idx])
243244
push!(
244245
func.terms,
245246
MOI.ScalarAffineTerm(A.nzval[idx], MOI.VariableIndex(col)),
@@ -266,10 +267,14 @@ function _extract_column_as_function(
266267
func = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], constant)
267268
for i in SparseArrays.nzrange(A, col)
268269
row = _shift(A.rowval[i], _indexing(A), OneBasedIndexing())
269-
push!(
270-
func.terms,
271-
MOI.ScalarAffineTerm(value_map(A.nzval[i]), MOI.VariableIndex(row)),
272-
)
270+
val = value_map(A.nzval[i])
271+
# `modify_coefficients` can create zeros
272+
if !iszero(val)
273+
push!(
274+
func.terms,
275+
MOI.ScalarAffineTerm(val, MOI.VariableIndex(row)),
276+
)
277+
end
273278
end
274279
return func
275280
end
@@ -293,16 +298,19 @@ function extract_function(
293298
if row != rows[output_index]
294299
continue
295300
end
296-
push!(
297-
func.terms,
298-
MOI.VectorAffineTerm(
299-
output_index,
300-
MOI.ScalarAffineTerm(
301-
A.nzval[idx[col]],
302-
MOI.VariableIndex(col),
301+
# `modify_coefficients` can create zeros
302+
if !iszero(A.nzval[idx[col]])
303+
push!(
304+
func.terms,
305+
MOI.VectorAffineTerm(
306+
output_index,
307+
MOI.ScalarAffineTerm(
308+
A.nzval[idx[col]],
309+
MOI.VariableIndex(col),
310+
),
303311
),
304-
),
305-
)
312+
)
313+
end
306314
idx[col] += 1
307315
end
308316
end

test/Utilities/test_matrix_of_constraints.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ function test_modify_scalar_coefficient_change()
665665
@test f 5x + 3y
666666
MOI.modify(model, c, MOI.ScalarCoefficientChange(y, 0))
667667
f = MOI.get(model, MOI.ConstraintFunction(), c)
668+
@test MOI.Utilities.is_canonical(f)
668669
@test f 5x + 0y
669670
return
670671
end
@@ -901,14 +902,19 @@ function test_modify_multirow_change_to_zero()
901902
index_map = MOI.copy_to(model, src)
902903
ci = index_map[c]
903904
x1 = index_map[x[1]]
905+
x2 = index_map[x[2]]
904906
MOI.modify(model, ci, MOI.MultirowChange(x1, [(1, 0)]))
905907
f = MOI.get(model, MOI.ConstraintFunction(), ci)
908+
@test MOI.Utilities.is_canonical(f)
909+
@test length(f.terms) == 3
906910
coefs = Dict(
907911
(t.output_index, t.scalar_term.variable) => t.scalar_term.coefficient
908912
for t in f.terms
909913
)
910-
@test coefs[(1, x1)] == 0
914+
@test !haskey(coefs, (1, x1))
911915
@test coefs[(2, x1)] == 4
916+
@test coefs[(1, x2)] == 3
917+
@test coefs[(2, x2)] == 5
912918
return
913919
end
914920

0 commit comments

Comments
 (0)