Skip to content

Commit

Permalink
minor edits to solvers.md and solutions.md
Browse files Browse the repository at this point in the history
  • Loading branch information
mlubin committed Jan 21, 2019
1 parent bff0916 commit 3d46ca9
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 34 deletions.
47 changes: 26 additions & 21 deletions docs/src/solutions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
CurrentModule = JuMP
DocTestSetup = quote
using JuMP
const MOI = JuMP.MathOptInterface
end
```

Expand All @@ -11,15 +10,16 @@ end
So far we have seen all the elements and constructs related to writing a JuMP
optimization model. In this section we reach the point of what to do with a
solved problem. Suppose your model is named `model`. Right after the call to
`JuMP.optimize!(model)` (which might take a while) it's possible to ask JuMP
questions about the finished optimization step. Typical questions include:
- Why has the optimization process stopped?
`optimize!(model)` it's natural to ask JuMP questions about the finished
optimization step. Typical questions include:
- Why has the optimization process stopped? Did it hit the time limit or run
into numerical issues?
- Do I have a solution to my problem?
- Is it optimal?
- Do I have a dual solution?

JuMP follows closely the concepts defined in [MathOptInterface (MOI)](https://github.com/JuliaOpt/MathOptInterface.jl)
to answer user questions about a finished call to `JuMP.optimize!(model)`. There
to answer user questions about a finished call to `optimize!(model)`. There
are three main steps in querying a solution:

First, we can query the [`termination_status`](@ref) which will tell us why the
Expand All @@ -29,12 +29,12 @@ user-provided limit such as a time limit was encountered. For more information,
see the [Termination statuses](@ref) section below.

Second, we can query the [`primal_status`](@ref) and [`dual_status`](@ref),
which will tell us what kind of result do we have for our primal and dual
which will tell us what kind of result we have for our primal and dual
solution. This might be an optimal primal-dual pair, a primal solution without a
corresponding dual solution, or a certificate of primal or dual infeasibility.
For more information, see the [Solution statuses](@ref) section below.

Third, we can query [`JuMP.value`](@ref) and [`JuMP.dual`](@ref) to obtain the
Third, we can query [`value`](@ref) and [`dual`](@ref) to obtain the
primal and dual values of the optimization variables and constraints (if there
are values to be queried).

Expand All @@ -54,42 +54,43 @@ MOI.TerminationStatusCode
## Solution statuses

These statuses indicate what kind of result is available to be queried
with [`JuMP.value`](@ref) and [`JuMP.dual`](@ref). Its possible that no result
with [`value`](@ref) and [`dual`](@ref). Its possible that no result
is available to be queried.

We can obtain these statuses by calling [`JuMP.primal_status`](@ref) for the
primal status, and [`JuMP.dual_status`](@ref) for the dual status. Both will
We can obtain these statuses by calling [`primal_status`](@ref) for the
primal status, and [`dual_status`](@ref) for the dual status. Both will
return a `MOI.ResultStatusCode` `enum`.

```@docs
MOI.ResultStatusCode
```

Common status situations are described in the [`MathOptInterface` docs](http://www.juliaopt.org/MathOptInterface.jl/v0.8/apimanual/#Common-status-situations-1).
Common status situations are described in the
[MOI docs](http://www.juliaopt.org/MathOptInterface.jl/v0.8/apimanual/#Common-status-situations-1).

## Obtaining solutions

Provided the primal status is not (`MOI.NO_SOLUTION`), the primal solution can
be obtained by calling [`JuMP.value`](@ref). For the dual solution, the function
is [`JuMP.dual`](@ref). One fast way to check if the status is not
`MOI.NO_SOLUTION` is via [`JuMP.has_values`](@ref) for the primal status and
[`JuMP.has_duals`](@ref) for the dual solution.
be obtained by calling [`value`](@ref). For the dual solution, the function
is [`dual`](@ref). An equivalent way to check if the status is not
`MOI.NO_SOLUTION` is by calling [`has_values`](@ref) for the primal status and
[`has_duals`](@ref) for the dual solution.

It is important to note that if `has_values` returns false, calls to
[`JuMP.value`](@ref) and [`JuMP.dual`](@ref) might throw an error or return
It is important to note that if `has_values` or `has_duals` return false,
calls to [`value`](@ref) and [`dual`](@ref) might throw an error or return
arbitrary values.

The container type (e.g., scalar, vector, or matrix) of the returned solution
(primal or dual) depends on the type of the variable or constraint. See
[`AbstractShape`](@ref) and [`dual_shape`](@ref) for details.

To call [`JuMP.value`](@ref) or [`JuMP.dual`](@ref) on container of
To call [`value`](@ref) or [`dual`](@ref) on container of
[`VariableRef`](@ref) or [`ConstraintRef`](@ref), use the broadcast syntax,
e.g., `JuMP.value.(x)`.
e.g., `value.(x)`.

The objective value of a solved problem can be obtained via
[`JuMP.objective_value`](@ref). The best known bound on the optimal objective
value can be obtained via [`JuMP.objective_bound`](@ref).
[`objective_value`](@ref). The best known bound on the optimal objective
value can be obtained via [`objective_bound`](@ref).

A recommended workflow for solving a model and querying the solution is the
following:
Expand All @@ -111,6 +112,10 @@ else
end
```

