Non-Linear Programming by Quadratic Lagrangian (NLPQL) for Python
nlpql solves the smooth nonlinear programming problem
min f(x)
g_j(x) = 0 , j = 1, ..., me
g_j(x) >= 0 , j = me+1, ..., m
xl <= x <= xu
by a sequential quadratic programming method. A quadratic subproblem is formulated from a quadratic approximation of the Lagrangian and a linearization of the constraints, and the steplength is determined by a line search with respect to an augmented Lagrangian merit function. Data fitting, min-max and multicriteria problems are transformed into programs of this form and solved by the same algorithm.
| code | purpose |
|---|---|
NLPQLP |
distributed and non-monotone line search, internal restarts |
NLPQL |
the original SQP method |
NLPQLY |
easy-to-use, all derivatives approximated internally |
NLPQLB |
active set strategy for a very large number of constraints |
NLPQLG |
successive restarts for a stepwise improvement of local minima |
NLPQLF |
model functions evaluable only on a convex subset |
Every code of this group transforms its problem into a nonlinear
program of the form above and solves it with NLPQLP.
| code | purpose |
|---|---|
NLPLSQ |
constrained nonlinear least squares |
NLPLSX |
least squares with a very large number of terms |
NLPL1 |
sum of absolute values |
NLPINF |
maximum norm data fitting |
NLPMMX |
min-max optimization |
NLPJOB |
multicriteria optimization, sixteen scalar transformations |
| code | purpose |
|---|---|
QL |
convex quadratic programming, solves the subproblem of every SQP step |
Rosenbrock's post office problem, test problem TP37 of Hock and Schittkowski:
import numpy as np
from nlpql import minimize
res = minimize(
fun=lambda x: -x[0] * x[1] * x[2],
x0=[10.0, 10.0, 10.0],
jac=lambda x: np.array([-x[1] * x[2], -x[0] * x[2], -x[0] * x[1]]),
bounds=[(0.0, 42.0)] * 3,
constraints={
"type": "ineq",
"fun": lambda x: np.array([
x[0] + 2 * x[1] + 2 * x[2],
72 - x[0] - 2 * x[1] - 2 * x[2],
]),
"jac": lambda x: np.array([[1.0, 2.0, 2.0], [-1.0, -2.0, -2.0]]),
},
)
print(res.x) # [24. 12. 12.]
print(res.fun) # -3456.0Problems with a very large number of constraints are handled by the active set code, which only needs the gradients of a working set:
m = 200_000
y = np.arange(m) / (m - 1.0)
res = minimize(
fun=lambda x: float(np.sum(np.exp(x))),
x0=[1.0, 0.5, 0.0],
method="NLPQLB",
jac=np.exp,
bounds=[(-100.0, 100.0)] * 3,
constraints={
"type": "ineq",
"fun": lambda x: x[0] + x[1] * y + x[2] * y**2 - 1.0 / (1.0 + y**2),
"jac": lambda x: np.column_stack([np.ones_like(y), y, y**2]),
},
options={"mw": 420, "acc": 1e-10, "rho": 0.1},
)
print(res.fun) # 4.3011838- upper and lower bounds are handled separately and stay satisfied
- an additional variable prevents inconsistent linearized constraints
- non-monotone line search and automatic restarts make the method very stable for noisy function and derivative values
- objective and constraints may be evaluated simultaneously at several test points of the line search
- initial multipliers and an initial quasi-Newton matrix may be provided
- reverse communication, so the model functions can be supplied by an external simulation
- no
COMMONblocks, noSAVE, no memory allocation, therefore thread-safe and re-entrant - the detailed iteration protocol of the original codes is available
through
options={"iprint": 4}
pip install nlpqlRequires Python 3.10+ and NumPy. No external runtime dependencies. See the full installation guide for uv, poetry and source builds.
- Theory — the mathematics of the implemented algorithms
- Quickstart — runnable examples
- API Reference — functions, options and termination flags
- References — literature citations
The algorithms were developed by Prof. Dr. K. Schittkowski and co-authors. The sources in this repository were written from scratch from the published user's guides and papers; no source code of the original implementations was used. Subroutine and argument names follow the published documentation, so existing calling programs can be adapted easily. Reimplementation from the documentation was explicitly permitted by the copyright holder.
GNU General Public License v3 (GPLv3) — see LICENSE.
