Skip to main content

SqpOptions

Struct SqpOptions 

Source
pub struct SqpOptions {
Show 18 fields pub globalization: SqpGlobalization, pub hessian: SqpHessianSource, pub tol: Number, pub constr_viol_tol: Number, pub dual_inf_tol: Number, pub max_iter: u32, pub l1_penalty: Number, pub l1_penalty_safety: Number, pub l1_penalty_max: Number, pub bt_reduction: Number, pub bt_min_alpha: Number, pub print_level: u8, pub lbfgs_max_history: u32, pub dense_hessian_max_n: usize, pub qp_schur_min_dim: Option<usize>, pub qp_schur_indefinite_max_dim: Option<usize>, pub qp_ipm_cold_start_min_dim: Option<usize>, pub deadline: Option<Deadline>,
}

Fields§

§globalization: SqpGlobalization§hessian: SqpHessianSource§tol: Number

KKT tolerance (max-norm) on the stationarity residual.

§constr_viol_tol: Number

Tolerance on constraint violation (max-norm).

§dual_inf_tol: Number

Tolerance on stationarity residual (max-norm).

§max_iter: u32

Outer-iteration cap.

§l1_penalty: Number

l1-merit penalty parameter ν. Used only when globalization = L1Elastic. Filter globalization ignores this. Default is a moderate starting value; the Han-Powell ν-adaptation in l1_merit_line_search grows ν to dominate ‖λ_qp‖_∞ + l1_penalty_safety on every iteration.

§l1_penalty_safety: Number

Additive safety margin in the Han-Powell ν update: ν_new = max(ν, ‖λ_qp‖_∞ + l1_penalty_safety). Default 0.1 per Nocedal-Wright §18.4. Only consulted when globalization = L1Elastic.

§l1_penalty_max: Number

Upper clamp on ν. Prevents catastrophic Armijo failure on pathological problems where ‖λ_qp‖ momentarily spikes. Default 1e10 — large enough not to interfere with normal runs, small enough to keep the merit numerically stable. Only consulted when globalization = L1Elastic.

§bt_reduction: Number

Backtracking line-search reduction factor.

§bt_min_alpha: Number

Minimum step before declaring line-search failure.

§print_level: u8

print_level: 0 = silent, 1 = per-iteration summary, 2+ = trace (planned).

§lbfgs_max_history: u32

Number of (s, y) history pairs retained when hessian = Lbfgs. Mirrors the upstream limited_memory_max_history default of 6 (Nocedal-Wright recommends 3–20). Ignored for Exact and DampedBfgs.

§dense_hessian_max_n: usize

Largest n at which a quasi-Newton Hessian is handed to the QP as a dense matrix (sqp_dense_hessian_max_n). Above it, Lbfgs poses the QP in its lifted low-rank form (crate::sqp::SqpQpData::build_low_rank) and QuasiNewtonAuto resolves to Lbfgs rather than DampedBfgs. At or below it nothing changes from before gh#1054. Default 1000.

§qp_schur_min_dim: Option<usize>

Size from which the step QP uses Schur-complement updates (gh#1054): when Some(d), each solve sets QpOptions::use_schur_updates to n + m ≥ d; None leaves the QP options as given. The driver reads sqp_qp_use_schur_updates only when it is set explicitly, and then passes None here.

Why size: the refactor path pays a full sparse factorization per working-set change, which is what made the cold first QP of a 15 000-variable model run for 30 minutes, while on small models the two paths cost the same and the Schur path is the less robust one (measured on the CLI fixture corpus under algorithm=active-set-sqp). See docs/src/active-set-sqp.md for the Maros-Mészáros comparison behind the default.

§qp_schur_indefinite_max_dim: Option<usize>

Size from which a warm-started step QP whose Hessian is not known PSD goes back to the refactor path, overriding Self::qp_schur_min_dim (gh#1083, gh#1091). None never does; cold solves and PSD step QPs are not affected.

Such a QP carries the inertia hint Indefinite, and on it every drop refactors anyway (a rank-2 update cannot re-run inertia control on the enlarged null space), so only adds take the update. A warm step QP is drop-dominated: the reporter’s took 187 Schur updates against 4181 working-set changes over a 3600 s run. It then pays for the larger K_max — dearer factorizations, back-solves about 5× the small KKT’s — and gets almost nothing back; on its handover QP the Schur path took 126 s, the refactor path 72 s.

Two step QPs carry the hint: an exact Hessian’s, and the lifted L-BFGS one above sqp_dense_hessian_max_n (crate::sqp::SqpQpData::build_low_rank), whose Hessian diag(σI, ±1) is indefinite although the B it lifts is not. The rule reads the hint, which is what the QP solver branches on, not the Hessian source; until gh#1091 it read the source and missed the lift.

Cold solves keep the size rule because they are the add-dominated ones the Schur path wins on, and at this size they are not all seeded from the interior point: when the hint is not Psd the seed certifies the Hessian PSD numerically (ipm_seeded_step_qp) and declines if it is not. The lifted QP’s -1 entries never pass, and a nonconvex model’s exact Hessian need not, so such a cold QP still builds its working set one add at a time. (A convex model’s exact Hessian does pass, and its cold step QPs are seeded.)

§qp_ipm_cold_start_min_dim: Option<usize>

NLP size n + m from which a step QP solved without a working set, or with one that pins to an infeasible point, is first solved by the convex interior point, when its Hessian is PSD, and the active-set solver warm-started from the working set that solution identifies (gh#1061). None never does. The warm case: the reporter’s second step QP went to the ℓ1-elastic phase 1 from its infeasible warm start and reached a 300 s cap after 564 working-set changes; seeded, 12.5 s.

A cold active-set start builds its working set one pivot at a time, and on a large model that is the whole cost: gh#1061’s first step QP (n = 14 952, 10 818 equalities, H = I) went through the elastic phase 1 for more than 30 minutes on either factorization path without finishing. The interior point solved it in 16 iterations, 4.3 s, and the active-set solve from its working set took zero working-set changes and one factorization, 0.4 s, to the same objective. The active-set solve still has the last word, so the step and its multipliers are what the active-set method certifies, and anything short of an interior-point Optimal falls back to the cold start.

At the same size a warm start that pins feasibly is given a budget of four active-set iterations per iteration the last seed took, and is seeded once it runs over. gh#1061’s warm step QPs took 68–350 working-set changes and 51–263 s each at about one factorization per change; on the handover QP the budget and the seed together take 34 s against 72 s warm (126 s with Schur updates).

§deadline: Option<Deadline>

Solve-wide time budget (max_wall_time / max_cpu_time), the same Deadline the interior-point arm checks. None means unlimited and is the default for a directly constructed driver.

A shared handle rather than two durations, because the SQP is not always the first thing a solve runs: crossover hands it the interior-point phase’s own deadline, and a duration measured from optimize would grant it a fresh budget (gh#1054).

Implementations§

Source§

impl SqpOptions

Source

pub fn step_qp_schur_updates( &self, dim: usize, warm: Option<HessianInertia>, ) -> Option<bool>

Whether a step QP of size n + m = dim uses Schur updates, by Self::qp_schur_min_dim and Self::qp_schur_indefinite_max_dim. warm is the inertia hint of a QP warm-started from a working set, None for a cold one, whose hint the rule does not read. None back when the caller chose (qp_schur_min_dim unset), which leaves the QP options as given.

Trait Implementations§

Source§

impl Clone for SqpOptions

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SqpOptions

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SqpOptions

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more