resopt 0.3.0

Declarative constrained residual optimization in Rust
Documentation
use std::time::Instant;

use crate::{
    solve::{SolveDiagnostics, SolveOptions, SolveResult, SolveStatus, Solver},
    ConstrainedResidualProblem, Error,
};

#[cfg(feature = "clarabel")]
use crate::backends::clarabel::ClarabelSolver;

/// Default public solver.
///
/// When the `clarabel` feature is enabled, this solver delegates supported
/// problems to the Clarabel backend. Otherwise, it returns `NotImplemented`.
#[derive(Debug, Clone, PartialEq)]
pub struct DefaultSolver {
    options: SolveOptions,
}

impl DefaultSolver {
    pub fn new() -> Self {
        Self {
            options: SolveOptions::default(),
        }
    }

    pub fn with_options(mut self, options: SolveOptions) -> Self {
        self.options = options;
        self
    }

    pub fn options(&self) -> &SolveOptions {
        &self.options
    }
}

impl Default for DefaultSolver {
    fn default() -> Self {
        Self::new()
    }
}

impl Solver for DefaultSolver {
    fn solve(&self, problem: &ConstrainedResidualProblem) -> Result<SolveResult, Error> {
        let start = Instant::now();

        if let Err(_err) = problem.validate() {
            let diagnostics = SolveDiagnostics::new(
                0,
                "problem validation failed".to_string(),
                start.elapsed().as_secs_f64(),
                None,
            );

            return Ok(SolveResult::new(
                SolveStatus::InvalidProblem,
                None,
                None,
                diagnostics,
            ));
        }

        #[cfg(feature = "clarabel")]
        {
            ClarabelSolver::new()
                .with_options(self.options.clone())
                .solve(problem)
        }

        #[cfg(not(feature = "clarabel"))]
        {
            let diagnostics = SolveDiagnostics::new(
                0,
                "default solver is not implemented yet; enable the `clarabel` feature".to_string(),
                start.elapsed().as_secs_f64(),
                None,
            );

            Ok(SolveResult::new(
                SolveStatus::NotImplemented,
                None,
                None,
                diagnostics,
            ))
        }
    }
}