Skip to main content

MonotoneMuUpdate

Struct MonotoneMuUpdate 

Source
pub struct MonotoneMuUpdate {
    pub mu_init: Number,
    pub mu_min: Number,
    pub mu_max: Number,
    pub mu_linear_decrease_factor: Number,
    pub mu_superlinear_decrease_power: Number,
    pub tau_min: Number,
    pub barrier_tol_factor: Number,
    pub mu_target: Number,
    pub mu_allow_fast_monotone_decrease: bool,
    pub compl_inf_tol: Number,
    pub first_iter_resto: bool,
}

Fields§

§mu_init: Number§mu_min: Number§mu_max: Number

Upper bound on μ from IpMonotoneMuUpdate.cpp:RegisterOptions. Used to clamp mu_init at MuUpdate::initialize so the barrier doesn’t start above the registered ceiling regardless of what the user set. Default 1e5 mirrors upstream.

§mu_linear_decrease_factor: Number§mu_superlinear_decrease_power: Number§tau_min: Number§barrier_tol_factor: Number

barrier_tol_factor from IpMonotoneMuUpdate.cpp:RegisterOptions. μ only decreases when the barrier subproblem error drops below barrier_tol_factor · μ.

§mu_target: Number

mu_target floor — μ never goes below this regardless of the reduction formula. Defaults to 0 (the floor is mu_min).

§mu_allow_fast_monotone_decrease: bool

mu_allow_fast_monotone_decrease from IpMonotoneMuUpdate.cpp:RegisterOptions. When true (the upstream default), the reduction loop keeps iterating while the sub-error stays below barrier_tol_factor · μ, allowing multiple consecutive μ reductions in one outer call. When false, the loop exits after the first successful reduction — useful on stiff problems where a runaway μ collapse destroys the line search.

§compl_inf_tol: Number

Complementarity tolerance — option compl_inf_tol, default 1e-4 per IpAlgorithmRegOp.cpp. Enters the dynamic μ floor via min(tol, compl_inf_tol) / (barrier_tol_factor + 1) per IpMonotoneMuUpdate.cpp:CalcNewMuAndTau:215. Without this floor, μ can collapse to the absolute floor (mu_min) while primal infeasibility is still large — observed on SSINE/DECONVBNE.

§first_iter_resto: bool

first_iter_resto_ flag from Algorithm/IpMonotoneMuUpdate.cpp:118-121,144,196. When set, the very next call to Self::update_barrier_parameter skips the μ-reduction loop entirely and clears the flag. Wired by the restoration sub-builder for the inner IPM (prefix "resto.") so the inner doesn’t immediately collapse μ on iteration 0 — it must use the resto_mu value that [crate::resto::init::RestoIterateInitializer::SetInitialIterates] seeded into data.curr_mu.

Implementations§

Source§

impl MonotoneMuUpdate

Source

pub fn new() -> Self

Source

pub fn with_first_iter_resto(self, b: bool) -> Self

Builder helper for the first_iter_resto_ flag. Mirrors the upstream prefix == "resto." branch in IpMonotoneMuUpdate.cpp:InitializeImpl.

Source

pub fn with_mu_min(self, mu_min: Number) -> Self

Builder for the mu_min floor. The restoration inner IPM uses 100 * outer_mu_min per upstream IpAdaptiveMuUpdate.cpp:206-211 (and the analogous monotone path); without the conservative floor, near-feasible iterates collapse μ to the absolute floor in a single step and the next direction is dominated by the penalty/proximity terms instead of the barrier, which destroys near-feasibility (DECONVBNE).

Source

pub fn compute_tau(&self, mu: Number) -> Number

Fraction-to-the-bound parameter tau from upstream IpMonotoneMuUpdate.cpp:Update:

  tau = max(tau_min, 1 - mu)

Returns a value in [tau_min, 1).

Source

pub fn scaled_compl_inf_tol(&self, obj_scaling_factor: Number) -> Number

