pub enum SecondOpinionTrigger {
LocalInfeasibility,
InvalidNumber,
RestorationFailure,
IterationLimit,
}Expand description
Which failure opened the ladder. Not every rung is evidence about every
failure: an Invalid_Number_Detected is a statement about the callbacks
at a point, and re-running the same callbacks at the same point under a
different linear-solver scaling or a different barrier strategy evaluates
the same non-finite quantity again. Only the rung that moves the point
applies there.
Variants§
LocalInfeasibility
Infeasible_Problem_Detected — a local statement about a nonconvex
problem, which every rung is evidence against.
InvalidNumber
Invalid_Number_Detected — a NaN or infinity out of the model.
RestorationFailure
Restoration_Failed — the restoration phase could not find a point
the filter would accept. Like the two above and unlike a budget exit,
this is a statement about the trajectory the solve happened to take,
not about the model; see SecondOpinionTrigger::for_status.
IterationLimit
Maximum_Iterations_Exceeded — and only when the solve escalated
the linear solver’s factorization quality at least once (gh#857).
This is the one trigger that is not a property of the verdict alone,
and the exception it carves out of the paragraph on
SecondOpinionTrigger::for_status is narrow on purpose. A budget
exit normally wants a bigger budget, not a different trajectory —
but a feral_increase_quality escalation changes which pivots are
taken and never steps back down, so when one fired, the wall the
solve hit may be the escalated trajectory’s rather than the model’s,
and a bigger budget re-runs the same wall. On
square_flowsheet_resto’s lbfgs leg the escalated path reaches 3000
iterations and the un-escalated one converges in 178.
The escalation count is what keeps this from opening a ladder on
every budget exit; it comes from the quality_escalations statistic
and is checked in second_opinion_rungs, not here — for_status
only sees a status. A solve that escalated zero times produces an
empty rung list and the driver returns before it narrates anything.
Implementations§
Source§impl SecondOpinionTrigger
impl SecondOpinionTrigger
Sourcepub fn for_status(status: ApplicationReturnStatus) -> Option<Self>
pub fn for_status(status: ApplicationReturnStatus) -> Option<Self>
Which ladder, if any, a finished solve’s verdict opens.
Only these three statuses open one. In particular an iteration- or time-limit exit does not: the answer there is a bigger budget, and a re-solve from a different trajectory would burn the same budget again to reach the same wall.
Restoration_Failed is on the list for the same reason the other two
are (gh#815): it is a report about the path, not about the model.
The restoration phase failing to find a filter-acceptable point says
the iterate reached somewhere the sub-problem could not work from, and
a different starting point is a different sub-problem. It is not a
budget exit — pounce stops far short of max_iter — so “give it more
iterations” is not the available answer, which is precisely the
distinction the paragraph above draws. Measured on the gh#815 square
flowsheet family: both failing members exit Restoration_Failed, no
ladder ran, and rung 3 alone recovers both to Optimal Solution Found — one of them (f100) to an optimum Ipopt itself misses.
Only rung 3 opens on this trigger; rungs 1 and 2 stay gated on
SecondOpinionTrigger::LocalInfeasibility, so a restoration failure
costs exactly one extra solve. That is the measured ordering, not
caution for its own sake: over the KRONOS corpus the displaced start
recovered 13 of 15 where mu_strategy=adaptive recovered 4 (see
start_point_retry’s option text).
Trait Implementations§
Source§impl Clone for SecondOpinionTrigger
impl Clone for SecondOpinionTrigger
Source§fn clone(&self) -> SecondOpinionTrigger
fn clone(&self) -> SecondOpinionTrigger
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for SecondOpinionTrigger
Source§impl Debug for SecondOpinionTrigger
impl Debug for SecondOpinionTrigger
impl Eq for SecondOpinionTrigger
Source§impl PartialEq for SecondOpinionTrigger
impl PartialEq for SecondOpinionTrigger
impl StructuralPartialEq for SecondOpinionTrigger
Auto Trait Implementations§
impl Freeze for SecondOpinionTrigger
impl RefUnwindSafe for SecondOpinionTrigger
impl Send for SecondOpinionTrigger
impl Sync for SecondOpinionTrigger
impl Unpin for SecondOpinionTrigger
impl UnsafeUnpin for SecondOpinionTrigger
impl UnwindSafe for SecondOpinionTrigger
Blanket Implementations§
impl<T> Boilerplate for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T, U> Imply<T> for U
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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