use approx::assert_abs_diff_eq;
use optirs_core::optimizers::{Lion, Optimizer};
use scirs2_core::ndarray::{Array1, Array2};
#[test]
#[allow(dead_code)]
fn test_lion_new_creates_optimizer_with_default_values() {
let optimizer: Lion<f64> = Lion::new(0.001);
assert_abs_diff_eq!(optimizer.learning_rate(), 0.001);
assert_abs_diff_eq!(optimizer.get_beta1(), 0.9);
assert_abs_diff_eq!(optimizer.get_beta2(), 0.99);
assert_abs_diff_eq!(optimizer.get_weight_decay(), 0.0);
}
#[test]
#[allow(dead_code)]
fn test_lion_new_with_config() {
let optimizer: Lion<f64> = Lion::new_with_config(0.01, 0.85, 0.98, 0.001);
assert_abs_diff_eq!(optimizer.learning_rate(), 0.01);
assert_abs_diff_eq!(optimizer.get_beta1(), 0.85);
assert_abs_diff_eq!(optimizer.get_beta2(), 0.98);
assert_abs_diff_eq!(optimizer.get_weight_decay(), 0.001);
}
#[test]
#[allow(dead_code)]
fn test_lion_setters() {
let mut optimizer: Lion<f64> = Lion::new(0.001);
optimizer.set_lr(0.002);
assert_abs_diff_eq!(optimizer.learning_rate(), 0.002);
optimizer.set_beta1(0.8);
assert_abs_diff_eq!(optimizer.get_beta1(), 0.8);
optimizer.set_beta2(0.95);
assert_abs_diff_eq!(optimizer.get_beta2(), 0.95);
optimizer.set_weight_decay(0.01);
assert_abs_diff_eq!(optimizer.get_weight_decay(), 0.01);
}
#[test]
#[allow(dead_code)]
fn test_lion_1d_optimization() {
let mut optimizer: Lion<f64> = Lion::new(0.1);
let mut params = Array1::from_vec(vec![2.0]);
for _ in 0..10 {
let gradients = Array1::from_vec(vec![2.0 * params[0]]);
params = optimizer.step(¶ms, &gradients).expect("unwrap failed");
}
assert!(params[0].abs() < 1.0);
}
#[test]
#[allow(dead_code)]
fn test_lion_2d_optimization() {
let mut optimizer: Lion<f64> = Lion::new(0.1);
let mut params = Array1::from_vec(vec![2.0, 3.0]);
for _ in 0..20 {
let gradients = Array1::from_vec(vec![2.0 * params[0], 2.0 * params[1]]);
params = optimizer.step(¶ms, &gradients).expect("unwrap failed");
}
assert!(params[0].abs() < 1.0);
assert!(params[1].abs() < 1.0);
}
#[test]
#[allow(dead_code)]
fn test_lion_with_weight_decay() {
let mut optimizer: Lion<f64> = Lion::new_with_config(0.1, 0.9, 0.99, 0.1);
let mut params = Array1::from_vec(vec![1.0, 1.0]);
for _ in 0..10 {
let gradients = Array1::zeros(2);
params = optimizer.step(¶ms, &gradients).expect("unwrap failed");
}
assert!(params[0] < 1.0);
assert!(params[1] < 1.0);
}
#[test]
#[allow(dead_code)]
fn test_lion_reset() {
let mut optimizer: Lion<f64> = Lion::new(0.1);
let params = Array1::from_vec(vec![1.0, 2.0]);
let gradients = Array1::from_vec(vec![0.1, 0.2]);
let _ = optimizer.step(¶ms, &gradients).expect("unwrap failed");
optimizer.reset();
let new_params = optimizer.step(¶ms, &gradients).expect("unwrap failed");
let mut fresh_optimizer: Lion<f64> = Lion::new(0.1);
let fresh_params = fresh_optimizer
.step(¶ms, &gradients)
.expect("unwrap failed");
assert_abs_diff_eq!(new_params[0], fresh_params[0], epsilon = 1e-6);
assert_abs_diff_eq!(new_params[1], fresh_params[1], epsilon = 1e-6);
}
#[test]
#[allow(dead_code)]
fn test_lion_multiple_dimensions() {
let mut optimizer: Lion<f64> = Lion::new(0.1);
let params_2d =
Array2::from_shape_vec((2, 3), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]).expect("unwrap failed");
let gradients_2d =
Array2::from_shape_vec((2, 3), vec![0.1, 0.2, 0.3, 0.4, 0.5, 0.6]).expect("unwrap failed");
let updated_2d = optimizer
.step(¶ms_2d, &gradients_2d)
.expect("unwrap failed");
assert_eq!(updated_2d.shape(), params_2d.shape());
assert_ne!(updated_2d[[0, 0]], params_2d[[0, 0]]);
assert_ne!(updated_2d[[1, 2]], params_2d[[1, 2]]);
}
#[test]
#[allow(dead_code)]
fn test_lion_trait_methods() {
let mut optimizer: Lion<f64> = Lion::new(0.001);
assert_abs_diff_eq!(optimizer.learning_rate(), 0.001);
optimizer.set_lr(0.005);
assert_abs_diff_eq!(optimizer.learning_rate(), 0.005);
}