use crate::core::ExitStatus;
use num::Float;
#[derive(Debug)]
pub struct AlmOptimizerStatus<T = f64>
where
T: Float,
{
exit_status: ExitStatus,
num_outer_iterations: usize,
num_inner_iterations: usize,
last_problem_norm_fpr: T,
lagrange_multipliers: Option<Vec<T>>,
solve_time: std::time::Duration,
penalty: T,
delta_y_norm: T,
f2_norm: T,
cost: T,
}
impl<T: Float> AlmOptimizerStatus<T> {
pub(crate) fn new(exit_status: ExitStatus) -> Self {
AlmOptimizerStatus {
exit_status,
num_outer_iterations: 0,
num_inner_iterations: 0,
last_problem_norm_fpr: -T::one(),
lagrange_multipliers: None,
solve_time: std::time::Duration::from_nanos(0),
penalty: T::zero(),
delta_y_norm: T::zero(),
f2_norm: T::zero(),
cost: T::zero(),
}
}
pub(crate) fn with_solve_time(mut self, duration: std::time::Duration) -> Self {
self.solve_time = duration;
self
}
pub(crate) fn with_outer_iterations(mut self, outer_iters: usize) -> Self {
self.num_outer_iterations = outer_iters;
self
}
pub(crate) fn with_inner_iterations(mut self, inner_iters: usize) -> Self {
self.num_inner_iterations = inner_iters;
self
}
pub(crate) fn with_lagrange_multipliers(mut self, lagrange_multipliers: &[T]) -> Self {
self.lagrange_multipliers = Some(vec![]);
if let Some(y) = &mut self.lagrange_multipliers {
y.extend_from_slice(lagrange_multipliers);
}
self
}
pub(crate) fn with_penalty(mut self, penalty: T) -> Self {
assert!(
penalty >= T::zero(),
"the penalty parameter should not be negative"
);
self.penalty = penalty;
self
}
pub(crate) fn with_last_problem_norm_fpr(mut self, last_problem_norm_fpr: T) -> Self {
assert!(
last_problem_norm_fpr >= T::zero(),
"last_problem_norm_fpr should not be negative"
);
self.last_problem_norm_fpr = last_problem_norm_fpr;
self
}
pub(crate) fn with_delta_y_norm(mut self, delta_y_norm: T) -> Self {
assert!(
delta_y_norm >= T::zero(),
"delta_y_norm must be nonnegative"
);
self.delta_y_norm = delta_y_norm;
self
}
pub(crate) fn with_f2_norm(mut self, f2_norm: T) -> Self {
assert!(f2_norm >= T::zero(), "f2_norm must be nonnegative");
self.f2_norm = f2_norm;
self
}
pub(crate) fn with_cost(mut self, cost: T) -> Self {
self.cost = cost;
self
}
pub fn update_cost(&mut self, new_cost: T) {
self.cost = new_cost;
}
pub fn update_f1_infeasibility(&mut self, new_alm_infeasibility: T) {
self.delta_y_norm = new_alm_infeasibility;
}
pub fn update_f2_norm(&mut self, new_pm_infeasibility: T) {
self.f2_norm = new_pm_infeasibility;
}
pub fn exit_status(&self) -> ExitStatus {
self.exit_status
}
pub fn num_outer_iterations(&self) -> usize {
self.num_outer_iterations
}
pub fn num_inner_iterations(&self) -> usize {
self.num_inner_iterations
}
pub fn lagrange_multipliers(&self) -> &Option<Vec<T>> {
&self.lagrange_multipliers
}
pub fn last_problem_norm_fpr(&self) -> T {
self.last_problem_norm_fpr
}
pub fn solve_time(&self) -> std::time::Duration {
self.solve_time
}
pub fn penalty(&self) -> T {
self.penalty
}
pub fn delta_y_norm_over_c(&self) -> T {
let c = self.penalty();
self.delta_y_norm / if c < T::one() { T::one() } else { c }
}
pub fn f2_norm(&self) -> T {
self.f2_norm
}
pub fn cost(&self) -> T {
self.cost
}
}