Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions src/Utilities/constraints.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"""
normalize_and_add_constraint(model::MOI.ModelLike,
func::MOI.AbstractScalarFunction,
set::MOI.AbstractScalarSet;
allow_modify_function::Bool=false)
normalize_and_add_constraint(
model::MOI.ModelLike,
func::MOI.AbstractScalarFunction,
set::MOI.AbstractScalarSet;
allow_modify_function::Bool = false,
)

Adds the scalar constraint obtained by moving the constant term in `func` to
the set in `model`. If `allow_modify_function` is `true` then the function
`func` can be modified.
Adds the scalar constraint obtained by moving the constant term in `func` to the
set in `model`. If `allow_modify_function` is `true` then the function `func`
can be modified.
"""
function normalize_and_add_constraint end

function normalize_and_add_constraint(
model::MOI.ModelLike,
func::MOI.AbstractScalarFunction,
Expand All @@ -27,13 +27,14 @@ function normalize_and_add_constraint(
end

"""
normalize_constant(func::MOI.AbstractScalarFunction,
set::MOI.AbstractScalarSet;
allow_modify_function::Bool=false)
normalize_constant(
func::MOI.AbstractScalarFunction,
set::MOI.AbstractScalarSet;
allow_modify_function::Bool = false,
)

Return the `func`-in-`set` constraint in normalized form. That is, if `func` is
[`MOI.ScalarQuadraticFunction`](@ref) or
[`MOI.ScalarAffineFunction`](@ref), the
[`MOI.ScalarQuadraticFunction`](@ref) or [`MOI.ScalarAffineFunction`](@ref), the
constant is moved to the set. If `allow_modify_function` is `true` then the
function `func` can be modified.
"""
Expand All @@ -44,6 +45,7 @@ function normalize_constant(
)
return func, set
end

function normalize_constant(
func::Union{MOI.ScalarAffineFunction{T},MOI.ScalarQuadraticFunction{T}},
set::MOI.AbstractScalarSet;
Expand Down
81 changes: 50 additions & 31 deletions test/Utilities/constraints.jl
Original file line number Diff line number Diff line change
@@ -1,37 +1,56 @@
module TestConstraints

using Test
import MathOptInterface
const MOI = MathOptInterface

@testset "Scalar" begin
model = MOIU.Model{Float64}()
x = MOI.add_variable(model)
@testset "SingleVariable" begin
f = MOI.SingleVariable(x)
ci = MOIU.normalize_and_add_constraint(
model,
f,
MOI.EqualTo(1.0),
allow_modify_function = false,
)
@test MOI.get(model, MOI.ConstraintFunction(), ci) == f
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.EqualTo(1.0)
end
@testset "ScalarAffineFunction" begin
f = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 2.0)
g = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0)
ci = MOIU.normalize_and_add_constraint(model, f, MOI.EqualTo(3.0))
@test f.constant == 2.0
@test MOI.get(model, MOI.ConstraintFunction(), ci) ≈ g
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.EqualTo(1.0)
ci = MOIU.normalize_and_add_constraint(
model,
f,
MOI.Interval(-1.0, 1.0),
allow_modify_function = true,
)
@test f.constant == 0.0
@test MOI.get(model, MOI.ConstraintFunction(), ci) ≈ g
@test MOI.get(model, MOI.ConstraintSet(), ci) ==
MOI.Interval(-3.0, -1.0)
function runtests()
for name in names(@__MODULE__; all = true)
if startswith("$(name)", "test_")
@testset "$(name)" begin
getfield(@__MODULE__, name)()
end
end
end
return
end

function test_normalize_and_add_constrant_SingleVariable()
model = MOI.Utilities.Model{Float64}()
x = MOI.add_variable(model)
f = MOI.SingleVariable(x)
ci = MOI.Utilities.normalize_and_add_constraint(
model,
f,
MOI.EqualTo(1.0),
allow_modify_function = false,
)
@test MOI.get(model, MOI.ConstraintFunction(), ci) == f
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.EqualTo(1.0)
return
end

function test_normalize_and_add_constrant_ScalarAffineFunction()
model = MOI.Utilities.Model{Float64}()
x = MOI.add_variable(model)
f = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 2.0)
g = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0)
ci = MOI.Utilities.normalize_and_add_constraint(model, f, MOI.EqualTo(3.0))
@test f.constant == 2.0
@test MOI.get(model, MOI.ConstraintFunction(), ci) ≈ g
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.EqualTo(1.0)
ci = MOI.Utilities.normalize_and_add_constraint(
model,
f,
MOI.Interval(-1.0, 1.0),
allow_modify_function = true,
)
@test f.constant == 0.0
@test MOI.get(model, MOI.ConstraintFunction(), ci) ≈ g
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.Interval(-3.0, -1.0)
return
end

end # module

TestConstraints.runtests()