compl_inf_tol expressed in the internally scaled space that μ lives in (pounce#257).

The dynamic μ floor exists so the barrier stops just below the accuracy the convergence test demands, and its two terms are enforced in different spaces. tol is compared against the scaled NLP error, so it needs no conversion. compl_inf_tol is compared against the unscaled complementarity (IpOptErrorConvCheck.cpp; pounce#173), which is the scaled complementarity divided by the objective scaling factor — so compl_inf_tol in scaled units is compl_inf_tol · |obj_scaling_factor|.

Taking the raw value put the floor 1/|df| too high whenever the objective was scaled down. On jit1’s branch-and-bound node subproblems (df = 1e-5, tol = 1e-7) μ bottomed out at 9.09e-9, leaving an unscaled complementarity of 9.09e-4 — a hard 9× over compl_inf_tol that no further iteration could clear, since μ was already at its floor. The iterate sat at the optimum with a scaled NLP error 10× under tol, yet the strict certificate was unreachable; μ-at-floor plus the vanishing step then exited STOP_AT_TINY_STEP (Search_Direction_Becomes_Too_Small), which callers read as unboundedness. Converting the tolerance into μ’s own space lets the barrier descend far enough for the certificate to be issued.

The factor is signed (obj_scaling_factor = -1 poses a maximization), so take its magnitude, and fall back to the unconverted tolerance when it is absent or degenerate — a floor that is too low only costs iterations, whereas one that is too high costs the certificate.

Source

pub fn certificate_safe_mu_min(&self, obj_scaling_factor: Number) -> Number

mu_min capped so it can never block the termination certificate (pounce#266) — the companion of Self::scaled_compl_inf_tol.

#258 converted the dynamic term of the barrier floor into μ’s scaled space, but the floor has a second, independent term: mu_min, a raw absolute constant (default 1e-11) that also lives in scaled space. Once compl_inf_tol·|df|/(barrier_tol_factor+1) < mu_min — i.e. |df| below ≈ mu_min·(barrier_tol_factor+1)/compl_inf_tol — the converted term stops mattering, μ bottoms out at mu_min, and the unscaled complementarity is pinned at mu_min/|df| > compl_inf_tol: the certificate is unreachable no matter how long the solve runs, and μ-at-floor plus the vanishing step exits STOP_AT_TINY_STEP on an iterate that is at the optimum (HS71 × 1e8, df = 8.3e-8).

Upstream’s monotone floor (IpMonotoneMuUpdate.cpp:CalcNewMuAndTau) has no mu_min term at all — pounce added it so the restoration sub-builder’s with_mu_min(100 * outer_mu_min) safeguard applies — which is why Ipopt certifies these files even with mu_min=1e-11 forced. Capping at scaled_compl_inf_tol / (barrier_tol_factor + 1) keeps mu_min inert exactly when it would cost the certificate, with the same headroom the dynamic floor reserves (μ then bottoms out where Ipopt’s does: 7.58e-13 on HS71 × 1e8). A floor that is too low only costs iterations; one that is too high costs the certificate.

The restoration safeguard is unaffected: RestoIpoptNlp does not override obj_scaling_factor, so the inner IPM sees df = 1 and the cap (compl_inf_tol/(barrier_tol_factor+1) ≈ 9e-6 at defaults) sits far above 100 · mu_min.

Source

pub fn compute_next_mu(&self, curr_mu: Number) -> Number

Pure scalar reduction used by the trait impl. Exposed so unit tests can drive the formula without standing up an IpoptData/IpoptCq fixture.

Trait Implementations§

Source§

impl Default for MonotoneMuUpdate

Source§

fn default() -> Self

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

impl MuUpdate for MonotoneMuUpdate

Source§

fn terminates_on_tiny_step(&self) -> bool

Monotone μ throws TINY_STEP_DETECTED when a tiny step is flagged and μ is already at its floor — see IpMonotoneMuUpdate.cpp. The main loop realises that throw as a STOP_AT_TINY_STEP termination.

Source§

fn initialize(&mut self, data: &IpoptDataHandle)

Port of IpMonotoneMuUpdate.cpp:InitializeImpl. Seeds curr_mu = min(mu_init, mu_max), curr_tau = max(tau_min, 1 - curr_mu).

Source§

fn update_barrier_parameter( &mut self, data: &IpoptDataHandle, cq: &IpoptCqHandle, _nlp: Option<&Rc<RefCell<dyn IpoptNlp>>>, _pd_search_dir: Option<&mut PdSearchDirCalc>, ) -> Number

Port of IpMonotoneMuUpdate.cpp:UpdateBarrierParameter. Reduces μ only while the barrier-subproblem error is below barrier_tol_factor · μ (or a tiny step was just detected). Each successful reduction also refreshes curr_tau and the new μ in data. Returns the post-update μ.

A reduction also raises IpoptData::request_ls_reset, which the main loop turns into the linesearch_->Reset() upstream issues at IpMonotoneMuUpdate.cpp:165. This is the same behaviour the caller previously inferred from “μ changed” — the loop below only ever exits with a strictly smaller μ — but the flag is now the single source of truth for both μ strategies (pounce#510).

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 = 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.
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