pympcc
A Python solver for Mathematical Programs with Complementarity Constraints (MPCC) using IPOPT via cyipopt, with an optional SciPy backend.
Thirteen reformulation strategies (six canonical + seven NCP variants), certified MPCC multipliers, B-stationarity / SOSC diagnostics, parametric sensitivity, and a
jax.custom_vjp-registered solve for end-to-end differentiability. See strategy selection for help picking one.
Problem form
min f(x)
s.t. g(x) ≤ 0 (inequality constraints)
h(x) = 0 (equality constraints)
G(x) ≥ 0 }
H(x) ≥ 0 } (complementarity)
G(x)ᵀ H(x) = 0 }
Install
Requirements: Python ≥ 3.11. The IPOPT backend also requires a working IPOPT installation.
brew install ipopt # macOS
sudo apt-get install coinor-libipopt-dev # Linux
pip install pympcc # default — pulls cyipopt
pip install "pympcc[scipy]" # also include the SciPy backend
pip install "pympcc[jax]" # solve_jax + JAX-AD derivatives
pip install "pympcc[dev]" # for development
See the documentation for the optional custom IPOPT linear-solver bridge and source builds.
Quickstart
import numpy as np
import pympcc
# min (x0-2)² + (x1-1)² s.t. x0 ≥ 0 ⊥ x1 ≥ 0
problem = pympcc.MPCCProblem(
n=2, n_comp=1,
x0=np.array([0.5, 0.5]),
xl=np.zeros(2),
objective=lambda x: (x[0] - 2)**2 + (x[1] - 1)**2,
gradient=lambda x: np.array([2*(x[0]-2), 2*(x[1]-1)]),
comp_G=lambda x: np.array([x[0]]),
comp_G_jacobian=lambda x: np.array([[1.0, 0.0]]),
comp_H=lambda x: np.array([x[1]]),
comp_H_jacobian=lambda x: np.array([[0.0, 1.0]]),
)
result = pympcc.solve(problem, strategy="scholtes")
print(result.x, result.obj, result.success) # [2. 0.] 1.0 True
Strategies
| Strategy | How it works | Best for |
|---|---|---|
"direct" |
G·H ≤ 0; single solve |
Quick feasibility checks |
"scholtes" |
G·H ≤ ε, drives ε → 0 |
Default — most robust |
"smoothing" |
Fischer-Burmeister φ_ε(G,H) = 0, drives ε → 0 |
Tight complementarity residuals |
"lin_fukushima" |
G·H ≤ ε and G+H ≥ ε; preserves MPCC-MFCQ |
Degenerate problems |
"augmented_lagrangian" |
PHR penalty in objective | Problems where MFCQ fails |
"slack" |
Lifts G, H to slacks; sparse comp rows |
Large-n problems (n ≫ n_comp) |
Highlights
- Certified stationarity —
tnlp_refine=Truere-solves a tightened NLP with the active set fixed and extracts MPCC-clean multipliers; classifies S- / W-stationarity. (docs) - Diagnostics — MPCC-LICQ / MPCC-MFCQ check, B-stationarity by branch enumeration, MPCC-SOSC, multi-merit cross-check, condition numbers, degeneracy report. (docs)
- Parametric sensitivity —
pympcc.sensitivity(result, problem, dgrad_L_dp=..., dc_dp=...)returnsdx*/dpanddλ*/dpfrom a single KKT linear solve. (docs) - Differentiable —
pympcc.solve_jax(parametric, theta, ...)isjax.custom_vjp-registered: differentiate transparently through a converged MPCC. (docs) - Bilevel —
pympcc.bilevel.from_lower_level(...)compilesmin_x F(x,y) s.t. y ∈ argmin_y f(x,y)to an MPCC by emitting lower-level KKT. (docs) - Sparse-friendly — COO-format Jacobians end-to-end; the
slackstrategy keeps the comp block at2·n_compnonzeros regardless ofn. - AMPL
.nlreader —pympcc.frontend.ampl.from_nl(path)for MacMPEC-format inputs. - Multistart and presolve —
pympcc.multistart(...),presolve=True.
Documentation
Full user guide, API reference, and theory primer at pympcc.readthedocs.io.
Testing
uv run pytest tests/ -v
The suite covers all thirteen strategies, all diagnostic modules, the MacMPEC benchmark collection, sensitivity, and solve_jax. The direct strategy tests are marked xfail(strict=False) because LICQ generically fails at MPCC feasible points.
Acknowledgements
pympcc is a thin orchestration layer on top of two excellent upstream projects:
- IPOPT — the interior-point NLP solver that does the actual numerical heavy lifting (Eclipse Public License 2.0, © the COIN-OR Foundation contributors).
- cyipopt — the Python bindings to IPOPT, by the cyipopt maintainers (EPL 2.0).
If you use pympcc in published work, please cite IPOPT alongside it.
References
- Scholtes, S. (2001). Convergence properties of a regularization scheme for mathematical programs with complementarity constraints. SIAM J. Optim. 11(4), 918–936.
- Lin, G.-H., & Fukushima, M. (2003). New relaxation method for mathematical programs with complementarity constraints. J. Optim. Theory Appl. 118(1), 81–116.
- Fischer, A. (1992). A special Newton-type optimization method. Optimization 24(3–4), 269–284.
- Luo, Z.-Q., Pang, J.-S., & Ralph, D. (1996). Mathematical Programs with Equilibrium Constraints. Cambridge University Press.
- Leyffer, S. (2000). MacMPEC — AMPL collection of MPECs. Argonne National Laboratory.
Metadata
Release files for pympcc 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pympcc-1.0.0.tar.gz | 4.7 MB | Without provenance | Details for pympcc-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pympcc-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for pympcc-1.0.0-py3-none-any.whl |
Total release size: 5.0 MB
Release files / pympcc-1.0.0.tar.gz
| Download URL | pympcc-1.0.0.tar.gz |
|---|---|
| Size | 4.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bc0e3495c452215c609930c13938743550ea76b14be766305f37a16d0d3187c7
|
|
BLAKE2b-256 checksum How to use checksums |
6625c1771b07340d6702e6908934b506ffcc6829701630830c6c52bea3297633
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / pympcc-1.0.0-py3-none-any.whl
| Download URL | pympcc-1.0.0-py3-none-any.whl |
|---|---|
| Size | 307.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73a42bb8bbf67a2b284f8766d5c0534a5c32861d3d8eaa15c6009fdc34ad7de4
|
|
BLAKE2b-256 checksum How to use checksums |
07a2af437d408d7be339a4029b655c12b243f283b3bdd9941b3e97cb904ad5ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for pympcc 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.