oximo-pounce 0.5.1

POUNCE (pure-Rust IPOPT) NLP backend for oximo. Finite differences on stable, exact derivatives via oximo-autodiff with the `enzyme` feature
Documentation

oximo-pounce

A POUNCE backend for oximo. POUNCE is a pure-Rust port of IPOPT, so this backend solves continuous LP/QP/QCP/NLP models.

Derivatives

  • Default (stable): every objective/constraint is classified once.
    • A model that is entirely linear/quadratic (LP/QP/QCP) solves on POUNCE's low-level TNLP surface with exact analytic gradients, Jacobian rows, and the exact constant Hessian of the Lagrangian including duals, reduced costs, iteration counts, and full primal-dual warm starts via the persistent handle.
    • A model with a nonlinear function solves through POUNCE's builder surface, where it uses finite differences and limited-memory L-BFGS Hessian. The backend supplies values from compiled tapes and still fills the exact closed-form parts through the builder's gradient/jacobian hooks. The builder doesn't expose solver internals, so on this path reduced costs and iteration counts are unavailable and warm starts are primal-only.
  • enzyme feature (nightly): exact gradient, sparse Jacobian, and sparse Hessian of the Lagrangian for everything, including nonlinear functions, from oximo-autodiff using TNLP.
use oximo_pounce::Pounce;
use oximo_solver::Solver;

let res = Pounce.solve(&model, &Default::default())?;

Options

PounceOptions has dedicated setters for the common controls (tol, max_iter, print_level, mu_strategy) plus one typed builder method per option in POUNCE's documented option reference (barrier-µ strategy, quality-function oracle, L1 penalty-barrier, NLP presolve/FBBT/auxiliary preprocessing, and FERAL backend tuning). Each method is named exactly like the POUNCE option:

use oximo_pounce::{MuStrategy, PounceOptions, Pounce};
use oximo_solver::Solver;

let opts = PounceOptions::default()
    .tol(1e-8)
    .mu_strategy(MuStrategy::Adaptive)
    .mu_oracle("probing")
    .presolve(true)
    .linear_solver("feral");

// Escape hatch:
let opts = opts.set("acceptable_tol", 1e-5);

let res = Pounce.solve(&model, &opts)?;

A few options are managed by this backend and should not be set by hand: print_level (via verbose/the print_level setter), max_cpu_time (via time_limit), warm_start_init_point (via the persistent handle), and hessian_approximation (set to limited-memory only when the model has a nonlinear function and the enzyme feature is off).

Solver type/routing

PounceOptions::algorithm selects either the default IPOPT-lineage PounceAlgorithm::InteriorPoint method or PounceAlgorithm::ActiveSetSqp. Both are valid for every continuous oximo kind POUNCE accepts: LP, QP, QCP, and NLP. The latter is a general NLP method despite solving QP subproblems.

POUNCE's lp-ipm, qp-ipm, and socp selectors rely on its command-line driver's structural extraction and are not available from pounce-rs's IpoptApplication.

Licensing

pounce-rs is licensed under EPL-2.0. oximo itself is MIT OR Apache-2.0.