Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
blegat committed Sep 4, 2019
1 parent f96a3dc commit ccba971
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 14 deletions.
8 changes: 8 additions & 0 deletions src/Bridges/Objective/functionize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ function MOIB.set_objective_function_type(::Type{FunctionizeBridge{T}}) where T
return MOI.ScalarAffineFunction{T}
end

# Attributes, Bridge acting as a model
function MOI.get(bridge::FunctionizeBridge, ::MOI.NumberOfVariables)
return 0
end
function MOI.get(bridge::FunctionizeBridge, ::MOI.ListOfVariableIndices)
return MOI.VariableIndex[]
end

# No variables or constraints are created in this bridge so there is nothing to
# delete.
function MOI.delete(model::MOI.ModelLike, bridge::FunctionizeBridge) end
Expand Down
21 changes: 20 additions & 1 deletion src/Bridges/Objective/slack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function bridge_objective(::Type{SlackBridge{T, F, G}}, model::MOI.ModelLike,
error("Set `MOI.ObjectiveSense` before `MOI.ObjectiveFunction` when",
" using `MOI.Bridges.Objective.SlackBridge`.")
end
constraint = MOIU.add_scalar_constraint(model, f, set)
constraint = MOIU.normalize_and_add_constraint(model, f, set)
MOI.set(model, MOI.ObjectiveFunction{MOI.SingleVariable}(), fslack)
return SlackBridge{T, F, G}(slack, constraint)
end
Expand All @@ -54,6 +54,25 @@ function concrete_bridge_type(::Type{<:SlackBridge{T}},
return SlackBridge{T, F, G}
end

# Attributes, Bridge acting as a model
function MOI.get(bridge::SlackBridge, ::MOI.NumberOfVariables)
return 1
end
function MOI.get(bridge::SlackBridge, ::MOI.ListOfVariableIndices)
return [bridge.slack]
end
function MOI.get(bridge::SlackBridge{T, F}, ::MOI.NumberOfConstraints{F, S}) where {
T, F, S <: Union{MOI.GreaterThan{T}, MOI.LessThan{T}}}
return bridge.constraint isa MOI.ConstraintIndex{F, S} ? 1 : 0
end
function MOI.get(bridge::SlackBridge{T, F}, ::MOI.ListOfConstraintIndices{F, S}) where {
T, F, S <: Union{MOI.GreaterThan{T}, MOI.LessThan{T}}}
if bridge.constraint isa MOI.ConstraintIndex{F, S}
return [bridge.constraint]
else
return MOI.ConstraintIndex{F, S}[]
end
end

function MOI.delete(model::MOI.ModelLike, bridge::SlackBridge)
MOI.delete(model, bridge.constraint)
Expand Down
20 changes: 19 additions & 1 deletion src/Bridges/bridge_optimizer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ function MOI.get(b::AbstractBridgeOptimizer,
for bridge in values(Constraint.bridges(b))
_remove_bridged(list, bridge, attr)
end
for bridge in values(Objective.bridges(b))
_remove_bridged(list, bridge, attr)
end
return list
end
function MOI.get(b::AbstractBridgeOptimizer, attr::MOI.NumberOfVariables)
Expand All @@ -422,6 +425,9 @@ function MOI.get(b::AbstractBridgeOptimizer, attr::MOI.NumberOfVariables)
for bridge in values(Constraint.bridges(b))
s -= MOI.get(bridge, attr)
end
for bridge in values(Objective.bridges(b))
s -= MOI.get(bridge, attr)
end
return s
end

Expand All @@ -446,6 +452,9 @@ function MOI.get(b::AbstractBridgeOptimizer,
for bridge in values(Constraint.bridges(b))
s -= MOI.get(bridge, attr)
end
for bridge in values(Objective.bridges(b))
s -= MOI.get(bridge, attr)
end
return s
end
function MOI.get(b::AbstractBridgeOptimizer, attr::MOI.ListOfConstraints)
Expand Down Expand Up @@ -569,6 +578,7 @@ function MOI.get(b::AbstractBridgeOptimizer,
end
function MOI.set(b::AbstractBridgeOptimizer, attr::MOI.ObjectiveSense,
value::MOI.OptimizationSense)
MOI.set(b.model, attr, value)
if is_objective_bridged(b)
if value == MOI.FEASIBILITY_SENSE
_delete_objective_bridges(b)
Expand All @@ -578,7 +588,6 @@ function MOI.set(b::AbstractBridgeOptimizer, attr::MOI.ObjectiveSense,
end
end
end
MOI.set(b.model, attr, value)
end
function _bridge_objective(b, BridgeType, func)
bridge = Objective.bridge_objective(BridgeType, b, func)
Expand All @@ -588,7 +597,16 @@ function MOI.set(b::AbstractBridgeOptimizer,
attr::MOI.ObjectiveFunction,
func::MOI.AbstractScalarFunction)
if is_objective_bridged(b)
# Clear objective function by setting sense to `MOI.FEASIBILITY_SENSE`
# first. This is needed if the objective function of `b.model` is
# `MOI.SingleVariable(slack)` where `slack` is the slack variable
# created by `Objective.SlackBridge`.
sense = MOI.get(b.model, MOI.ObjectiveSense())
MOI.set(b.model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE)
_delete_objective_bridges(b)
if sense != MOI.FEASIBILITY_SENSE
MOI.set(b.model, MOI.ObjectiveSense(), sense)
end
end
if Variable.has_bridges(Variable.bridges(b))
if func isa MOI.SingleVariable
Expand Down
9 changes: 7 additions & 2 deletions src/Utilities/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,12 @@ end
# Objective
MOI.get(model::AbstractModel, ::MOI.ObjectiveSense) = model.sense
MOI.supports(model::AbstractModel, ::MOI.ObjectiveSense) = true
function MOI.set(model::AbstractModel, ::MOI.ObjectiveSense, sense::MOI.OptimizationSense)
function MOI.set(model::AbstractModel{T}, ::MOI.ObjectiveSense,
sense::MOI.OptimizationSense) where T
if sense == MOI.FEASIBILITY_SENSE
model.objectiveset = false
model.objective = zero(MOI.ScalarAffineFunction{T})
end
model.senseset = true
model.sense = sense
end
Expand Down Expand Up @@ -922,7 +927,7 @@ macro model(model_name, ss, sst, vs, vst, sf, sft, vf, vft)
model.senseset = false
model.sense = $MOI.FEASIBILITY_SENSE
model.objectiveset = false
model.objective = $SAF{T}(MOI.ScalarAffineTerm{T}[], zero(T))
model.objective = zero($MOI.ScalarAffineFunction{T})
model.num_variables_created = 0
model.variable_indices = nothing
model.single_variable_mask = UInt8[]
Expand Down
14 changes: 9 additions & 5 deletions test/Bridges/Objective/slack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,24 @@ end
MOIU.set_mock_optimize!(mock,
(mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
MOI.OPTIMAL,
(MOI.FEASIBLE_POINT, [1.0, 2.0])
(MOI.FEASIBLE_POINT, [1.0, 2.0, 5.0])
),
(mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
MOI.OPTIMAL,
(MOI.FEASIBLE_POINT, [1.0, 2.0])
(MOI.FEASIBLE_POINT, [1.0, 2.0, 7.0])
),
(mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
MOI.OPTIMAL,
(MOI.FEASIBLE_POINT, [1.0, 2.0])
(MOI.FEASIBLE_POINT, [1.0, 2.0, 2.0])
),
(mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
MOI.OPTIMAL,
(MOI.FEASIBLE_POINT, [1.0, 2.0])
(MOI.FEASIBLE_POINT, [1.0, 2.0, 7.0])
)
)
MOIT.solve_qp_edge_cases(mock, config)
MOIT.solve_qp_edge_cases(bridged_mock, config)
test_delete_objective(bridged_mock, 2, (
(MOI.ScalarQuadraticFunction{Float64}, MOI.GreaterThan{Float64}, 0),
(MOI.ScalarQuadraticFunction{Float64}, MOI.LessThan{Float64}, 0),
))
end
11 changes: 6 additions & 5 deletions test/Bridges/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,22 +112,23 @@ function test_delete_bridged_variables(
end
function test_delete_objective(
m::MOIB.AbstractBridgeOptimizer, nvars::Int,
nocs::Tuple; used_bridges = 1)
list_num_constraints::Tuple; used_bridges = 1)
warn_incomplete_list_num_constraints(typeof(MOIB.Objective.root_bridge(MOIB.Objective.bridges(m))), list_num_constraints)
function num_bridges()
return length(MOIB.Objective.bridges(m))
end
start_num_bridges = num_bridges()
@test MOI.get(m, MOI.NumberOfVariables()) == nvars
@test length(MOI.get(m, MOI.ListOfVariableIndices())) == nvars
for noc in nocs
test_noc(m, noc...)
for num_constraints in list_num_constraints
test_num_constraints(m, num_constraints...)
end
MOI.set(m, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE)
@test MOI.get(m, MOI.ObjectiveSense()) == MOI.FEASIBILITY_SENSE
@test num_bridges() == start_num_bridges - used_bridges
@test MOI.get(m, MOI.NumberOfVariables()) == nvars
@test length(MOI.get(m, MOI.ListOfVariableIndices())) == nvars
for noc in nocs
test_noc(m, noc...)
for num_constraints in list_num_constraints
test_num_constraints(m, num_constraints...)
end
end

0 comments on commit ccba971

Please sign in to comment.