slsqp_jax.qp.active_set¶
Single shared run_active_set_loop (add / drop / EXPAND / ping-pong) consumed by every QP strategy.
slsqp_jax.qp.active_set
Shared add / drop / EXPAND / ping-pong active-set loop.
The legacy slsqp_jax/qp_solver.py carried three near-identical copies
of this loop body — one in _solve_qp_proximal, one in
_solve_qp_direct, and one inlined in solve_qp’s ineq-only path.
This module hosts the single implementation; the three QP-strategy
modules now build their own initial state and inner-solve closure and
delegate to run_active_set_loop().
The loop is parameterised by the inner solve closure:
inner_solve_fn(state) -> ActiveSetInnerResult
which packages the new direction, equality / inequality multipliers, projection diagnostics, and the inner-failure flag. Callers control how the inner solver is wired (proximal-stabilised HVP vs. direct projection) by what they put in this closure.
- class slsqp_jax.qp.active_set.ActiveSetInnerResult[source]¶
Bases:
NamedTuplePer-iteration payload returned by the caller’s inner-solve closure.
- Attributes:
d: New search direction. multipliers_eq: Recovered (or absorbed) equality multipliers
for this iteration. Pass an empty
(0,)vector when no equality constraints are present.- multipliers_ineq: Recovered inequality multipliers (length
m_ineq); zero on inactive entries.- inner_failed: Whether the inner solve produced a non-finite
direction.
- proj_residual: Latest M-metric projection residual from the
inner solver (
MinresQLPSolver); always0for null-space CG / CRAIG.- n_proj_refinements: Refinement rounds applied by the inner
solver on this call. Accumulated by the loop into the running QPState count.
- projected_grad_norm: Latest projected-gradient norm from the
inner solver (
HRInexactSTCGonly;infotherwise).
- d: Float[Array, 'n']¶
Alias for field number 0
- multipliers_eq: Float[Array, 'm_eq']¶
Alias for field number 1
- multipliers_ineq: Float[Array, 'm_ineq']¶
Alias for field number 2
- inner_failed: Bool[Array, '']¶
Alias for field number 3
- proj_residual: Float[Array, '']¶
Alias for field number 4
- projected_grad_norm: Float[Array, '']¶
Alias for field number 6
- slsqp_jax.qp.active_set.run_active_set_loop(init_state, inner_solve_fn, A_ineq, b_ineq, max_iter, base_tol, effective_tau, drop_floor, ping_pong_threshold)[source]¶
Run the shared add / drop / EXPAND / ping-pong active-set loop.
The body, identical across all three QP strategies:
Compute the working tolerance
working_tol = base_tol + iteration * effective_tau(EXPAND ramp).Call the caller-supplied
inner_solve_fn()with the current active set; receive a new direction, multipliers, and projection diagnostics.Compute violation scores
A_ineq d - b_ineqand drop scoresmult_ineq < -max(working_tol, drop_floor).Branch on add / drop / mark_converged with the same ping-pong short-circuit logic that the legacy bodies used.
- Args:
init_state: Initial active-set state. inner_solve_fn: Closure performing the per-iteration inner
equality-constrained QP solve. Receives the current
QPStateand the currentworking_tol(some callers ignore it).- A_ineq: Inequality constraint matrix used for the violation
check. Must match what
inner_solve_fnconsumes.
b_ineq: Inequality RHS for the violation check. max_iter: Iteration budget (matches
while_loopcond). base_tol: Outer SQP-level base tolerance. effective_tau: Per-iteration EXPAND increment.0.0disables the ramp.
- drop_floor: Floor on the drop test so multiplier-recovery noise
does not flip a negligible negative multiplier into a drop.
- ping_pong_threshold: Threshold for the explicit add/drop
ping-pong short-circuit (
2**31 - 1effectively disables it).
- Returns:
The final
QPStateafter the active-set loop terminates.
- Return type:
- Parameters:
init_state (QPState)
inner_solve_fn (Callable[[QPState, Float[Array, '']], ActiveSetInnerResult])
A_ineq (Float[Array, 'm_ineq n'])
b_ineq (Float[Array, 'm_ineq'])
max_iter (int)
base_tol (Float[Array, ''])
effective_tau (Float[Array, ''] | float)
drop_floor (Float[Array, ''])
ping_pong_threshold (int)