pub struct DebugCtx { /* private fields */ }Expand description
Live, mutable view of solver state handed to a DebugHook.
Cheap to construct (two Rc clones); every accessor borrows the
shared RefCells on demand.
Implementations§
Source§impl DebugCtx
impl DebugCtx
pub fn new(data: IpoptDataHandle, cq: IpoptCqHandle, cp: Checkpoint) -> Self
Sourcepub fn set_live_tolerance(&mut self, name: &str, value: Number)
pub fn set_live_tolerance(&mut self, name: &str, value: Number)
Stage a live convergence-tolerance change (e.g. tol,
acceptable_tol). Accumulated across all commands at one pause and
applied by the main loop after the hook returns, so the next
iteration’s convergence test uses the new value. No effect for
names outside LIVE_TOLERANCE_OPTS.
Sourcepub fn take_live_tolerances(&mut self) -> Vec<(String, Number)>
pub fn take_live_tolerances(&mut self) -> Vec<(String, Number)>
Drain the staged live-tolerance changes (main loop only).
Sourcepub fn with_status(self, status: String) -> Self
pub fn with_status(self, status: String) -> Self
Attach a solve-outcome string (used for the terminal checkpoint).
Sourcepub fn status(&self) -> Option<&str>
pub fn status(&self) -> Option<&str>
Solve outcome, present only at Checkpoint::Terminated.
Sourcepub fn snapshot(&self) -> Option<IterateSnapshot>
pub fn snapshot(&self) -> Option<IterateSnapshot>
Capture the current primal-dual state for later Self::restore.
None before the iterate is set.
Sourcepub fn restore(&mut self, snap: &IterateSnapshot)
pub fn restore(&mut self, snap: &IterateSnapshot)
Restore a previously captured snapshot: rewinds the iterate, μ, τ,
and iteration index so the next iterate() resumes from that
point. Strategy history is not rewound (see IterateSnapshot).
Sourcepub fn checkpoint(&self) -> Checkpoint
pub fn checkpoint(&self) -> Checkpoint
Which checkpoint we are paused at.
Sourcepub fn complementarity(&self) -> Number
pub fn complementarity(&self) -> Number
Average complementarity (mean slack·multiplier over all bounds) — the IPM’s “distance from the central path” gauge; should track μ.
Sourcepub fn bound_slack(&self, which: &str) -> Option<Vec<Number>>
pub fn bound_slack(&self, which: &str) -> Option<Vec<Number>>
Slacks to a bound category — x_l / x_u / s_l / s_u — i.e.
the distance of each (lower/upper-bounded) variable or inequality
slack from its bound. A small entry ⇒ that bound is near-active.
Sourcepub fn var_bounds(&self) -> Option<(Vec<Number>, Vec<Number>)>
pub fn var_bounds(&self) -> Option<(Vec<Number>, Vec<Number>)>
Full-length variable bounds in algorithm space — (x_L, x_U), each
of length n, with -∞ / +∞ in slots that have no lower / upper
bound. Reconstructed from the NLP’s reduced bound vectors
(x_l/x_u, indexed over only the bounded variables) and their
expansion matrices, so the result lines up with the x block and
with a set x / resolve seed. None in the CQ-less test context
or before the iterate exists.
These are the bounds the algorithm sees — post-scaling and after
any bound_relax_factor — which is exactly the space a box-sampled
start must live in to be a valid seed.
Sourcepub fn constraint_residuals(&self) -> Option<Vec<Residual>>
pub fn constraint_residuals(&self) -> Option<Vec<Residual>>
Per-constraint signed primal residuals at the current iterate,
equality constraints (ResidKind::Eq, c_i(x)) then inequality
constraints (ResidKind::Ineq, d_i(x) − s_i). These are the
same quantities the studio iterate-dump emits as slack, and the
largest |value| over the returned vector equals Self::inf_pr.
None only in the CQ-less test context.
Sourcepub fn dual_residuals(&self) -> Option<Vec<Residual>>
pub fn dual_residuals(&self) -> Option<Vec<Residual>>
Per-variable signed dual residuals (Lagrangian-gradient
components) at the current iterate, x-space
(ResidKind::DualX, (∇_x L)_i) then s-space
(ResidKind::DualS, (∇_s L)_i). The largest |value| over
the returned vector equals Self::inf_du. None only in the
CQ-less test context.
Sourcepub fn split_names(&self) -> Option<SplitNames>
pub fn split_names(&self) -> Option<SplitNames>
Model names for the residual index spaces, projected into the
solver’s split space (free variables, equalities, inequalities), or
None when the problem carries no names (or in the CQ-less test
context). The REPL pairs these with Residual::kind /
Residual::index to print mass_balance instead of c[3] —
closing the model-vs-index reporting gap Lee et al. (2024,
https://doi.org/10.69997/sct.147875) identify for equation-oriented
model debugging.
Sourcepub fn regularization(&self) -> Number
pub fn regularization(&self) -> Number
Primal regularization δ_w as recorded for this iteration’s info
(info_regu_x) — the value reported in the iteration table’s lg(rg)
column, reset to 0 at the start of each iteration. This is distinct
from Self::kkt’s delta_w, which reads the live perturbation
(perturbations.delta_x) applied during the inertia-correction loop;
the two can differ by timing at a given checkpoint.
Sourcepub fn ls_count(&self) -> i32
pub fn ls_count(&self) -> i32
Number of line-search trial points tried for the accepted step (1 ⇒ full step accepted first try).
Sourcepub fn kkt(&self) -> Option<KktReport>
pub fn kkt(&self) -> Option<KktReport>
KKT-factorization report for the current iteration, if a search
direction has been computed this iteration (i.e. at/after the
after_search_dir checkpoint). Combines the captured inertia with
the applied regularization and the expected inertia derived from
the multiplier dimensions. delta_w/delta_c are the live
primal/dual perturbations (perturbations.delta_x/delta_c) applied
during inertia correction — distinct from Self::regularization’s
recorded per-iteration info value (see its note).
Sourcepub fn kkt_matrix(&self) -> Option<(i32, Vec<i32>, Vec<i32>, Vec<Number>)>
pub fn kkt_matrix(&self) -> Option<(i32, Vec<i32>, Vec<i32>, Vec<Number>)>
The assembled KKT matrix triplets (dim, irn, jcn, vals) (1-based
lower triangle) for viz kkt, if captured this iteration.
Sourcepub fn rank_report(&self) -> Option<RankReport>
pub fn rank_report(&self) -> Option<RankReport>
Numerical rank diagnosis of the equality-constraint Jacobian J_c
at the current iterate. J_c is the block whose (near) rank
deficiency drives the δ_c dual regularization and wrong-inertia
signals; this assembles it densely (with the constraint scaling the
solver factorizes), runs a rank-revealing SVD, and localizes any
dependency to specific equation rows by their model name (see
crate::debug_rank). None in the CQ-less test context, when the
problem has no equality constraints, or if the SVD fails.
Unlike the structural Dulmage–Mendelsohn pass (which works on the sparsity pattern alone), this catches dependencies that are numerical — values that cancel over a structurally full-rank pattern at this point.
Sourcepub fn kkt_captured_iter(&self) -> Option<i32>
pub fn kkt_captured_iter(&self) -> Option<i32>
The outer iteration the captured KKT system / factor came from —
the previous iteration at an iter_start pause (look-back). For
labeling viz kkt / viz L with the right iteration.
Sourcepub fn kkt_l_factor(
&self,
) -> Option<(usize, Vec<usize>, Vec<i32>, Vec<i32>, Option<Vec<Number>>)>
pub fn kkt_l_factor( &self, ) -> Option<(usize, Vec<usize>, Vec<i32>, Vec<i32>, Option<Vec<Number>>)>
The LDLᵀ factor (n, perm, strict-lower l_irn/l_jcn and
optional l_vals) for viz L, if captured this iteration (i.e.
the debugger was stepping — see DebugHook::wants_kkt_capture).
Sourcepub fn block_dims(&self) -> Vec<(&'static str, usize)>
pub fn block_dims(&self) -> Vec<(&'static str, usize)>
Dimensions of every named block, in BLOCK_NAMES order.
Sourcepub fn block(&self, name: &str) -> Option<Vec<Number>>
pub fn block(&self, name: &str) -> Option<Vec<Number>>
Read a named block of the current iterate as a flat f64 vec.
Returns None for an unknown name or before the iterate is set.
Sourcepub fn delta_block(&self, name: &str) -> Option<Vec<Number>>
pub fn delta_block(&self, name: &str) -> Option<Vec<Number>>
Read a named block of the most recent search direction δ.
Sourcepub fn set_mu(&mut self, mu: Number) -> Result<(), String>
pub fn set_mu(&mut self, mu: Number) -> Result<(), String>
Overwrite the barrier parameter μ. Takes effect on the next
update_barrier_parameter consult (the monotone updater treats
it as the current value; adaptive updaters re-derive from it).
Sourcepub fn set_block(&mut self, name: &str, vals: &[Number]) -> Result<(), String>
pub fn set_block(&mut self, name: &str, vals: &[Number]) -> Result<(), String>
Overwrite an entire named block of the current iterate.
Rebuilds curr from a deep copy with a fresh vector tag, so all
tag-keyed CQ caches invalidate and downstream quantities recompute
from the new point.
No invariant enforcement. Only the dimension is checked. Mutating
the slacks (s) to ≤ 0, or the bound/inequality multipliers
(z_l/z_u/v_l/v_u) to ≤ 0, or pushing x past a bound, breaks
the interior-point feasibility invariant (s > 0, z > 0) — the next
step’s σ = z/s and fraction-to-the-boundary rule can then produce
NaN/Inf or a non-descent direction rather than erroring here. The
solver’s strategy history (filter, adaptive-μ oracle, quasi-Newton
memory) is not rewound to the mutated point either, so a resumed
solve may behave inconsistently. This is a debugging tool: “wrong”
states are allowed on purpose — it’s on the caller to keep the point
sane if they intend to continue the solve.
Auto Trait Implementations§
impl !RefUnwindSafe for DebugCtx
impl !Send for DebugCtx
impl !Sync for DebugCtx
impl !UnwindSafe for DebugCtx
impl Freeze for DebugCtx
impl Unpin for DebugCtx
impl UnsafeUnpin for DebugCtx
Blanket Implementations§
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
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