pounce_algorithm/mu/trait.rs
1//! `MuUpdate` trait — port of `IpMuUpdate.hpp`.
2
3use crate::ipopt_cq::IpoptCqHandle;
4use crate::ipopt_data::IpoptDataHandle;
5use crate::ipopt_nlp::IpoptNlp;
6use crate::kkt::pd_search_dir_calc::PdSearchDirCalc;
7use pounce_common::types::Number;
8use std::cell::RefCell;
9use std::rc::Rc;
10
11pub trait MuUpdate {
12 /// Initialize `data.curr_mu` and `data.curr_tau` before the first
13 /// iteration. Mirrors upstream's `MuUpdate::InitializeImpl`.
14 /// Default is no-op so existing implementors don't have to change.
15 fn initialize(&mut self, _data: &IpoptDataHandle) {}
16
17 /// Compute the next mu after a successful iteration. Mirrors
18 /// upstream's `MuUpdate::UpdateBarrierParameter`. Implementations
19 /// that need the iterate state (adaptive mu, oracles) read it via
20 /// the supplied handles; pure scalar reductions like
21 /// Fiacco-McCormick consult only `data.curr_mu`.
22 ///
23 /// `nlp` and `pd_search_dir` are optional handles needed by the
24 /// adaptive μ oracles that drive an affine-step / centring solve
25 /// (probing, quality-function). When either is `None` the adaptive
26 /// path silently falls back to the LOQO closed form — matching
27 /// upstream's "oracle returned no candidate" branch
28 /// (`IpAdaptiveMuUpdate.cpp:CalculateMuFromOracle:330-340`).
29 fn update_barrier_parameter(
30 &mut self,
31 data: &IpoptDataHandle,
32 cq: &IpoptCqHandle,
33 nlp: Option<&Rc<RefCell<dyn IpoptNlp>>>,
34 pd_search_dir: Option<&mut PdSearchDirCalc>,
35 ) -> Number;
36
37 /// Whether a flagged tiny step with μ unable to decrease should
38 /// terminate the algorithm with `STOP_AT_TINY_STEP`. Upstream
39 /// `IpMonotoneMuUpdate.cpp` throws `TINY_STEP_DETECTED` in exactly
40 /// that case; `IpAdaptiveMuUpdate.cpp` instead routes the tiny-step
41 /// flag through its `force_no_progress` path — it fixes μ and keeps
42 /// iterating, never self-terminating. Default `false` matches the
43 /// adaptive behaviour; `MonotoneMuUpdate` overrides to `true`.
44 fn terminates_on_tiny_step(&self) -> bool {
45 false
46 }
47}