herculesabqp 0.1.2

A convex box-constrained quadratic programming solver with warm starts and active-set polishing.
Documentation
use std::sync::Arc;

use herculesabqp::solver::{solve_box_qp_implicit, QuadraticOperator, ScalingMode, SolverOptions};
use ndarray::Array1;

#[derive(Clone)]
struct DiagonalOperator {
    diag: Vec<f64>,
}

impl QuadraticOperator for DiagonalOperator {
    fn n(&self) -> usize {
        self.diag.len()
    }

    fn matvec_into(&self, x: &Array1<f64>, out: &mut Array1<f64>) {
        for i in 0..self.diag.len() {
            out[i] = self.diag[i] * x[i];
        }
    }

    fn diagonal(&self) -> Option<Array1<f64>> {
        Some(Array1::from_vec(self.diag.clone()))
    }
}

fn main() {
    let q = Arc::new(DiagonalOperator {
        diag: vec![4.0, 9.0, 2.0],
    });
    let c = vec![-2.0, 3.0, -0.5];
    let lb = vec![0.0, 0.0, 0.0];
    let ub = vec![1.0, 1.0, 1.0];

    let mut options = SolverOptions::default();
    options.assume_symmetric = true;
    options.scaling.mode = ScalingMode::HessianDiag;

    let result = solve_box_qp_implicit(q, &c, &lb, &ub, &options)
        .expect("failed to solve implicit box QP");

    println!("objective = {:.8}", result.objective);
    println!("x = {:?}", result.x);
    println!(
        "scaling applied = {} ({})",
        result.scaling.applied, result.scaling.name
    );
}