What's the recommended package for constrained non-linear optimization in python ?
The specific problem I'm trying to solve is this:
I have an unknown X
(Nx1), I have M
(Nx1) u
vectors and M
(NxN) s
matrices.
max [5th percentile of (ui_T*X), i in 1 to M]
st
0<=X<=1 and
[95th percentile of (X_T*si*X), i in 1 to M]<= constant
When I started out the problem I only had one point estimate for u
and s
and I was able to solve the problem above with cvxpy
.
I realized that instead of one estimate for u
and s
, I had the entire distribution of values so I wanted to change my objective function so that I could use the entire distribution. The problem description above is my attempt to include that information in a meaningful way.
cvxpy
cannot be used to solve this, I've tried scipy.optimize.anneal
, but I can't seem to set bounds on the unknown values. I've looked at pulp
too but it doesnt allow nonlinear constraints.
While the
SLSQP
algorithm inscipy.optimize.minimize
is good, it has a bunch of limitations. The first of which is it's aQP
solver, so it works will for equations that fit well into a quadratic programming paradigm. But what happens if you have functional constraints? Also,scipy.optimize.minimize
is not a global optimizer, so you often need to start very close to the final results.There is a constrained nonlinear optimization package (called
mystic
) that has been around for nearly as long asscipy.optimize
itself -- I'd suggest it as the go-to for handling any general constrained nonlinear optimization.For example, your problem, if I understand your pseudo-code, looks something like this:
So, to handle your problem in
mystic
, you just need to specify the bounds and the constraints.The result looks something like this:
mystic
is very flexible, and can handle any type of constraints (e.g. equalities, inequalities) including symbolic and functional constraints. I specified the constraints as "penalties" above, which is the traditional way, in that they apply a penalty to the objective when the constraint is violated.mystic
also provides nonlinear kernel transformations, which constrain solution space by reducing the space of valid solutions (i.e. by a spatial mapping or kernel transformation).As an example, here's
mystic
solving a problem that breaks a lot of QP solvers, since the constraints are not in the form of a constraints matrix. It's optimizing the design of a pressure vessel.Find this, and roughly 100 examples like it, here: https://github.com/uqfoundation/mystic.
I'm the author, so I am slightly biased. However, the bias is very slight.
mystic
is both mature and well-supported, and is unparalleled in capacity to solve hard constrained nonlinear optimization problems.As others have commented as well, the SciPy minimize package is a good place to start. I've included an example below (Hock Schittkowski #71 benchmark) that includes an objective function, equality constraint, and inequality constraint.
There is also a more comprehensive discussion thread on nonlinear programming solvers for Python if SLSQP can't solve your problem. My course material on Engineering Design Optimization is available if you need additional information on the solver methods.
Typically for fitting you can use
scipy.optimize
functions, orlmfit
which simply extends the scipy.optimize package to make it easier to pass things like bounds. Personally, I like usingkmpfit
, part of the kapteyn library and is based on the C implementation of MPFIT.scipy.optimize.minimize()
is probably the most easy to obtain and is commonly used.scipy
has a spectacular package for constrained non-linear optimization.You can get started by reading the
optimize
doc, but here's an example with SLSQP: