slsqp_jax.inner.krylov

Low-level Krylov primitives: symmetric Givens rotations, the basic CG step, unconstrained CG, CRAIG bidiagonalization, and the PMINRES-QLP iteration.

slsqp_jax.inner.krylov

Krylov primitives shared by the inner solvers.

Hosts the building blocks used by every projector-based and saddle-point inner solver:

These were previously defined inline inside slsqp_jax/inner_solver.py mixed with the solver classes. Splitting them out keeps each Krylov recurrence in a single, navigable module and makes the high-level solver classes easier to read.

slsqp_jax.inner.krylov.build_cg_step(hvp_fn, cg_tol, precond_fn=None, project=None, cg_regularization=1e-06, cg_atol=None)[source]

Build a CG step function.

Args:

hvp_fn: Hessian-vector product function v -> B @ v. cg_tol: Convergence tolerance on residual norm (absolute when

cg_atol is None; otherwise the squared per-step test is r^T r < max(cg_atol**2, cg_tol**2) so the larger of the two acts as the effective floor).

precond_fn: Optional preconditioner v -> M @ v where M ~ B^{-1}. project: Optional projection function v -> P(v) where P is the

projection onto the null space of A.

cg_regularization: Minimum eigenvalue threshold for the curvature

guard.

cg_atol: Optional absolute residual-norm floor. When provided,

convergence is declared at r^T r < max(cg_atol**2, cg_tol**2). Used by the multiplier-recovery CG inside ProjectedCGCraig so that a near-KKT iterate does not chase a relative target below eps. Defaults to None (current behaviour: pure absolute test r^T r < cg_tol**2).

Returns:

A CG step function.

Parameters:
  • cg_tol (Float[Array, ''] | float)

  • precond_fn (Callable[[Float[Array, 'n']], Float[Array, 'n']] | None)

  • project (Callable[[Float[Array, 'n']], Float[Array, 'n']] | None)

  • cg_regularization (float)

  • cg_atol (float | None)

slsqp_jax.inner.krylov.craig_solve(A, rhs, tol=1e-10, max_iter=100)[source]

Solve min ||x|| s.t. A x = rhs via CRAIG’s method.

CRAIG’s method (Paige & Saunders, 1982) uses Golub-Kahan bidiagonalization to solve the minimum-norm problem without forming A A^T. Only matrix-vector products A @ v and A.T @ u are needed.

Convergence test is hybrid absolute+relative: residual < max(_CRAIG_TOL_ABS=1e-12, tol * ||rhs||). The absolute floor protects against the pathology where ||rhs|| is itself near machine epsilon (e.g. when projecting at a near-KKT iterate where A v shrinks at the rate the SQP is converging), in which case the pure-relative target tol * ||rhs|| would drop below eps and convergence could never fire.

Return type:

tuple[Float[Array, 'n'], Bool[Array, '']]

Parameters:
  • A (Float[Array, 'm n'])

  • rhs (Float[Array, 'm'])

  • tol (float | Float[Array, ''])

  • max_iter (int)

Args:

A: Matrix (m x n). rhs: Right-hand side (m,). tol: Relative tolerance on ||A x - rhs|| / ||rhs||. The

effective convergence threshold also has a hardcoded absolute floor of 1e-12.

max_iter: Maximum bidiagonalization steps.

Returns:

Tuple (x, converged). converged is True only when the residual fell below the hybrid threshold; it is False if CRAIG broke down (alpha / beta below an absolute threshold, signalling rank deficiency or numerical collapse) or exhausted its iteration budget. When converged is False the returned x is still the best iterate produced before the failure.

slsqp_jax.inner.krylov.pminres_qlp_solve(matvec, rhs, tol=1e-10, max_iter=200, precond=None)[source]

Solve a symmetric (possibly indefinite/singular) system Ax = b.

Implements the full Preconditioned MINRES-QLP algorithm (Table 3.5 of Choi, Paige & Saunders, SIAM J. Sci. Comput. 33(4), 2011).

All iterations use QLP mode (equivalent to TranCond=1 in the reference implementation).

Return type:

tuple[Float[Array, 'n'], Bool[Array, '']]

Parameters:
  • matvec (Callable[[Float[Array, 'n']], Float[Array, 'n']])

  • rhs (Float[Array, 'n'])

  • tol (float | Float[Array, ''])

  • max_iter (int)

  • precond (Callable[[Float[Array, 'n']], Float[Array, 'n']] | None)

Args:

matvec: Symmetric operator v -> A @ v. rhs: Right-hand side vector. tol: Convergence tolerance on relative residual. max_iter: Maximum Lanczos iterations. precond: Optional SPD preconditioner v -> M^{-1} @ v.

Returns:

Tuple of (x, converged).

slsqp_jax.inner.krylov.solve_unconstrained_cg(hvp_fn, g, max_cg_iter, cg_tol, precond_fn=None, cg_regularization=1e-06, cg_atol=None)[source]

Solve the unconstrained QP: min (1/2) d^T B d + g^T d.

Uses (preconditioned) conjugate gradient to solve B d = -g without forming B. When precond_fn is provided, the standard PCG algorithm is used: z = M r, beta = r_new^T z_new / r_old^T z_old, and p is built from z (Nocedal & Wright, Algorithm 5.3).

Return type:

tuple[Float[Array, 'n'], Bool[Array, '']]

Parameters:
  • hvp_fn (Callable[[Float[Array, 'n']], Float[Array, 'n']])

  • g (Float[Array, 'n'])

  • max_cg_iter (int)

  • cg_tol (Float[Array, ''] | float)

  • precond_fn (Callable[[Float[Array, 'n']], Float[Array, 'n']] | None)

  • cg_regularization (float)

  • cg_atol (float | None)

Args:

hvp_fn: Hessian-vector product function v -> B @ v. g: Linear term (gradient). max_cg_iter: Maximum CG iterations. cg_tol: Convergence tolerance on residual norm. precond_fn: Optional preconditioner v -> M @ v where M ~ B^{-1}. cg_regularization: Minimum eigenvalue threshold for the curvature

guard. CG declares “bad curvature” when the effective eigenvalue p^T B p / ||p||^2 falls below this value. Based on SNOPT Section 4.5 (Gill, Murray & Saunders, 2005).

cg_atol: Optional absolute residual-norm floor. When provided,

the per-step convergence test becomes r^T r < max(cg_atol**2, cg_tol**2) so an absolute floor kicks in whenever the user-supplied cg_tol would target a residual below the floor.

Returns:

Tuple of (d, converged) where d is the solution vector and converged indicates whether CG converged (residual below tolerance) as opposed to hitting bad curvature or exhausting the iteration budget.