use std::fmt;
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct OptimResult<F> {
pub x: Vec<F>,
pub value: F,
pub gradient: Vec<F>,
pub gradient_norm: F,
pub iterations: usize,
pub func_evals: usize,
pub termination: TerminationReason,
pub diagnostics: SolverDiagnostics,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TerminationReason {
GradientNorm,
StepSize,
FunctionChange,
MaxIterations,
LineSearchFailed,
NumericalError,
}
impl fmt::Display for TerminationReason {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TerminationReason::GradientNorm => write!(f, "gradient norm below tolerance"),
TerminationReason::StepSize => write!(f, "step size below tolerance"),
TerminationReason::FunctionChange => write!(f, "function change below tolerance"),
TerminationReason::MaxIterations => write!(f, "maximum iterations reached"),
TerminationReason::LineSearchFailed => write!(f, "line search failed"),
TerminationReason::NumericalError => write!(f, "numerical error"),
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub enum SolverDiagnostics {
Lbfgs(LbfgsDiagnostics),
Newton(NewtonDiagnostics),
TrustRegion(TrustRegionDiagnostics),
Other,
}
impl SolverDiagnostics {
#[must_use]
pub fn as_lbfgs(&self) -> Option<&LbfgsDiagnostics> {
match self {
SolverDiagnostics::Lbfgs(d) => Some(d),
_ => None,
}
}
#[must_use]
pub fn as_newton(&self) -> Option<&NewtonDiagnostics> {
match self {
SolverDiagnostics::Newton(d) => Some(d),
_ => None,
}
}
#[must_use]
pub fn as_trust_region(&self) -> Option<&TrustRegionDiagnostics> {
match self {
SolverDiagnostics::TrustRegion(d) => Some(d),
_ => None,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct LbfgsDiagnostics {
pub pairs_accepted: usize,
pub pairs_curvature_rejected: usize,
pub pairs_evicted_by_memory: usize,
pub gamma_clamp_hits: usize,
pub line_search_backtracks: usize,
}
#[derive(Debug, Clone, Default)]
pub struct NewtonDiagnostics {
pub fallback_steps: usize,
pub line_search_backtracks: usize,
}
#[derive(Debug, Clone, Default)]
pub struct TrustRegionDiagnostics {
pub cg_inner_iters: usize,
pub radius_shrinks_bad_model: usize,
pub radius_shrinks_low_rho: usize,
}