pub fn resolve_solver(
class: ProblemClass,
selection: SolverSelection,
) -> Result<SolverChoice, String>Expand description
Resolve a ProblemClass and a SolverSelection into the solver
to dispatch to, or an error string when a forced selection does not
match the detected class.
auto routes LP / convex QP to the convex IPM (QpIpm) and convex
QCQP to the conic IPM (SocpIpm); nonconvex QP and general NLP resolve
to Nlp. A forced selection that does not match the detected class is
rejected with a clear message.
QpActiveSet is the one forced selection that is not restricted to the
convex classes: pounce-qp handles an indefinite Hessian by construction
(§4.5 inertia control), which is what docs/src/choosing-a-solver.md has
always advertised, so a NonconvexQp is accepted here and dispatched to it
(gh #786). auto still sends that class to the NLP filter-IPM — the class
is our inference, and the general path is the safer default for it — so
this is reachable only by asking for the engine by name.
What the verdict on an indefinite QP does and does not mean (gh #848).
This comment used to say the engine returns “a local solution”, reading
§4.5 inertia control as a second-order guarantee. It is not one: inertia
control shifts the KKT diagonal so each factorization has the right
inertia, which makes the linear algebra work and says nothing about the
curvature of P on the feasible directions at the point finally returned.
On P = [[1, 5], [5, 1]] over [-1, 1]² the engine reported Optimal at
the strict saddle x = 0, f = 0, where x = (1, -1) is feasible at
f = -4.
Second-order evidence is now part of the verdict, from two guards that
cover different classes (both described on
pounce_convex::solve_qp_active_set_inertia). The engine certifies the
reduced Hessian on its working set’s null space and, where it finds a
witness of negative curvature, escapes along it and returns the better
point — so the fix is usually a better answer rather than a worse status.
The driver then screens what comes back by exhibition, which reaches the
degenerate-active-bound class the first cannot, and refuses a verdict only
where it holds a strictly better feasible point in hand.
Local, still, and not even that in general: seeing past every working set
is the NP-hard part of nonconvex QP. sqp_qp_certify_second_order turns
the engine-side check off.