Penopt.jl is a wrapper for the Penopt Optimizer.
It has two components:
- a thin wrapper around the complete C API
- an interface to MathOptInterface
The C API can be accessed via Penopt.penbmi functions, where the names and
arguments are identical to the C API. See the /tests folder for inspiration.
This wrapper is maintained by the JuMP community and is not officially supported by Penopt.
Penopt.jl is licensed under the MIT License.
The underlying solver is a closed-source commercial product for which you must purchase a license.
Warning
Only Linux is supported at the moment. Help is welcome to add support for Mac OS and Windows.
You can install Penopt.jl through the
Julia package manager:
] add https://github.com/jump-dev/Penopt.jl.gitThis downloads and builds PENSDP, the free
SDP-only solver of the PENOPT family, which is used by Penopt.pensdp and by
Penopt.SDP.Optimizer.
Bilinear matrix inequalities and quadratic objectives require PENBMI, which is a
commercial product for which you must
purchase a license. Set the PENOPT_LIBPENBMI
environment variable to the path of the PENBMI library and re-run the build:
ENV["PENOPT_LIBPENBMI"] = "/path/to/PENBMI2.1/lib/libpenbmi.a"
import Pkg
Pkg.build("Penopt")then restart Julia.
PENOPT distributes PENBMI as a static library, which Julia cannot call into
directly. The build detects this and links a shared library from it in
deps/usr/lib; a path pointing to a shared library is used as is. To change the
location of the library, update PENOPT_LIBPENBMI, re-run
Pkg.build("Penopt") and restart Julia.
Whether PENBMI is available is given by Penopt.has_penbmi().
The nonlinear PENNON backend is enabled by setting PENOPT_LIBPENNON to a
PENNON shared library or static archive, re-running Pkg.build("Penopt"), and
restarting Julia, as for PENBMI. Availability is reported by
Penopt.has_pennon().
Penopt.NON.Optimizer accepts nonlinear scalar objectives and constraints,
and accepts nonlinear semidefinite constraints as an
MOI.VectorNonlinearFunction in an
MOI.PositiveSemidefiniteConeTriangle. Derivatives are evaluated with MOI's
sparse reverse-mode automatic differentiation.
You can test the installation with using Pkg; Pkg.test("Penopt") in a Julia
session.
Pick the solver explicitly: Penopt.SDP.Optimizer solves semidefinite programs
with PENSDP, Penopt.BMI.Optimizer solves bilinear matrix inequalities and
quadratic objectives with PENBMI, and Penopt.NON.Optimizer solves general
nonlinear semidefinite programs with PENNON.
using JuMP, Penopt
model = Model(Penopt.SDP.Optimizer)
set_attribute(model, "PBM_MAX_ITER", 100)
set_attribute(model, "TR_MODE", 1)Penopt.SDP.Optimizer supports a linear objective and linear matrix
inequalities; a convex quadratic objective is reformulated into an additional
matrix constraint by the JuMP bridges. Anything PENBMI-specific, that is, a
quadratic objective or a matrix inequality with bilinear entries, is solved
natively by Penopt.BMI.Optimizer:
model = Model(Penopt.BMI.Optimizer)For general nonlinear objectives, scalar constraints, and matrix inequalities, use the PENNON backend:
model = Model(Penopt.NON.Optimizer)Enable the PENNON library as described in PENNON above. MOI bridges automatically convert affine and quadratic functions to nonlinear functions, so JuMP expressions do not need explicit nonlinear conversion.
See the Penbmi Documentation for a list and description of allowable parameters.
You can get and set Penopt-specific attributes via JuMP as follows:
@show MOI.get(model, Penopt.NumberOfOuterIterations())
@show MOI.get(model, Penopt.NumberOfNewtonSteps())
@show MOI.get(model, Penopt.NumberOfLinesearchSteps())