use crate::iterates_vector::IteratesVector;
use pounce_common::timing::TimingStatistics;
use pounce_common::types::{Index, Number};
use pounce_linalg::SymMatrix;
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug, Default, Clone, Copy)]
pub struct PdPerturbations {
pub delta_x: Number,
pub delta_s: Number,
pub delta_c: Number,
pub delta_d: Number,
}
#[derive(Clone, Debug, Default)]
pub struct KktDebug {
pub iter: i32,
pub dim: i32,
pub n_neg: i32,
pub provides_inertia: bool,
pub status: String,
pub matrix: Option<(i32, Vec<i32>, Vec<i32>, Vec<f64>)>,
pub l_factor: Option<pounce_linsol::FactorPattern>,
}
pub struct IpoptData {
pub curr: Option<IteratesVector>,
pub trial: Option<IteratesVector>,
pub delta: Option<IteratesVector>,
pub delta_aff: Option<IteratesVector>,
pub delta_cen: Option<IteratesVector>,
pub w: Option<Rc<dyn SymMatrix>>,
pub iter_count: Index,
pub curr_mu: Number,
pub curr_tau: Number,
pub tol: Number,
pub perturbations: PdPerturbations,
pub kkt_debug: Option<KktDebug>,
pub info_alpha_primal: Number,
pub info_alpha_dual: Number,
pub info_regu_x: Number,
pub info_skip_output: bool,
pub info_string: String,
pub tiny_step_flag: bool,
pub request_resto: bool,
pub info_alpha_primal_char: char,
pub info_ls_count: Index,
pub info_last_output: Number,
pub info_iters_since_header: Index,
pub timing: Rc<TimingStatistics>,
}
impl Default for IpoptData {
fn default() -> Self {
Self::new()
}
}
impl IpoptData {
pub fn new() -> Self {
Self {
curr: None,
trial: None,
delta: None,
delta_aff: None,
delta_cen: None,
w: None,
iter_count: 0,
curr_mu: 0.1,
curr_tau: 0.99,
tol: 1e-8,
perturbations: PdPerturbations::default(),
kkt_debug: None,
info_alpha_primal: 0.0,
info_alpha_dual: 0.0,
info_regu_x: 0.0,
info_skip_output: false,
info_string: String::new(),
tiny_step_flag: false,
request_resto: false,
info_alpha_primal_char: ' ',
info_ls_count: 0,
info_last_output: -1.0,
info_iters_since_header: 0,
timing: Rc::new(TimingStatistics::new()),
}
}
pub fn append_info_string(&mut self, s: &str) {
self.info_string.push_str(s);
}
pub fn reset_info(&mut self) {
self.info_string.clear();
self.info_skip_output = false;
self.info_alpha_primal_char = ' ';
self.info_ls_count = 0;
self.info_regu_x = 0.0;
}
pub fn accept_trial_point(&mut self) {
self.curr = self.trial.take();
}
pub fn set_trial(&mut self, trial: IteratesVector) {
self.trial = Some(trial);
}
pub fn set_curr(&mut self, curr: IteratesVector) {
self.curr = Some(curr);
}
pub fn set_delta(&mut self, d: IteratesVector) {
self.delta = Some(d);
}
pub fn set_delta_aff(&mut self, d: IteratesVector) {
self.delta_aff = Some(d);
}
pub fn set_delta_cen(&mut self, d: IteratesVector) {
self.delta_cen = Some(d);
}
}
pub type IpoptDataHandle = Rc<RefCell<IpoptData>>;
#[cfg(test)]
mod tests {
use super::*;
use crate::iterates_vector::IteratesVector;
use pounce_linalg::dense_vector::DenseVectorSpace;
use pounce_linalg::Vector;
use std::rc::Rc as StdRc;
fn zero_iv() -> IteratesVector {
let z = |n| StdRc::new(DenseVectorSpace::new(n).make_new_dense()) as StdRc<dyn Vector>;
IteratesVector::new(z(2), z(1), z(1), z(1), z(2), z(2), z(1), z(1))
}
#[test]
fn accept_trial_point_promotes_trial_to_curr() {
let mut d = IpoptData::new();
d.set_trial(zero_iv());
assert!(d.curr.is_none());
d.accept_trial_point();
assert!(d.curr.is_some());
assert!(d.trial.is_none());
}
}