diff --git a/REQUIRE b/REQUIRE index b62a93944c4..7ab83d8feb6 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,5 +1,5 @@ julia 0.7 -MathOptInterface 0.6.3 0.7 +MathOptInterface 0.7 0.8 ForwardDiff 0.5 0.11 Calculus DataStructures diff --git a/docs/src/quickstart.md b/docs/src/quickstart.md index 35500114ba5..7c4986fdf88 100644 --- a/docs/src/quickstart.md +++ b/docs/src/quickstart.md @@ -99,7 +99,7 @@ DocTestSetup = quote # Now we load in the solution. Using a caching optimizer removes the need to # load a solver such as GLPK for building the documentation. mock = JuMP.backend(model).optimizer.model - MOI.set(mock, MOI.TerminationStatus(), MOI.Success) + MOI.set(mock, MOI.TerminationStatus(), MOI.Optimal) MOI.set(mock, MOI.PrimalStatus(), MOI.FeasiblePoint) MOI.set(mock, MOI.DualStatus(), MOI.FeasiblePoint) MOI.set(mock, MOI.ResultCount(), 1) @@ -120,31 +120,28 @@ to a setting such as a time limit. We can ask the solver why it stopped using the `JuMP.termination_status` function: ```jldoctest quickstart_example julia> JuMP.termination_status(model) -Success::TerminationStatusCode = 1 +Optimal::TerminationStatusCode = 1 ``` -In this case, `GLPK` returned `Success`. This does *not* mean that it has found -the optimal solution. Instead, it indicates that GLPK has finished running and -did not encounter any errors or user-provided termination limits. +In this case, `GLPK` returned `Optimal`, this mean that it has found the optimal +solution. ```@meta DocTestSetup = nothing ``` -To understand the reason for termination in more detail, we need to query -`JuMP.primalstatus`: +As the solver found an optimal solution, we expect the solution returned to be +a primal-dual pair of feasible solutions with zero duality gap. +We can verify the primal and dual status as follows to confirm this: ```jldoctest quickstart_example julia> JuMP.primal_status(model) FeasiblePoint::ResultStatusCode = 1 -``` -This indicates that GLPK has found a `FeasiblePoint` to the primal problem. -Coupled with the `Success` from `JuMP.termination_status`, we can infer that GLPK -has indeed found the optimal solution. We can also query `JuMP.dual_status`: -```jldoctest quickstart_example + julia> JuMP.dual_status(model) FeasiblePoint::ResultStatusCode = 1 ``` -Like the `primal_status`, GLPK indicates that it has found a `FeasiblePoint` to -the dual problem. +Note that the primal and dual status only inform that the primal and dual +solutions are feasible and it is only because we verified that the termination +status is `Optimal` that we can conclude that they form an optimal solution. Finally, we can query the result of the optimization. First, we can query the objective value: diff --git a/examples/cannery.jl b/examples/cannery.jl index c6dbb40c583..3091bdd1637 100644 --- a/examples/cannery.jl +++ b/examples/cannery.jl @@ -53,7 +53,7 @@ function solveCannery(plants, markets, capacity, demand, distance, freight) term_status = JuMP.termination_status(cannery) primal_status = JuMP.primal_status(cannery) - is_optimal = term_status == MOI.Success && primal_status == MOI.FeasiblePoint + is_optimal = term_status == MOI.Optimal PrintSolution(is_optimal, plants, markets, ship) return is_optimal diff --git a/examples/diet.jl b/examples/diet.jl index f4ee81c0706..e35af475442 100644 --- a/examples/diet.jl +++ b/examples/diet.jl @@ -74,7 +74,7 @@ function SolveDiet() JuMP.optimize!(m) term_status = JuMP.termination_status(m) primal_status = JuMP.primal_status(m) - is_optimal = term_status == MOI.Success && primal_status == MOI.FeasiblePoint + is_optimal = term_status == MOI.Optimal PrintSolution(is_optimal, foods, buy) @@ -85,7 +85,7 @@ function SolveDiet() JuMP.optimize!(m) term_status = JuMP.termination_status(m) primal_status = JuMP.primal_status(m) - is_optimal = term_status == MOI.Success && primal_status == MOI.FeasiblePoint + is_optimal = term_status == MOI.Optimal PrintSolution(is_optimal, foods, buy) end diff --git a/examples/multi.jl b/examples/multi.jl index ee15ffeb592..7de4fea9d03 100644 --- a/examples/multi.jl +++ b/examples/multi.jl @@ -105,6 +105,6 @@ JuMP.optimize!(multi) term_status = JuMP.termination_status(multi) primal_status = JuMP.primal_status(multi) -is_optimal = term_status == MOI.Success && primal_status == MOI.FeasiblePoint +is_optimal = term_status == MOI.Optimal PrintSolution(is_optimal, Trans, orig, dest, prod) diff --git a/examples/prod.jl b/examples/prod.jl index 4d73818120e..31df1f44025 100644 --- a/examples/prod.jl +++ b/examples/prod.jl @@ -253,6 +253,6 @@ JuMP.optimize!(prod) term_status = JuMP.termination_status(prod) primal_status = JuMP.primal_status(prod) -is_optimal = status == MOI.Success && primal_status == MOI.FeasiblePoint +is_optimal = status == MOI.Optimal PrintSolution(is_optimal, Crews, Hire, Layoff) diff --git a/examples/steelT3.jl b/examples/steelT3.jl index 3002241cc95..eb61c418226 100644 --- a/examples/steelT3.jl +++ b/examples/steelT3.jl @@ -123,6 +123,6 @@ JuMP.optimize!(Prod) term_status = JuMP.termination_status(Prod) primal_status = JuMP.primal_status(Prod) -is_optimal = status == MOI.Success && primal_status == MOI.FeasiblePoint +is_optimal = status == MOI.Optimal PrintSolution(is_optimal, area, Make, Inv, Sell, prod, T) diff --git a/examples/sudoku.jl b/examples/sudoku.jl index 93646a4eba1..99a4dea755e 100644 --- a/examples/sudoku.jl +++ b/examples/sudoku.jl @@ -65,7 +65,7 @@ function SolveModel(initgrid) term_status = JuMP.termination_status(m) primal_status = JuMP.primal_status(m) - is_optimal = term_status == MOI.Success && primal_status == MOI.FeasiblePoint + is_optimal = term_status == MOI.Optimal # Check solution if is_optimal diff --git a/examples/transp.jl b/examples/transp.jl index 00e48d71ac3..13fb3888015 100644 --- a/examples/transp.jl +++ b/examples/transp.jl @@ -48,7 +48,7 @@ JuMP.optimize!(m) term_status = JuMP.termination_status(m) primal_status = JuMP.primal_status(m) -is_optimal = term_status == MOI.Success && primal_status == MOI.FeasiblePoint +is_optimal = term_status == MOI.Optimal if is_optimal @printf("Optimal!\n") diff --git a/examples/urbanplan.jl b/examples/urbanplan.jl index ce3221ef7ca..9058ba5733c 100644 --- a/examples/urbanplan.jl +++ b/examples/urbanplan.jl @@ -70,7 +70,7 @@ function SolveUrban() term_status = JuMP.termination_status(m) primal_status = JuMP.primal_status(m) - is_optimal = term_status == MOI.Success && primal_status == MOI.FeasiblePoint + is_optimal = term_status == MOI.Optimal if ! is_optimal error("The solver did not find an optimal solution.") diff --git a/test/constraint.jl b/test/constraint.jl index 9fbda0a2f3c..e67d98fa27d 100644 --- a/test/constraint.jl +++ b/test/constraint.jl @@ -339,7 +339,7 @@ function test_shadow_price(model_string, constraint_dual, constraint_shadow) eval_objective_value=false, eval_variable_constraint_dual=false)) mock_optimizer = JuMP.backend(model).optimizer.model - MOI.set(mock_optimizer, MOI.TerminationStatus(), MOI.Success) + MOI.set(mock_optimizer, MOI.TerminationStatus(), MOI.Optimal) MOI.set(mock_optimizer, MOI.DualStatus(), MOI.FeasiblePoint) JuMP.optimize!(model) diff --git a/test/generate_and_solve.jl b/test/generate_and_solve.jl index af1896e02d6..23d42c703b5 100644 --- a/test/generate_and_solve.jl +++ b/test/generate_and_solve.jl @@ -44,7 +44,7 @@ eval_objective_value=false)) mockoptimizer = JuMP.backend(m).optimizer.model - MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Success) + MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Optimal) MOI.set(mockoptimizer, MOI.ObjectiveValue(), -1.0) MOI.set(mockoptimizer, MOI.ResultCount(), 1) MOI.set(mockoptimizer, MOI.PrimalStatus(), MOI.FeasiblePoint) @@ -58,7 +58,7 @@ #@test JuMP.isattached(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.Optimal @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.value(x) == 1.0 @@ -82,7 +82,7 @@ @objective(m, Min, -x) c = @constraint(m, x + y <= 1) - MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Success) + MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Optimal) MOI.set(mockoptimizer, MOI.ObjectiveValue(), -1.0) MOI.set(mockoptimizer, MOI.ResultCount(), 1) MOI.set(mockoptimizer, MOI.PrimalStatus(), MOI.FeasiblePoint) @@ -98,7 +98,7 @@ #@test JuMP.isattached(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.Optimal @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.value(x) == 1.0 @@ -143,7 +143,7 @@ MOIU.attachoptimizer!(m) mockoptimizer = JuMP.backend(m).optimizer.model - MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Success) + MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Optimal) MOI.set(mockoptimizer, MOI.ObjectiveValue(), 1.0) MOI.set(mockoptimizer, MOI.ResultCount(), 1) MOI.set(mockoptimizer, MOI.PrimalStatus(), MOI.FeasiblePoint) @@ -156,7 +156,7 @@ #@test JuMP.isattached(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.Optimal @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.value(x) == 1.0 @@ -193,7 +193,7 @@ eval_objective_value=false)) mockoptimizer = JuMP.backend(m).optimizer.model - MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Success) + MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Optimal) MOI.set(mockoptimizer, MOI.ObjectiveValue(), -1.0) MOI.set(mockoptimizer, MOI.ResultCount(), 1) MOI.set(mockoptimizer, MOI.PrimalStatus(), MOI.FeasiblePoint) @@ -207,7 +207,7 @@ #@test JuMP.isattached(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.Optimal @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.value(x) == 1.0 @@ -253,7 +253,7 @@ MOIU.resetoptimizer!(m, mockoptimizer) MOIU.attachoptimizer!(m) - MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Success) + MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Optimal) MOI.set(mockoptimizer, MOI.ResultCount(), 1) MOI.set(mockoptimizer, MOI.PrimalStatus(), MOI.FeasiblePoint) MOI.set(mockoptimizer, MOI.DualStatus(), MOI.FeasiblePoint) @@ -268,7 +268,7 @@ #@test JuMP.isattached(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.Optimal @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.value(x) == 1.0 @@ -314,7 +314,7 @@ MOIU.resetoptimizer!(m, mockoptimizer) MOIU.attachoptimizer!(m) - MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Success) + MOI.set(mockoptimizer, MOI.TerminationStatus(), MOI.Optimal) MOI.set(mockoptimizer, MOI.ResultCount(), 1) MOI.set(mockoptimizer, MOI.PrimalStatus(), MOI.FeasiblePoint) MOI.set(mockoptimizer, MOI.DualStatus(), MOI.FeasiblePoint) @@ -330,7 +330,7 @@ JuMP.optimize!(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.Optimal @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.has_values(m) diff --git a/test/nlp_solver.jl b/test/nlp_solver.jl index 8bc2acfcbab..8b880568fd8 100644 --- a/test/nlp_solver.jl +++ b/test/nlp_solver.jl @@ -47,7 +47,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.value.(x) ≈ [1.000000, 4.742999, 3.821150, 1.379408] atol=1e-3 @@ -78,7 +78,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.value.(x) ≈ [1.000000, 4.742999, 3.821150, 1.379408] atol=1e-3 @@ -126,7 +126,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ 5326.851310161077 atol=1e-5 @@ -144,8 +144,8 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - # Ipopt returns AlmostSuccess and NearlyFeasiblePoint on this instance. - # @test JuMP.termination_status(m) == MOI.Success + # Ipopt returns AlmostLocallySolved and NearlyFeasiblePoint on this instance. + # @test JuMP.termination_status(m) == MOI.LocallySolved # @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ -45.77846971 atol=1e-5 @@ -167,7 +167,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ -47.76109026 atol=1e-5 @@ -188,7 +188,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ -47.76109026 atol=1e-5 @@ -223,7 +223,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ -1768.80696 atol=1e-3 @@ -269,7 +269,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint # This test occasionally fails, for unknown reasons. @@ -337,7 +337,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.value.(x[1:4]) ≈ [8.0, 49.0, 3.0, 1.0] atol=1e-4 @@ -354,7 +354,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ u atol=1e-6 @@ -362,7 +362,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ l atol=1e-6 end @@ -377,7 +377,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ u atol=1e-6 @@ -385,7 +385,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ l atol=1e-6 end @@ -403,7 +403,7 @@ const MOI = MathOptInterface function test_result() @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @@ -455,7 +455,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ -1-4/sqrt(3) atol=1e-6 @test JuMP.value(x) + JuMP.value(y) ≈ -1/3 atol=1e-3 @@ -470,7 +470,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ -1-4/sqrt(3) atol=1e-6 @test JuMP.value(x) + JuMP.value(y) ≈ -1/3 atol=1e-3 @@ -484,7 +484,7 @@ const MOI = MathOptInterface JuMP.optimize!(m) @test JuMP.has_values(m) - @test JuMP.termination_status(m) == MOI.Success + @test JuMP.termination_status(m) == MOI.LocallySolved @test JuMP.primal_status(m) == MOI.FeasiblePoint @test JuMP.objective_value(m) ≈ sqrt(1/2) atol=1e-6 @test JuMP.value.(x) ≈ [sqrt(1/2), 0] atol=1e-6