use pounce_common::types::{Index, Number};
#[derive(Debug, Default, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct IterRecord {
pub iter: Index,
pub objective: Number,
pub inf_pr: Number,
#[cfg_attr(feature = "serde", serde(default))]
pub inf_pr_internal: Number,
pub inf_du: Number,
pub mu: Number,
pub d_norm: Number,
pub regularization: Number,
pub alpha_dual: Number,
pub alpha_primal: Number,
pub alpha_primal_char: char,
pub ls_trials: Index,
#[cfg_attr(feature = "serde", serde(default))]
pub phase: IterPhase,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum IterPhase {
#[default]
Main,
Restoration,
}
impl IterPhase {
pub fn as_str(self) -> &'static str {
match self {
IterPhase::Main => "main",
IterPhase::Restoration => "restoration",
}
}
pub fn from_name(name: &str) -> Self {
match name {
"restoration" => IterPhase::Restoration,
_ => IterPhase::Main,
}
}
}
#[derive(Debug, Clone, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SolvePassRecord {
#[cfg_attr(feature = "serde", serde(default))]
pub rho: Option<Number>,
pub iterations: Index,
#[cfg_attr(feature = "serde", serde(default))]
pub first_row: usize,
#[cfg_attr(feature = "serde", serde(default))]
pub slack_sum: Option<Number>,
#[cfg_attr(feature = "serde", serde(default))]
pub constraint_violation: Option<Number>,
#[cfg_attr(feature = "serde", serde(default))]
pub status: String,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SolveStatistics {
pub iteration_count: Index,
pub total_cpu_time_secs: Number,
pub total_sys_time_secs: Number,
pub total_wallclock_time_secs: Number,
pub num_obj_evals: Index,
pub num_constr_evals: Index,
pub num_obj_grad_evals: Index,
pub num_constr_jac_evals: Index,
pub num_hess_evals: Index,
pub final_objective: Number,
pub final_scaled_objective: Number,
pub final_dual_inf: Number,
pub final_constr_viol: Number,
pub final_compl: Number,
pub final_kkt_error: Number,
pub final_declared_constr_viol: Number,
pub final_declared_box_viol: Number,
pub final_unscaled_dual_inf: Number,
pub final_unscaled_dual_scale: Number,
pub final_obj_scaling_factor: Number,
pub final_total_obj_scaling_factor: Number,
pub start_obj_grad_max: Number,
pub warnings: Vec<String>,
#[cfg_attr(feature = "serde", serde(skip))]
pub derivative_check: Option<crate::derivative_test::DerivativeCheckSummary>,
pub obj_scale_certificate_refused: bool,
pub obj_scale_acceptable_refused: bool,
pub final_unscaled_constr_viol: Number,
pub final_unscaled_compl: Number,
pub final_unscaled_kkt_error: Number,
pub final_kkt_error_above_noise: Number,
pub final_mu: Number,
pub fd_hessian_pattern_used: Index,
pub fd_hessian_nnz: Index,
pub fd_hessian_n: Index,
pub fd_hessian_groups: Index,
pub fd_hessian_rho_max: Index,
pub fd_hessian_coloring_fell_back: bool,
pub fd_hessian_objective_clique_widened: bool,
pub restoration_calls: Index,
pub restoration_inner_iters: Index,
pub restoration_outer_iters: Index,
pub restoration_wall_secs: Number,
pub quality_escalations: Index,
pub dual_divergence_signature: bool,
#[cfg_attr(feature = "serde", serde(default))]
pub returned_run_dual_divergence_signature: bool,
pub dual_divergence_retry_promoted: bool,
pub sqp_qp_solves: Index,
pub sqp_qp_working_set_changes: Index,
#[cfg_attr(feature = "serde", serde(default))]
pub sqp_warm_working_set_applied: bool,
pub iterations: Vec<IterRecord>,
pub passes: Vec<SolvePassRecord>,
}
impl Default for SolveStatistics {
fn default() -> Self {
Self {
iteration_count: 0,
total_cpu_time_secs: 0.0,
total_sys_time_secs: 0.0,
total_wallclock_time_secs: 0.0,
num_obj_evals: 0,
num_constr_evals: 0,
num_obj_grad_evals: 0,
num_constr_jac_evals: 0,
num_hess_evals: 0,
final_objective: Number::NAN,
final_scaled_objective: Number::NAN,
final_dual_inf: Number::NAN,
final_constr_viol: Number::NAN,
final_compl: Number::NAN,
final_kkt_error: Number::NAN,
final_unscaled_dual_inf: Number::NAN,
final_unscaled_dual_scale: Number::NAN,
final_obj_scaling_factor: Number::NAN,
final_total_obj_scaling_factor: Number::NAN,
start_obj_grad_max: Number::NAN,
warnings: Vec::new(),
derivative_check: None,
obj_scale_certificate_refused: false,
obj_scale_acceptable_refused: false,
final_declared_constr_viol: Number::NAN,
final_declared_box_viol: Number::NAN,
final_unscaled_constr_viol: Number::NAN,
final_unscaled_compl: Number::NAN,
final_unscaled_kkt_error: Number::NAN,
final_kkt_error_above_noise: Number::NAN,
final_mu: 0.0,
fd_hessian_pattern_used: -1,
fd_hessian_nnz: 0,
fd_hessian_n: 0,
fd_hessian_groups: 0,
fd_hessian_rho_max: 0,
fd_hessian_coloring_fell_back: false,
fd_hessian_objective_clique_widened: false,
restoration_calls: 0,
restoration_inner_iters: 0,
restoration_outer_iters: 0,
restoration_wall_secs: 0.0,
quality_escalations: 0,
dual_divergence_signature: false,
returned_run_dual_divergence_signature: false,
dual_divergence_retry_promoted: false,
sqp_qp_solves: 0,
sqp_qp_working_set_changes: 0,
sqp_warm_working_set_applied: false,
iterations: Vec::new(),
passes: Vec::new(),
}
}
}
impl SolveStatistics {
pub fn new() -> Self {
Self::default()
}
}