pub trait IpoptNlp: Nlp {
Show 37 methods
// Required methods
fn x_l(&self) -> &(dyn Vector + 'static);
fn x_u(&self) -> &(dyn Vector + 'static);
fn d_l(&self) -> &(dyn Vector + 'static);
fn d_u(&self) -> &(dyn Vector + 'static);
fn px_l(&self) -> Rc<dyn Matrix>;
fn px_u(&self) -> Rc<dyn Matrix>;
fn pd_l(&self) -> Rc<dyn Matrix>;
fn pd_u(&self) -> Rc<dyn Matrix>;
// Provided methods
fn eval_counts(&self) -> [i32; 7] { ... }
fn declared_d_bounds(&self) -> Option<(Vec<f64>, Vec<f64>)> { ... }
fn declared_c_rhs(&self) -> Option<Vec<f64>> { ... }
fn adjust_variable_bounds(
&mut self,
_new_x_l: &(dyn Vector + 'static),
_new_x_u: &(dyn Vector + 'static),
_new_d_l: &(dyn Vector + 'static),
_new_d_u: &(dyn Vector + 'static),
) { ... }
fn get_starting_x(&mut self, _x: &mut (dyn Vector + 'static)) -> bool { ... }
fn prepare_warm_start(&mut self) -> bool { ... }
fn finish_warm_start(&mut self) { ... }
fn get_starting_y(
&mut self,
_y_c: &mut (dyn Vector + 'static),
_y_d: &mut (dyn Vector + 'static),
) -> bool { ... }
fn get_starting_z(
&mut self,
_z_l: &mut (dyn Vector + 'static),
_z_u: &mut (dyn Vector + 'static),
_v_l: &mut (dyn Vector + 'static),
_v_u: &mut (dyn Vector + 'static),
) -> bool { ... }
fn lift_x_to_full(&self, x: &(dyn Vector + 'static)) -> Vec<f64> { ... }
fn finalize_solution_x(&self, x: &(dyn Vector + 'static)) -> Vec<f64> { ... }
fn pack_lambda_for_user(
&self,
_y_c: &(dyn Vector + 'static),
_y_d: &(dyn Vector + 'static),
) -> Vec<f64> { ... }
fn pack_g_for_user(
&self,
_c: &(dyn Vector + 'static),
_d: &(dyn Vector + 'static),
) -> Vec<f64> { ... }
fn pack_z_l_for_user(&self, _z_l: &(dyn Vector + 'static)) -> Vec<f64> { ... }
fn pack_z_u_for_user(&self, _z_u: &(dyn Vector + 'static)) -> Vec<f64> { ... }
fn n_full_x(&self) -> i32 { ... }
fn n_full_g(&self) -> i32 { ... }
fn finalize_solution_lambda(
&self,
_y_c: &(dyn Vector + 'static),
_y_d: &(dyn Vector + 'static),
) -> Vec<f64> { ... }
fn finalize_solution_z_l(&self, _z_l: &(dyn Vector + 'static)) -> Vec<f64> { ... }
fn finalize_solution_z_u(&self, _z_u: &(dyn Vector + 'static)) -> Vec<f64> { ... }
fn full_x_to_var_x(&self, full_idx: i32) -> Option<i32> { ... }
fn full_g_to_c_block(&self, full_idx: i32) -> Option<i32> { ... }
fn var_x_to_full_x(&self, var_idx: i32) -> i32 { ... }
fn obj_scaling_factor(&self) -> f64 { ... }
fn computed_obj_scaling_factor(&self) -> f64 { ... }
fn c_scale_vec(&self) -> Option<Vec<f64>> { ... }
fn d_scale_vec(&self) -> Option<Vec<f64>> { ... }
fn variable_scaling(&self) -> Option<Vec<f64>> { ... }
fn split_space_names(&self) -> Option<SplitNames> { ... }
}Expand description
Algorithm-side NLP (adds scaling-aware variants and provides the
bound expansion matrices Px_L, Px_U, Pd_L, Pd_U). Mirrors
upstream Ipopt::IpoptNLP.
Required Methods§
fn x_l(&self) -> &(dyn Vector + 'static)
fn x_u(&self) -> &(dyn Vector + 'static)
fn d_l(&self) -> &(dyn Vector + 'static)
fn d_u(&self) -> &(dyn Vector + 'static)
Sourcefn px_l(&self) -> Rc<dyn Matrix>
fn px_l(&self) -> Rc<dyn Matrix>
Bound expansion matrices: Px_L extracts the
x components that have a finite lower bound, etc.
fn px_u(&self) -> Rc<dyn Matrix>
fn pd_l(&self) -> Rc<dyn Matrix>
fn pd_u(&self) -> Rc<dyn Matrix>
Provided Methods§
Sourcefn eval_counts(&self) -> [i32; 7]
fn eval_counts(&self) -> [i32; 7]
Per-evaluation call counts accumulated over the solve, ordered
[f, grad_f, c, d, jac_c, jac_d, h]. Populates the end-of-run
summary’s evaluation tallies (#206). Default is all zeros for
implementors that do not count; [OrigIpoptNlp] reports its live
counters.
Sourcefn declared_d_bounds(&self) -> Option<(Vec<f64>, Vec<f64>)>
fn declared_d_bounds(&self) -> Option<(Vec<f64>, Vec<f64>)>
The declared compressed inequality bounds (d_L, d_U), in the same
(internally scaled) space as Self::d_l / Self::d_u but without
the bound_relax_factor widening or safe-slack adjustments the live
vectors carry. The scale-relative feasibility measure keys row
magnitudes off these: on the live vector a relaxed zero bound reads as
~1e-8, fabricating a magnitude for a row that has none. None (the
default) means “not tracked” — callers should fall back to the live
bounds.
Sourcefn declared_c_rhs(&self) -> Option<Vec<f64>>
fn declared_c_rhs(&self) -> Option<Vec<f64>>
The declared equality right-hand sides b — the pre-fold constants
subtracted to turn g_i(x) == b_i into the algorithm’s residual
c_i(x) = 0 — reported in the same (internally scaled) space as
Nlp::eval_c’s output, so |c_i| / |b_i| is a pure ratio.
The fold is exactly what erases the row’s magnitude: |c_i| is the
violation and carries no independent scale, so a scale-relative
feasibility measure has nothing to divide by unless the RHS is plumbed
back. Same “declared, not live” contract as Self::declared_d_bounds:
the value is the one the user wrote (times any row scaling the solver
itself applied), never a relaxed or otherwise adjusted stand-in.
None (the default) means “not tracked” — callers must then abstain
from any relative verdict on the c block rather than substitute a
magnitude of their own.
Sourcefn adjust_variable_bounds(
&mut self,
_new_x_l: &(dyn Vector + 'static),
_new_x_u: &(dyn Vector + 'static),
_new_d_l: &(dyn Vector + 'static),
_new_d_u: &(dyn Vector + 'static),
)
fn adjust_variable_bounds( &mut self, _new_x_l: &(dyn Vector + 'static), _new_x_u: &(dyn Vector + 'static), _new_d_l: &(dyn Vector + 'static), _new_d_u: &(dyn Vector + 'static), )
Replace the x_L / x_U / d_L / d_U bounds in place. Invoked by the
algorithm’s accept step when the safe-slack mechanism moved one or
more bounds (port of IpoptNLP::AdjustVariableBounds,
IpOrigIpoptNLP.cpp:990-1001). Default is a no-op for NLP
implementations that do not own mutable bound storage.
Sourcefn get_starting_x(&mut self, _x: &mut (dyn Vector + 'static)) -> bool
fn get_starting_x(&mut self, _x: &mut (dyn Vector + 'static)) -> bool
Fill x with the initial primal values (mirrors upstream
IpoptNLP::GetStartingPoint’s init_x flag). Default impl
leaves x at its current contents (typically the zero vector
produced by make_new).
Sourcefn prepare_warm_start(&mut self) -> bool
fn prepare_warm_start(&mut self) -> bool
Prepare a complete primal-dual starting-point snapshot for a warm start. The default is a no-op for NLP implementations that do not route through a TNLP callback.
The warm-start initializer calls this once before its separate
get_starting_x / get_starting_y / get_starting_z projections.
Implementations can therefore fetch all requested data in one callback,
matching Ipopt’s single GetStartingPoint call.
Sourcefn finish_warm_start(&mut self)
fn finish_warm_start(&mut self)
Release any temporary state prepared for the warm-start projections.
Called once the initializer has obtained its x, y, and z blocks.
The default is a no-op; adapters that cache a TNLP callback payload use
this to keep that snapshot scoped to one initialization only.
Sourcefn get_starting_y(
&mut self,
_y_c: &mut (dyn Vector + 'static),
_y_d: &mut (dyn Vector + 'static),
) -> bool
fn get_starting_y( &mut self, _y_c: &mut (dyn Vector + 'static), _y_d: &mut (dyn Vector + 'static), ) -> bool
Fill y_c / y_d with initial multiplier guesses (mirrors
IpoptNLP::GetStartingPoint’s init_lambda flag). Default
impl leaves them at their current contents (zeros).
Sourcefn get_starting_z(
&mut self,
_z_l: &mut (dyn Vector + 'static),
_z_u: &mut (dyn Vector + 'static),
_v_l: &mut (dyn Vector + 'static),
_v_u: &mut (dyn Vector + 'static),
) -> bool
fn get_starting_z( &mut self, _z_l: &mut (dyn Vector + 'static), _z_u: &mut (dyn Vector + 'static), _v_l: &mut (dyn Vector + 'static), _v_u: &mut (dyn Vector + 'static), ) -> bool
Fill z_l / z_u / v_l / v_u with initial bound-multiplier
guesses (mirrors init_z). Default impl leaves them at zeros.
Sourcefn lift_x_to_full(&self, x: &(dyn Vector + 'static)) -> Vec<f64>
fn lift_x_to_full(&self, x: &(dyn Vector + 'static)) -> Vec<f64>
Lift a compressed x_var (length n_x_var) to the full-x
length (n_full_x = user TNLP’s n), splicing fixed-variable
values back in. Used at finalize-solution time to hand the user
a full-length x. Default impl returns x as-is, valid when the
problem has no fixed variables.
Sourcefn finalize_solution_x(&self, x: &(dyn Vector + 'static)) -> Vec<f64>
fn finalize_solution_x(&self, x: &(dyn Vector + 'static)) -> Vec<f64>
The full-x to hand TNLP::finalize_solution: Self::lift_x_to_full,
plus whatever the reported point owes the user that the working
iterate does not — today, the honor_original_bounds projection
back into the declared box (the bound_relax_factor widening
otherwise reports a bound-pinned solution just outside its own
bounds). Default impl is lift_x_to_full; OrigIpoptNlp
overrides.
Sourcefn pack_lambda_for_user(
&self,
_y_c: &(dyn Vector + 'static),
_y_d: &(dyn Vector + 'static),
) -> Vec<f64>
fn pack_lambda_for_user( &self, _y_c: &(dyn Vector + 'static), _y_d: &(dyn Vector + 'static), ) -> Vec<f64>
Pack the algorithm-side (y_c, y_d) constraint multipliers into
the user TNLP’s lambda array (length n_full_g, ordered by
the original g index). Used by GetIpoptCurrentIterate and
finalize_solution. Default impl returns an empty vector — the
canonical OrigIpoptNlp implementation overrides it to perform
the c/d-split inverse and scaling unwind.
Sourcefn pack_g_for_user(
&self,
_c: &(dyn Vector + 'static),
_d: &(dyn Vector + 'static),
) -> Vec<f64>
fn pack_g_for_user( &self, _c: &(dyn Vector + 'static), _d: &(dyn Vector + 'static), ) -> Vec<f64>
Pack the algorithm-side (c, d) constraint values into the user
TNLP’s g array (length n_full_g, ordered by the original g
index, in user-unscaled space). Default impl returns an empty
vector; OrigIpoptNlp overrides.
Sourcefn pack_z_l_for_user(&self, _z_l: &(dyn Vector + 'static)) -> Vec<f64>
fn pack_z_l_for_user(&self, _z_l: &(dyn Vector + 'static)) -> Vec<f64>
Expand a compressed lower-bound-multiplier vector
(length = number of finite-lower-bound free variables) into the
user TNLP’s full-n length z_L array. Default impl returns an
empty vector; OrigIpoptNlp overrides.
Sourcefn pack_z_u_for_user(&self, _z_u: &(dyn Vector + 'static)) -> Vec<f64>
fn pack_z_u_for_user(&self, _z_u: &(dyn Vector + 'static)) -> Vec<f64>
Expand a compressed upper-bound-multiplier vector into the user
TNLP’s full-n length z_U array. Default impl returns an
empty vector; OrigIpoptNlp overrides.
Sourcefn n_full_x(&self) -> i32
fn n_full_x(&self) -> i32
Number of variables n as the user TNLP declared it (= n_full_x,
before fixed-variable elimination). Used by inspector entry
points that need to size full-n buffers. Default impl returns
0; OrigIpoptNlp overrides.
Sourcefn n_full_g(&self) -> i32
fn n_full_g(&self) -> i32
Number of constraints m as the user TNLP declared it (= n_full_g).
Default impl returns 0; OrigIpoptNlp overrides.
Sourcefn finalize_solution_lambda(
&self,
_y_c: &(dyn Vector + 'static),
_y_d: &(dyn Vector + 'static),
) -> Vec<f64>
fn finalize_solution_lambda( &self, _y_c: &(dyn Vector + 'static), _y_d: &(dyn Vector + 'static), ) -> Vec<f64>
Lift the algorithm-side (y_c, y_d) multipliers back to the
user TNLP’s lambda array (length m_full = n_c + n_d),
matching upstream IpOrigIpoptNLP::FinalizeSolution. Sibling
to pack_lambda_for_user; added by pounce#11 for the
finalize_solution path. Default returns empty; OrigIpoptNlp
overrides.
Sourcefn finalize_solution_z_l(&self, _z_l: &(dyn Vector + 'static)) -> Vec<f64>
fn finalize_solution_z_l(&self, _z_l: &(dyn Vector + 'static)) -> Vec<f64>
Lift compressed z_l back to full-x. Sibling to
pack_z_l_for_user; added by pounce#11. Default returns empty.
Sourcefn finalize_solution_z_u(&self, _z_u: &(dyn Vector + 'static)) -> Vec<f64>
fn finalize_solution_z_u(&self, _z_u: &(dyn Vector + 'static)) -> Vec<f64>
Lift compressed z_u back to full-x. Sibling to
pack_z_u_for_user; added by pounce#11. Default returns empty.
Sourcefn full_x_to_var_x(&self, full_idx: i32) -> Option<i32>
fn full_x_to_var_x(&self, full_idx: i32) -> Option<i32>
Map a 0-based full-x index (user-TNLP space, length
n_full_x()) to a 0-based var-x index (algorithm-side,
length n()). Returns None when the variable was eliminated
because x_l[i] == x_u[i] under
fixed_variable_treatment = make_parameter.
Default impl assumes no fixed variables (identity mapping). The
OrigIpoptNlp implementation consults
BoundClassification::full_to_var.
Sourcefn full_g_to_c_block(&self, full_idx: i32) -> Option<i32>
fn full_g_to_c_block(&self, full_idx: i32) -> Option<i32>
Map a 0-based full-g index (user-TNLP space, length
n_full_g()) to a 0-based position in the c-block (algorithm-side
equality multiplier vector y_c, length m_eq()). Returns
None when the constraint is an inequality (lives in d, not
c).
Default impl assumes the c-block matches the user’s g order
(no c/d split); OrigIpoptNlp overrides via
BoundClassification::c_map.
Sourcefn var_x_to_full_x(&self, var_idx: i32) -> i32
fn var_x_to_full_x(&self, var_idx: i32) -> i32
Inverse of Self::full_x_to_var_x: map a 0-based var-x index
(length n()) to the corresponding full-x index (length
n_full_x()). Used when scattering a compressed step or
iterate back into the user’s full-x array.
Default impl assumes no fixed variables (identity); OrigIpoptNlp
returns classification.x_not_fixed_map[var_idx].
Sourcefn obj_scaling_factor(&self) -> f64
fn obj_scaling_factor(&self) -> f64
Effective objective scaling factor (df_ upstream): the value
f is multiplied by inside [Self::eval_f]. Used to recover the
unscaled objective for display. Default 1.0 (no scaling);
OrigIpoptNlp overrides.
Sourcefn computed_obj_scaling_factor(&self) -> f64
fn computed_obj_scaling_factor(&self) -> f64
The solver-computed part of the objective scale, before the user’s
constant obj_scaling_factor is multiplied in.
Self::obj_scaling_factor returns the product df * user_factor,
which is the right thing for unscaling a residual but the wrong thing
for asking why the scale is small. df is what gradient-based scaling
computed and clamped at nlp_scaling_min_value; the user factor is a
deliberate choice. Only the former can mask a certificate (gh #200), so
the termination logic keys on this rather than on the product.
Default 1.0; OrigIpoptNlp overrides.
Sourcefn c_scale_vec(&self) -> Option<Vec<f64>>
fn c_scale_vec(&self) -> Option<Vec<f64>>
Per-row scaling vector for the equality block (dc_ upstream):
the factor each c row is multiplied by inside [Self::eval_c]
/ [Self::eval_jac_c]. None ⇔ no row scaling (all 1.0);
length m_eq() when present. Together with
Self::obj_scaling_factor and Self::d_scale_vec this is
what lets pounce-sensitivity undo the NLP scaling baked into
the converged KKT factor (pounce#128). Default None;
OrigIpoptNlp overrides.
Sourcefn d_scale_vec(&self) -> Option<Vec<f64>>
fn d_scale_vec(&self) -> Option<Vec<f64>>
Per-row scaling vector for the inequality block (dd_
upstream), same convention as Self::c_scale_vec. Length
m_ineq() when present. Default None; OrigIpoptNlp
overrides.
Sourcefn variable_scaling(&self) -> Option<Vec<f64>>
fn variable_scaling(&self) -> Option<Vec<f64>>
The per-variable factors d a scaling wrapper below this NLP
applied as a change of variables x̃ = d ⊙ x (gh#486). None
⇔ no variable scaling; length Self::n_full_x when present,
i.e. the full-x space of the TNLP that was submitted, before
fixed variables were dropped.
This is the x-axis counterpart of Self::obj_scaling_factor /
Self::c_scale_vec / Self::d_scale_vec, and it exists for
the same reason: a consumer reading the converged KKT system
rather than the finalize_solution payload is looking at x̃,
not x, and needs the factors to say so. Unlike the other
three, the substitution happens below the NLP — in
ScalingTnlp — so this only forwards what the TNLP reports.
Default None; OrigIpoptNlp overrides.
Sourcefn split_space_names(&self) -> Option<SplitNames>
fn split_space_names(&self) -> Option<SplitNames>
Human-readable variable / constraint names projected into the
algorithm’s split space (free variables, equalities, inequalities),
or None when the model carries no names. The debugger uses this to
label residuals by model name (mass_balance) rather than index
(c[3]) — see SplitNames and Lee et al. (2024,
https://doi.org/10.69997/sct.147875).
Default returns None; OrigIpoptNlp overrides by pulling
idx_names metadata from the underlying TNLP and composing it with
the bound / c-d-split permutations.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".