pub struct PdSensBacksolver { /* private fields */ }Expand description
Adapter from PdFullSpaceSolver to SensBacksolver. Holds
owning clones of the four pieces of the algorithm’s converged
state, plus the 8-block iterate template used to allocate fresh
RHS / LHS vectors.
The PD solver lives behind an Rc<RefCell<…>> because
SensBacksolver::solve is &self but the upstream signature
for PdFullSpaceSolver::solve is &mut self (it caches the
last-solve dependency tags and the augsys-improved flag). The
RefCell is single-thread-only, single-borrow, exactly matching
the call pattern from pounce-sensitivity’s pipeline.
Owning (rather than borrowing) the four handles is what lets a
PdSensBacksolver outlive the on_converged callback frame —
required by the public Solver session API in pounce-algorithm,
which retains the backsolver for repeated parametric_step /
kkt_solve / compute_reduced_hessian calls after the IPM has
returned. The data, cq, and nlp handles are already
Rc<RefCell<…>> cheap-clone handles upstream, so this carries no
allocation overhead.
Implementations§
Source§impl PdSensBacksolver
impl PdSensBacksolver
Sourcepub fn new(
data: &IpoptDataHandle,
cq: &IpoptCqHandle,
nlp: &Rc<RefCell<dyn IpoptNlp>>,
pd: Rc<RefCell<PdFullSpaceSolver>>,
) -> Result<Self, String>
pub fn new( data: &IpoptDataHandle, cq: &IpoptCqHandle, nlp: &Rc<RefCell<dyn IpoptNlp>>, pd: Rc<RefCell<PdFullSpaceSolver>>, ) -> Result<Self, String>
Construct from the four handles handed in by the on_converged
callback. Errors if data has no curr (i.e. the algorithm
never reached an iterate — should not happen on
SolveSucceeded) or the NLP reports scaling data inconsistent
with the converged iterate (see Self::natural_units_conj).
Sourcepub fn obj_scaling_factor(&self) -> Number
pub fn obj_scaling_factor(&self) -> Number
Effective objective scaling factor df of the converged NLP
(1.0 when no scaling is active).
Sourcepub fn nlp_scaling(&self) -> (Number, Option<Vec<Number>>, Option<Vec<Number>>)
pub fn nlp_scaling(&self) -> (Number, Option<Vec<Number>>, Option<Vec<Number>>)
Effective NLP scaling at convergence:
(obj_scaling_factor, c_scale, d_scale). The vectors are
None when the corresponding block carries no row scaling.
Sourcepub fn kkt_perturbations(&self) -> [Number; 4]
pub fn kkt_perturbations(&self) -> [Number; 4]
Inertia-correction perturbations (δ_x, δ_s, δ_c, δ_d) baked
into the held KKT factor (the IPM’s current_perturbation
state at convergence). All zero ⇔ the final factorization was
unregularized and the natural-units back-solves invert the
exact KKT matrix. Nonzero ⇔ the factor carries a (scaled-space)
regularization, so sensitivity outputs — covariance in
particular — are perturbed and no longer exactly
scaling-invariant; consumers should check this before trusting
-inv(reduced_hessian) on ill-conditioned problems
(pounce#128 follow-up).
Sourcepub fn pin_rows_and_c_scales(
&self,
pin_g_indices: &[Index],
) -> Result<(Vec<Index>, Vec<Number>), String>
pub fn pin_rows_and_c_scales( &self, pin_g_indices: &[Index], ) -> Result<(Vec<Index>, Vec<Number>), String>
Map user-facing 0-based g(x) indices of parameter-pin
equality constraints to flat KKT rows and the pin rows’
dc_i scaling factors, in one pass. The KKT row of pin i is
n_x + n_s + c_block_idx, i.e. the matching y_c slot, found
through IpoptNlp::full_g_to_c_block so the c/d split’s row
permutation is honored (pounce#128 follow-up: the previous
direct n_x + n_s + g_idx mapping silently picked wrong rows
when inequalities preceded the pins). The scales are 1.0 when
no constraint scaling is active; they relate the natural and
solver-space reduced Hessians via
H̃_ij = (df / (dc_i·dc_j)) · H_ij. Errors when a pin index
is out of range or refers to an inequality row.
Sourcepub fn map_pin_g_to_kkt_rows(
&self,
pin_g_indices: &[Index],
) -> Result<Vec<Index>, String>
pub fn map_pin_g_to_kkt_rows( &self, pin_g_indices: &[Index], ) -> Result<Vec<Index>, String>
KKT-row half of Self::pin_rows_and_c_scales.
Sourcepub fn pin_c_scales(
&self,
pin_g_indices: &[Index],
) -> Result<Vec<Number>, String>
pub fn pin_c_scales( &self, pin_g_indices: &[Index], ) -> Result<Vec<Number>, String>
Scaling half of Self::pin_rows_and_c_scales.
Sourcepub fn block_dims(&self) -> [usize; 8]
pub fn block_dims(&self) -> [usize; 8]
Block dimensions of the compound KKT vector at convergence, in
(x, s, y_c, y_d, z_l, z_u, v_l, v_u) order. Sum equals
SensBacksolver::dim. Useful when a caller needs to compute
the flat offset of a non-x block (e.g. n_x + n_s for the
start of the equality-multiplier y_c block).
Sourcepub fn full_g_to_c_block(&self, full_idx: Index) -> Option<Index>
pub fn full_g_to_c_block(&self, full_idx: Index) -> Option<Index>
Map a 0-based full-g index (user-TNLP g(x) order) to its
0-based position in the equality-multiplier y_c block, or
None when the constraint is an inequality (it lives in the d
block, not y_c). Delegates to the held NLP’s c/d-split map.
Pin-row construction must route through this: the flat KKT row of
a pinned equality is n_x + n_s + full_g_to_c_block(g), NOT
n_x + n_s + g — those differ whenever any inequality precedes
the pinned equality in g(x).
Source§impl PdSensBacksolver
impl PdSensBacksolver
Sourcepub fn solve_many(
&self,
rhs_flat: &[Number],
lhs_flat: &mut [Number],
n_rhs: usize,
) -> bool
pub fn solve_many( &self, rhs_flat: &[Number], lhs_flat: &mut [Number], n_rhs: usize, ) -> bool
Batched-RHS back-solve over the held factor. rhs_flat and
lhs_flat are row-major (n_rhs, dim) buffers. Equivalent to
looping SensBacksolver::solve over each row but reuses one
frozen IteratesVector for the RHS and one IteratesVectorMut
for the result across all n_rhs calls into
PdFullSpaceSolver::solve. The pack step writes into the
existing DenseVector storage via Rc::get_mut +
set_values, and the unpack step reads it back via values()
/scalar() — skipping the per-call 8-block make_new_zeroed
(Box alloc) in pack and the per-block expanded_values() Vec
alloc in unpack that otherwise dominate the held-factor
back-solve cost under jax.jacrev over a JaxProblem solve
(pounce#77 follow-up).
The matrix and perturbation state inside PdFullSpaceSolver
are unchanged across calls, so each iteration hits the cached
fast path in solve_once (uptodate && !pretend_singular).
Like SensBacksolver::solve, results are in natural
(unscaled) units — see Self::solve_many_scaled_space for
the raw solver-space back-solve.
Sourcepub fn solve_many_scaled_space(
&self,
rhs_flat: &[Number],
lhs_flat: &mut [Number],
n_rhs: usize,
) -> bool
pub fn solve_many_scaled_space( &self, rhs_flat: &[Number], lhs_flat: &mut [Number], n_rhs: usize, ) -> bool
Batched-RHS back-solve against the held factor in the solver’s
internal scaled space (no natural-units conjugation). Same
buffer contract as Self::solve_many.
Source§impl PdSensBacksolver
impl PdSensBacksolver
Sourcepub fn solve_scaled_space(&self, rhs: &[Number], lhs: &mut [Number]) -> bool
pub fn solve_scaled_space(&self, rhs: &[Number], lhs: &mut [Number]) -> bool
Single-RHS back-solve against the held factor in the solver’s
internal scaled space (no natural-units conjugation). This
is the value SensBacksolver::solve returned before
pounce#128; kept for callers that want the raw factor.
Trait Implementations§
Source§impl Clone for PdSensBacksolver
impl Clone for PdSensBacksolver
Source§fn clone(&self) -> PdSensBacksolver
fn clone(&self) -> PdSensBacksolver
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl SensBacksolver for PdSensBacksolver
impl SensBacksolver for PdSensBacksolver
Source§fn solve(&self, rhs: &[Number], lhs: &mut [Number]) -> bool
fn solve(&self, rhs: &[Number], lhs: &mut [Number]) -> bool
Solve K · lhs = rhs against the converged factor, in
natural (unscaled) units (pounce#128): when the NLP carries
active scaling (nlp_scaling_method, obj_scaling_factor,
user scaling) the RHS is pre-multiplied by E and the result
post-multiplied by F (see the conj field doc), so
lhs = K_natural⁻¹ rhs for all eight blocks — including
the z/v bound-multiplier rows. Use
Self::solve_scaled_space for the raw factor.
Auto Trait Implementations§
impl !RefUnwindSafe for PdSensBacksolver
impl !Send for PdSensBacksolver
impl !Sync for PdSensBacksolver
impl !UnwindSafe for PdSensBacksolver
impl Freeze for PdSensBacksolver
impl Unpin for PdSensBacksolver
impl UnsafeUnpin for PdSensBacksolver
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
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