```@meta
# TODO: How to accurately measure the solve time.
```

## Reference

```@docs
Expand Down
23 changes: 10 additions & 13 deletions docs/src/solvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ Interacting with solvers
========================

A JuMP model keeps a [MathOptInterface (MOI)](https://github.com/JuliaOpt/MathOptInterface.jl)
*backend* of type `MOI.ModelLike` internally that stores the optimization
*backend* of type `MOI.ModelLike` that stores the optimization
problem and acts as the optimization solver. We call it an MOI *backend* and not
optimizer as it can also be a wrapper around an optimization file format such as
MPS that writes the JuMP model in a file. From JuMP, the MathOptInterface
backend can be accessed using the [`JuMP.backend`](@ref) function. JuMP can be
viewed as a lightweight user-friendly layer on top of the MOI backend:
MPS that writes the JuMP model in a file. From JuMP, the MOI
backend can be accessed using the [`backend`](@ref) function. JuMP can be
viewed as a lightweight user-friendly layer on top of the MOI backend, in the
sense that:

* JuMP does not maintain any copy of the model outside this MOI backend.
* JuMP variable (resp. constraint) references are simple structures containing
Expand All @@ -27,10 +28,11 @@ copied at once before solve. Moreover it seems to require all solvers to
implement all possible reformulations independently which seems both very
ambitious and might generate a lot of duplicated code.

These apparent limitations are in fact addressed at the MOI level in a manner
These apparent limitations are addressed at level of MOI in a manner
that is completely transparent to JuMP. While the MOI API may seem very
demanding, it allows MOI models to be a succession of lightweight MOI layers
that fill the gap between JuMP requirements and the solver capabilities.
that fill the gap between JuMP requirements and the solver capabilities. The
remainder of this section describes how JuMP interacts with the MOI backend.

JuMP models can be created in three different modes: `AUTOMATIC`, `MANUAL` and
`DIRECT`.
Expand All @@ -54,7 +56,7 @@ the optimizer:
MOI but new ones can be defined and added to the `LazyBridgeOptimizer` used by
JuMP.

See the [MOI documentation](http://www.juliaopt.org/MathOptInterface.jl/stable/)
See the [MOI documentation](http://www.juliaopt.org/MathOptInterface.jl/v0.8.1/)
for more details on these two MOI layers.

To attach an optimizer to a JuMP model, JuMP needs to create a new empty
Expand All @@ -66,7 +68,7 @@ with_optimizer
```

The factory can be provided either at model construction time or at
[`JuMP.optimize!`](@ref) time:
[`optimize!`](@ref) time:
```@docs
JuMP.optimize!
```
Expand All @@ -90,8 +92,3 @@ JuMP.direct_model
```@docs
JuMP.backend
```


TODO: How to set parameters (solver
specific and generic). Status codes. Accessing the result.
How to accurately measure the solve time.

0 comments on commit 3d46ca9

Please sign in to comment.