use crate::kkt::KktTriplet;
fn diag_kkt(n: usize, h_diag: &[f64]) -> KktTriplet {
let mut irn = Vec::with_capacity(n);
let mut jcn = Vec::with_capacity(n);
let mut vals = Vec::with_capacity(n);
for i in 0..n {
irn.push((i + 1) as pounce_common::Index);
jcn.push((i + 1) as pounce_common::Index);
vals.push(h_diag[i]);
}
KktTriplet {
dim: n,
irn,
jcn,
vals,
}
}
#[test]
fn add_h_diagonal_shift_zero_delta_is_no_op() {
let mut k = diag_kkt(3, &[1.0, 2.0, 3.0]);
let before = (k.irn.clone(), k.jcn.clone(), k.vals.clone());
k.add_h_diagonal_shift(3, 0.0);
assert_eq!(k.irn, before.0);
assert_eq!(k.jcn, before.1);
assert_eq!(k.vals, before.2);
}
#[test]
fn add_h_diagonal_shift_increments_existing_diagonals() {
let mut k = diag_kkt(3, &[1.0, 2.0, 3.0]);
k.add_h_diagonal_shift(3, 0.5);
assert_eq!(k.vals, vec![1.5, 2.5, 3.5]);
assert_eq!(k.irn.len(), 3);
}
#[test]
fn add_h_diagonal_shift_appends_missing_diagonals() {
let mut k = KktTriplet {
dim: 3,
irn: vec![1, 3],
jcn: vec![1, 3],
vals: vec![1.0, 3.0],
};
k.add_h_diagonal_shift(3, 0.5);
assert_eq!(k.irn.len(), 3);
assert!(k
.irn
.iter()
.zip(k.jcn.iter())
.zip(k.vals.iter())
.any(|((&r, &c), &v)| r == 2 && c == 2 && v == 0.5));
}
#[test]
fn add_h_diagonal_shift_respects_n_h_rows_boundary() {
let mut k = KktTriplet {
dim: 5,
irn: vec![1, 2, 3, 4, 5],
jcn: vec![1, 2, 3, 4, 5],
vals: vec![1.0, 2.0, 3.0, 10.0, 20.0],
};
k.add_h_diagonal_shift(3, 0.1);
assert_eq!(k.vals[..3], [1.1, 2.1, 3.1]);
assert_eq!(k.vals[3], 10.0);
assert_eq!(k.vals[4], 20.0);
}
#[test]
fn add_h_diagonal_shift_accumulates_across_calls() {
let mut k = diag_kkt(2, &[1.0, 2.0]);
k.add_h_diagonal_shift(2, 0.1);
k.add_h_diagonal_shift(2, 0.2);
assert!((k.vals[0] - 1.3).abs() < 1e-12);
assert!((k.vals[1] - 2.3).abs() < 1e-12);
}