Skip to main content

IpoptAlgorithm

Struct IpoptAlgorithm 

Source
pub struct IpoptAlgorithm {
Show 33 fields pub data: IpoptDataHandle, pub cq: IpoptCqHandle, pub bundle: AlgorithmBundle, pub nlp: Option<Rc<RefCell<dyn IpoptNlp>>>, pub tnlp: Option<Rc<RefCell<dyn TNLP>>>, pub fires_as_restoration: bool, pub search_dir: Option<PdSearchDirCalc>, pub restoration: Option<Box<dyn RestorationPhase>>, pub kappa_sigma: Number, pub slack_based_scaling: bool, pub recalc_y: bool, pub recalc_y_feas_tol: Number, pub max_iter: Index, pub start_with_resto: bool, pub alpha_init: Number, pub tiny_step_tol: Number, pub diverging_iterates_tol: Number, pub tiny_step_y_tol: Number, pub dual_diverging_streak: usize, pub dual_divergence_retry_step_tol: Number, pub dual_divergence_retry_du_floor: Number, pub tiny_step_last_iteration: bool, pub resto_decline_deferrals: usize, pub resto_decline_progress_ratio: Number, pub neg_curv_escapes: usize, pub lbfgs_ls_failure_restarts: usize, pub last_iter_stats_sink: Option<Rc<RefCell<Option<IterStats>>>>, pub kkt_fidelity_tol: Number, pub resto_calls: Index, pub resto_inner_iters: Index, pub resto_outer_iters: Index, pub resto_wall_secs: Number, pub print_iter_output: bool, /* private fields */
}

Fields§

§data: IpoptDataHandle§cq: IpoptCqHandle§bundle: AlgorithmBundle§nlp: Option<Rc<RefCell<dyn IpoptNlp>>>

Optional NLP handle. Required for any step that evaluates problem functions or pulls bound expansion matrices (init, search direction, line-search trial-point evaluation). Absent in the structural unit tests of Phases 5-6.

§tnlp: Option<Rc<RefCell<dyn TNLP>>>

Optional TNLP handle — the user-facing problem. When present, iterate() fires TNLP::intermediate_callback once per outer iteration so callers can monitor progress or request early termination (returning false from the callback surfaces as SolverReturn::UserRequestedStop). Kept separate from nlp because the algorithm-side NLP is the compressed OrigIpoptNlp view (fixed-variable elimination, c/d split) while the callback payload needs to expose the original-coordinate iterate.

§fires_as_restoration: bool

