#![allow(non_snake_case)]
use clarabel::{algebra::*, solver::*};
#[allow(clippy::type_complexity)]
fn basic_expcone_data() -> (
CscMatrix<f64>, //P
Vec<f64>, //c
CscMatrix<f64>, //A
Vec<f64>, //b
Vec<SupportedConeT<f64>>,
) {
let P = CscMatrix::<f64>::zeros((3, 3));
let c = vec![-1., 0., 0.];
let mut A1 = CscMatrix::<f64>::identity(3);
A1.negate();
let b1 = vec![0.; 3];
let A2 = CscMatrix::new(
2, 3, vec![0, 0, 1, 2], vec![0, 1], vec![1., 1.], );
let b2 = vec![1., f64::exp(5.)];
let A = CscMatrix::vcat(&A1, &A2).unwrap();
let b = [b1, b2].concat();
let cones = vec![ExponentialConeT(), ZeroConeT(2)];
(P, c, A, b, cones)
}
#[test]
fn test_expcone_feasible() {
let (P, c, A, b, cones) = basic_expcone_data();
let settings = DefaultSettings::default();
let mut solver = DefaultSolver::new(&P, &c, &A, &b, &cones, settings).unwrap();
solver.solve();
assert_eq!(solver.solution.status, SolverStatus::Solved);
let refsol = vec![5.0, 1.0, f64::exp(5.0)];
assert!(solver.solution.x.dist(&refsol) <= 1e-6);
let refobj = -5.0;
assert!(f64::abs(solver.info.cost_primal - refobj) <= 1e-6);
}
#[test]
fn test_expcone_primal_infeasible() {
let (P, c, A, mut b, cones) = basic_expcone_data();
b[4] = -1.;
let settings = DefaultSettings::default();
let mut solver = DefaultSolver::new(&P, &c, &A, &b, &cones, settings).unwrap();
solver.solve();
assert_eq!(solver.solution.status, SolverStatus::PrimalInfeasible);
}
#[test]
fn test_expcone_dual_infeasible() {
let P = CscMatrix::<f64>::zeros((3, 3));
let c = vec![-1., 0., 0.];
let mut A = CscMatrix::<f64>::identity(3);
A.negate();
let b = vec![0.; 3];
let cones = vec![ExponentialConeT()];
let settings = DefaultSettings::default();
let mut solver = DefaultSolver::new(&P, &c, &A, &b, &cones, settings).unwrap();
solver.solve();
assert_eq!(solver.solution.status, SolverStatus::DualInfeasible);
}