use crate::optim::*;
use crate::primitives::{Matrix, Vector};
#[test]
fn test_admm_adaptive_rho_decrease() {
let n = 3;
let A = Matrix::eye(n);
let B = Matrix::from_vec(n, n, vec![-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0])
.expect("Valid matrix");
let c = Vector::zeros(n);
let x_minimizer = |z: &Vector<f32>, u: &Vector<f32>, _c: &Vector<f32>, rho: f32| {
let mut x = Vector::zeros(n);
for i in 0..n {
x[i] = z[i] - u[i] + 100.0 * (rho - 1.0).signum();
}
x
};
let z_minimizer = |ax: &Vector<f32>, u: &Vector<f32>, _c: &Vector<f32>, rho: f32| {
let mut z = Vector::zeros(n);
for i in 0..n {
z[i] = -ax[i] - u[i] + (rho * 50.0);
}
z
};
let mut admm = ADMM::new(50, 100.0, 1e-6).with_adaptive_rho(true);
let x0 = Vector::from_slice(&[1.0, 2.0, 3.0]);
let z0 = Vector::from_slice(&[10.0, 20.0, 30.0]);
let result = admm.minimize_consensus(x_minimizer, z_minimizer, &A, &B, &c, x0, z0);
assert!(result.solution.len() == n);
}
#[test]
fn test_admm_adaptive_rho_max_iterations() {
let n = 2;
let A = Matrix::eye(n);
let B = Matrix::eye(n);
let c = Vector::zeros(n);
let x_minimizer = |z: &Vector<f32>, u: &Vector<f32>, _c: &Vector<f32>, _rho: f32| {
let mut x = Vector::zeros(n);
for i in 0..n {
x[i] = z[i] - u[i] + 0.1; }
x
};
let z_minimizer = |ax: &Vector<f32>, u: &Vector<f32>, _c: &Vector<f32>, _rho: f32| {
let mut z = Vector::zeros(n);
for i in 0..n {
z[i] = ax[i] + u[i] - 0.1; }
z
};
let mut admm = ADMM::new(5, 1.0, 1e-12) .with_adaptive_rho(true)
.with_rho_factors(3.0, 3.0);
let x0 = Vector::zeros(n);
let z0 = Vector::zeros(n);
let result = admm.minimize_consensus(x_minimizer, z_minimizer, &A, &B, &c, x0, z0);
assert!(
result.status == ConvergenceStatus::MaxIterations
|| result.status == ConvergenceStatus::Converged
);
}
#[test]
fn test_prox_nonnegative_all_positive2() {
let x = Vector::from_slice(&[1.0, 2.0, 3.0, 4.0]);
let result = prox::nonnegative(&x);
for i in 0..4 {
assert!((result[i] - x[i]).abs() < f32::EPSILON);
}
}
#[test]
fn test_prox_nonnegative_all_negative2() {
let x = Vector::from_slice(&[-1.0, -2.0, -3.0, -4.0]);
let result = prox::nonnegative(&x);
for i in 0..4 {
assert!(result[i].abs() < f32::EPSILON);
}
}
#[test]
fn test_prox_soft_threshold_below_threshold2() {
let x = Vector::from_slice(&[0.3, -0.2, 0.1, -0.05]);
let result = prox::soft_threshold(&x, 0.5);
for i in 0..4 {
assert!(result[i].abs() < f32::EPSILON);
}
}
#[test]
fn test_lbfgs_debug_clone2() {
let lbfgs = LBFGS::new(100, 1e-6, 10);
let cloned = lbfgs.clone();
let debug_str = format!("{:?}", lbfgs);
assert!(debug_str.contains("LBFGS"));
drop(cloned);
}
#[test]
fn test_damped_newton_debug_clone2() {
let dn = DampedNewton::new(100, 1e-6);
let _cloned = dn.clone();
let debug_str = format!("{:?}", dn);
assert!(debug_str.contains("DampedNewton"));
}