Skip to main content

TerminationReason

Enum TerminationReason 

Source
#[non_exhaustive]
pub enum TerminationReason {
Show 13 variants GradientTolerance { grad_norm: f64, threshold: f64, }, SmallStepFlatObjective { step_norm: f64, objective_change: f64, grad_norm: f64, threshold: f64, }, RelativeStationarityWindow { grad_inf: f64, threshold: f64, window: usize, }, CostStallStationary { grad_norm: f64, threshold: f64, window: usize, }, CostStallFloor { grad_norm: f64, threshold: f64, window: usize, }, ModelNoiseFloor { predicted_decrease: f64, noise_floor: f64, grad_norm: f64, }, TrustRegionRejectFloor { radius: f64, floor: f64, consecutive_rejections: usize, grad_norm: f64, }, StepNormTolerance { step_norm: f64, threshold: f64, }, FixedPointRequestedStop { step_norm: f64, }, IterationBudget { iterations: usize, grad_norm: f64, threshold: f64, }, LineSearchFailed { grad_norm: f64, }, ObjectiveFailed, NumericalFailure,
}
Expand description

Why a solver stopped, and the quantities that decided it.

Every opt solver reaches its return through exactly one of these tests. Before this type existed the choice was discarded at the return statement: forty-two distinct stop decisions across the five solvers collapsed into three observable outcomes (Ok, MaxIterationsReached, LineSearchFailed), and every consumer re-derived the reason from the error variant, from the rendered message text, or from whichever solver branch it happened to call. Those re-derivations disagreed with each other and with the solver.

The reason is therefore a required field of Solution, not an Option on a side channel: an absent reason and a reason that happens to be uninteresting must not render identically, and a stop site that forgets to name its test must not compile.

§Not every “converged” is the same claim

GradientTolerance and RelativeStationarityWindow both return successfully, but the second applies a threshold scaled by 1 + ‖x‖∞ and measured in L∞ — at a large iterate it can be orders of magnitude weaker. Consumers that certify optimality must read stationarity_evidence rather than treating every success alike.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

GradientTolerance

The bound-projected gradient norm fell below the resolved gradient tolerance. The strongest claim any solver here makes.

Fields

§grad_norm: f64
§threshold: f64
§

SmallStepFlatObjective

The step became negligible, the objective flat across it, and the projected gradient below tolerance — all three together.

Fields

§step_norm: f64
§objective_change: f64
§grad_norm: f64
§threshold: f64
§

RelativeStationarityWindow

An L∞ stationarity test, with the threshold rescaled by 1 + ‖x‖∞, held for window consecutive iterations. Weaker than GradientTolerance by the scaling factor and by the norm change; see StationarityScaling::RelativeToIterate.

Fields

§grad_inf: f64
§threshold: f64
§window: usize
§

CostStallStationary

The objective flatlined over the cost-stall window and the projected gradient at the best iterate cleared its tolerance: a genuine stationary optimum on a flat valley.

Fields

§grad_norm: f64
§threshold: f64
§window: usize
§

CostStallFloor

The objective flatlined over the cost-stall window but the projected gradient did not clear tolerance. Halting is correct — no further cost progress is available — but the point is not stationary. Not a success.

Fields

§grad_norm: f64
§threshold: f64
§window: usize
§

ModelNoiseFloor

The model’s predicted decrease fell below the objective’s round-off noise floor, so the acceptance ratio carries no curvature information. Stationary in the finite-precision sense.

Fields

§predicted_decrease: f64
§noise_floor: f64
§grad_norm: f64
§

TrustRegionRejectFloor

The trust radius (or cubic regularization) reached its floor with consecutive_rejections steps rejected in a row: the region cannot shrink further and no step is acceptable. Further iterations would re-evaluate the objective without any prospect of progress, so the loop stops here rather than grinding out its iteration budget.

Fields

§radius: f64
§floor: f64
§consecutive_rejections: usize
§grad_norm: f64
§

StepNormTolerance

A fixed-point iteration’s accepted step norm fell below tolerance.

Fields

§step_norm: f64
§threshold: f64
§

FixedPointRequestedStop

A fixed-point objective returned FixedPointStatus::Stop. The objective, not the solver, decided to stop; the solver makes no stationarity claim of its own.

Fields

§step_norm: f64
§

IterationBudget

The iteration budget was exhausted with no test satisfied. The returned point is the best seen.

Fields

§iterations: usize
§grad_norm: f64
§threshold: f64
§

LineSearchFailed

The line search could not produce an acceptable point.

Fields

§grad_norm: f64
§

ObjectiveFailed

The objective returned a fatal evaluation error.

§

NumericalFailure

Numerical instability: non-finite gradient or objective, a model Hessian that could not be made positive definite, a subproblem solver that produced no usable step.

Implementations§

Source§

impl TerminationReason

Source

pub fn stationarity_evidence(&self) -> Option<StationarityEvidence>

The quantity this stop was decided against, when it asserts first-order stationarity at all.

None for stops that make no stationarity claim (IterationBudget, ObjectiveFailed, …). For those the gradient norm, where known, is still readable via grad_norm — but it was not compared against anything, and reporting it as though it had been is the defect this distinction exists to prevent.

Source

pub fn grad_norm(&self) -> Option<f64>

The gradient norm at the returned point, where the stop site knew one. Unlike stationarity_evidence this makes no claim that the value was compared against anything.

Source

pub fn is_stationary_claim(&self) -> bool

true when the solver asserts the returned point is stationary.

Note this is a claim about the test that fired, not about its strength: RelativeStationarityWindow answers true while applying a threshold that can be orders of magnitude looser than the absolute one. Read stationarity_evidence to judge the strength.

Source

pub fn status(&self) -> OptimizationStatus

The OptimizationStatus this reason maps to.

OptimizationStatus is derived from the reason rather than being set independently, so the coarse classification can never disagree with the test that actually fired.

Source

pub fn is_success(&self) -> bool

true when the run terminated at a point the solver is willing to certify. Equivalent to self.status().is_success().

Source

pub fn label(&self) -> &'static str

A short stable identifier, suitable for logs and structured records.

Trait Implementations§

Source§

impl Clone for TerminationReason

Source§

fn clone(&self) -> TerminationReason

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 Copy for TerminationReason

Source§

impl Debug for TerminationReason

Source§

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

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

impl Display for TerminationReason

Source§

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

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

impl PartialEq for TerminationReason

Source§

fn eq(&self, other: &TerminationReason) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for TerminationReason

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> Boilerplate for T
where T: Copy + Send + Sync + Debug + PartialEq + 'static,

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, 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> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.