ripopt
A memory-safe interior point optimizer written in Rust, inspired by Ipopt.
What is ripopt?
ripopt solves nonlinear programming (NLP) problems of the form:
min f(x)
s.t. g_l <= g(x) <= g_u
x_l <= x <= x_u
It implements a primal-dual interior point method (IPM) with a logarithmic barrier formulation. The solver is written entirely in Rust (~21,700 lines) with no external C/Fortran dependencies.
At a glance
| Property | Value |
|---|---|
| Algorithm | Primal-dual IPM with Mehrotra predictor-corrector |
| Linear solver | Dense Bunch-Kaufman LDL^T (small) / rmumps multifrontal (large) |
| HS benchmark | 118/120 (98.3%) — surpasses Ipopt's 116/120 |
| CUTEst benchmark | 562/727 (77.3%) — surpasses Ipopt's 561/727 |
| Speed vs Ipopt | 15.0x geo mean on HS suite, 9.9x on CUTEst |
| Language | Rust (no unsafe FFI) |
| Interfaces | Rust API, C API, Pyomo/AMPL, GAMS, Julia/JuMP |
Key features
- Primal-dual IPM with logarithmic barrier and fraction-to-boundary rule
- Mehrotra predictor-corrector with Gondzio centrality corrections (enabled by default)
- Filter line search with switching condition and second-order corrections
- Two-phase restoration: fast Gauss-Newton + full NLP restoration subproblem
- Multi-solver fallback: L-BFGS → Augmented Lagrangian → SQP → slack reformulation
- Dense condensed KKT (Schur complement) for tall-narrow problems: 100-800x speedup on m >> n
- Adaptive and monotone barrier strategies with automatic mode switching
- NE-to-LS reformulation for overdetermined nonlinear equation systems
- Parametric sensitivity analysis (sIPOPT-style)
- Preprocessing: fixed variable elimination, redundant constraint removal, bound tightening
- C API mirroring Ipopt's interface; Pyomo, GAMS, and Julia/JuMP wrappers
Quick example
use ripopt::{NlpProblem, SolveStatus, SolverOptions}; struct Hs071; impl NlpProblem for Hs071 { // ... (see API Guide for full implementation) } fn main() { let result = ripopt::solve(&Hs071, &SolverOptions::default()); assert_eq!(result.status, SolveStatus::Optimal); println!("f* = {:.6}", result.objective); // 17.014017 }
See the API Guide for a complete walkthrough.