Set on the restoration inner IPM so its callback fires report AlgorithmMode::RestorationPhaseMode (gh#645). Two things hang off it, both in Self::fire_intermediate:

  1. the mode field of the IterStats payload, which is what tells a caller the numbers beside it (obj, inf_pr, inf_du, alpha_*) describe the min-C1-norm feasibility subproblem rather than the user’s NLP;
  2. whether the live-inspector IntermediateContext is installed — and for a restoration fire it deliberately is not. The inner iterate is a CompoundVector over (x_orig, n, p), so it does not even have the user’s n, and the C API’s GetIpoptCurrent* family checks the caller’s n/m against the problem’s registered dimensions rather than the context’s. Installing this context would sail past that check and read a differently-shaped cq. The live accessors therefore report “no data” during restoration, which is the truth: there is no current iterate of the user’s problem while the subproblem is being solved.
§search_dir: Option<PdSearchDirCalc>

Search-direction calculator (PdSearchDirCalc). Lands once a concrete SymLinearSolver backend (MUMPS / FERAL) is wired through AlgBuilder in Phase 7’s tail.

§restoration: Option<Box<dyn RestorationPhase>>

Restoration-phase strategy. Invoked when the line search returns Outcome::Failed (port of upstream IpBacktrackingLineSearch::ActivateLineSearch’s resto fallback). Optional: in its absence, line-search failure maps directly to SolverReturn::RestorationFailure so the main loop’s exit-code semantics match upstream’s “no resto built” case.

§kappa_sigma: Number

kappa_sigma for the post-AcceptTrialPoint multiplier reset (IpIpoptAlg.cpp:correct_bound_multiplier, line 1055-1134).

§slack_based_scaling: bool

recalc_y — recompute y_c/y_d as least-square estimates once the iterate is feasible enough, instead of carrying the multipliers the Newton step produced. Upstream registers this no, but its own option text says “If a limited memory quasi-Newton option is chosen, this is used by default”, so the L-BFGS path auto-enables it (see application.rs). Costs one extra augmented-system solve on every iteration where it fires.

It exists because a quasi-Newton model’s multipliers are only as good as the Hessian approximation behind them: L-BFGS can reach a feasible primal and still fail to drive inf_du down, because the dual step is computed from an approximate W. Re-estimating y by least squares side-steps the approximation entirely. linear_system_scaling=slack-based is active, so the iterate-dependent s-block scaling must be refreshed each iteration. See Self::push_slack_scaling.

§recalc_y: bool§recalc_y_feas_tol: Number

recalc_y_feas_tol — the constraint-violation threshold below which Self::recalc_y fires. Upstream default 1e-6.

§max_iter: Index§start_with_resto: bool

start_with_resto — force the feasibility restoration phase in the first iteration.

This is an outer-loop behaviour, which is where it went wrong before: the option was threaded from the OptionsList through AlgorithmBuilder::resto into RestoAlgorithmBuilder and on into MinC1NrmDriver, a field on the inner restoration solver, where there is no first iteration of the outer algorithm to act on. It was set by everything and read by nothing, so start_with_resto yes was a silent no-op. unimplemented_options.rs’s the_restoration_switches_reach_the_builder asserted only that the value reached the builder — the very “read site populating a field nobody consumes” its own comment names as the defect to avoid.

§alpha_init: Number

Initial primal step length offered to the line search at the top of each iteration. Mirrors IpBacktrackingLineSearch’s fraction-to-the-boundary primal step (with τ = data.curr_tau). In v1.0 the structural value here is 1.0 and the FTB cap is applied per-component when the line-search driver computes trial slacks; the simplification holds for non-degenerate runs.

§tiny_step_tol: Number

Tiny-step relative tolerance — port of upstream IpBacktrackingLineSearch::tiny_step_tol_ (default 10·EPSILON). Step is “tiny” when max_i |δx_i|/(1+|x_i|) ≤ tiny_step_tol (and same for s, and c_viol ≤ 1e-4).

§diverging_iterates_tol: Number

Port of upstream IpIpoptAlg.cpp divergence guard: when max_i |x_i| exceeds this threshold the optimization aborts with SolverReturn::DivergingIterates. Default 1e20 matches the registered diverging_iterates_tol option. Catches MESH and similar cases where the normal-mode IPM heads off to infinity (orig f to ±1e33 by iter 90) before line-search failure forces a degenerate restoration entry.

§tiny_step_y_tol: Number

Companion threshold on the dual step — when both primal and dual steps are tiny in two consecutive iterations the algorithm declares convergence at the best attainable accuracy. Default 1e-2 matches upstream.

§dual_diverging_streak: usize

dual_diverging_streak (pounce#246) — number of consecutive iterations of growing dual infeasibility (in the elevated regime, inf_du > [DUAL_DIV_COUNT_FLOOR]) that must accumulate before the dual-divergence guard fires. When the streak reaches the limit and inf_du > [DUAL_DIV_FIRE_TOL], the outer routes to restoration.

0 (off) is the default, set from the option of the same name (application.rs). It defaulted to 15 when introduced; see the option help in upstream_options.rs for why that changed, and Self::honour_best_acceptable_after_dual_guard for what protects a solve when it is enabled. See the guard itself in Self::iterate.

§dual_divergence_retry_step_tol: Number

gh#884 — thresholds for the dual-divergence retry signature. Distinct from the pounce#246 guard above in both mechanism and consequence: that one diverts a running solve to restoration, this one only records that a cold retry is worth attempting after the solve has already given up. Set from options of the same name; see [DUAL_DIV_RETRY_STEP_TOL] for the measured populations.

§dual_divergence_retry_du_floor: Number

Companion floor on the unscaled dual — see [DUAL_DIV_RETRY_DU_FLOOR].

§tiny_step_last_iteration: bool

Set true when the previous iterate was tagged tiny; on the second consecutive tiny step the loop sets data.tiny_step_flag so the mu update can attempt to terminate. Mirrors IpBacktrackingLineSearch::tiny_step_last_iteration_.

§resto_decline_deferrals: usize

resto_decline_deferrals (gh #534) — how many times the acceptable-point restoration decline in Self::invoke_restoration may be deferred on a solve whose NLP error is still contracting. 0 restores the pre-#534 behaviour (decline immediately, always).

See Self::may_defer_acceptable_decline for the progress test and Self::honour_decline_floor for what makes a spent deferral harmless.

§resto_decline_progress_ratio: Number

resto_decline_progress_ratio (gh #534) — the contraction each of the last [DECLINE_PROGRESS_SAMPLES] - 1 iterations must have achieved for the decline to be deferred. Default [DEFAULT_DECLINE_PROGRESS_RATIO]. A value of 1 admits any non-increasing window and a large one drops the progress requirement altogether, which is the “patch the guard and see” experiment the issue asks for, available without patching.

§neg_curv_escapes: usize

neg_curv_escapes (gh #797) — how many times a certified stationary point whose reduced Hessian is not positive semidefinite may be left along a direction of negative curvature instead of reported. 0 restores the pre-#797 behaviour (report the first-order certificate, whatever its curvature).

See Self::try_neg_curv_escape for the test and the step, and Self::honour_neg_curv_floor for what makes a lost bet harmless.

§lbfgs_ls_failure_restarts: usize

limited_memory_ls_failure_restarts (gh #818) — how many times a line-search failure at an already feasible point may re-anchor the quasi-Newton model and retry, instead of handing off to a restoration phase that has no constraint violation to reduce. 0 restores the pre-#818 behaviour (always hand off).

See Self::try_reanchor_before_restoration for the rung and what bounds it.

§last_iter_stats_sink: Option<Rc<RefCell<Option<IterStats>>>>

Sink for the last IterStats handed to the user’s intermediate_callback (pounce#870). A second-opinion retry that loses needs it, so that the trace a consumer accumulated can be made to end on the iterate actually reported. Set by IpoptApplication; None everywhere else.

§kkt_fidelity_tol: Number

kkt_fidelity_tol (pounce#173), needed here — not just at termination — because the fallback’s tiebreak has to predict the post-solve status gate. See Self::honour_refused_certificate. Zero (the default) disables the gate, and with it every tiebreak effect it has.

§resto_calls: Index

Number of invoke_restoration entries.

§resto_inner_iters: Index

Sum of inner-IPM iter counts across every restoration call.

§resto_outer_iters: Index

Number of outer iters that ran in restoration mode (R-line equivalents in print_level=5 output).

§resto_wall_secs: Number

Cumulative wall-clock seconds spent inside perform_restoration.

§print_iter_output: bool

When false, the per-iteration table that iterate() writes straight to stdout is suppressed. Wired from IpoptApplication’s print_level option: level 0 turns this off (matches upstream’s “no console output” contract). Default true so CLI / direct-driver users keep the familiar trace.

Implementations§

Source§

impl IpoptAlgorithm

Source

pub fn least_square_init_report(&self) -> Option<LeastSquareInitReport>

Diagnostics from the safeguarded least_square_init_primal initializer step (gh#605). None when the step was not run.

Source

pub fn new( data: IpoptDataHandle, cq: IpoptCqHandle, bundle: AlgorithmBundle, ) -> Self

Source

pub fn with_nlp(self, nlp: Rc<RefCell<dyn IpoptNlp>>) -> Self

Source

pub fn with_tnlp(self, tnlp: Rc<RefCell<dyn TNLP>>) -> Self

Install a user-facing TNLP handle. Enables per-iteration TNLP::intermediate_callback invocation from optimize().

Source

pub fn with_search_dir(self, sd: PdSearchDirCalc) -> Self

Source

pub fn with_restoration(self, resto: Box<dyn RestorationPhase>) -> Self

Source

pub fn with_diagnostics(self, diag: Rc<DiagnosticsState>) -> Self

Install the shared diagnostics state. The state is propagated to the augmented-system solver at the top of Self::optimize so dump sites can consult per-iter gating.

Source

pub fn with_debug_hook(self, hook: Rc<RefCell<dyn DebugHook>>) -> Self

Install an interactive debugger hook. Fired at each checkpoint in Self::optimize; returning crate::debug::DebugAction::Stop ends the solve with SolverReturn::UserRequestedStop.

Source

pub fn debug_hook(&self) -> Option<Rc<RefCell<dyn DebugHook>>>

Shared handle to the installed debugger, if any — used to forward it into the restoration inner IPM.

Source

pub fn dual_divergence_signature(&self) -> bool

Whether this solve ever saw gh#884’s dual-divergence-at-a-settled-primal signature. Sticky; see Self::dual_divergence_signature.

Source

pub fn optimize(&mut self) -> SolverReturn

Outer entry point — port of IpoptAlgorithm::Optimize(). Calls the iterate-initializer once, then loops iterate() until a terminal status. The exception → SolverReturn mapping (TINY_STEP_DETECTED → STEP_BECOMES_TINY, RESTORATION_FAILED → RESTORATION_FAILURE, etc.) lands in Phase 9 alongside the restoration phase. Run the solve and finalize its result.

A thin wrapper on purpose. The gh #200 fallback must see every exit of the driver loop, and wiring it into individual termination sites was tried and failed — there are sixteen, and the ones easiest to overlook are the ones most likely to matter. Keeping the loop in a separate function means every return inside it, present or future, flows through Self::honour_refused_certificate by construction rather than by the author remembering to.

This got more important once the fallback started changing the status in both directions: it can now hand back StopAtAcceptablePoint for a Success it was given. Anything reading result before the hook is reading a status that is not the one reported.

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> 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, 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