pub(crate) use super::*;
#[test]
fn test_sphere_optimum() {
let x = vec![0.0; 10];
assert!((sphere(&x)).abs() < 1e-10);
}
#[test]
fn test_sphere_known_value() {
assert!((sphere(&[1.0, 2.0, 3.0]) - 14.0).abs() < 1e-10);
}
#[test]
fn test_sphere_single_dim() {
assert!((sphere(&[3.0]) - 9.0).abs() < 1e-10);
}
#[test]
fn test_sphere_empty() {
assert!((sphere(&[])).abs() < 1e-10);
}
#[test]
fn test_sphere_symmetry() {
let x = vec![1.5, -2.3, 4.7];
let neg_x: Vec<f64> = x.iter().map(|xi| -xi).collect();
assert!((sphere(&x) - sphere(&neg_x)).abs() < 1e-10);
}
#[test]
fn test_rosenbrock_optimum() {
let x = vec![1.0; 5];
assert!((rosenbrock(&x)).abs() < 1e-10);
}
#[test]
fn test_rosenbrock_known_value() {
assert!((rosenbrock(&[0.0, 0.0]) - 1.0).abs() < 1e-10);
}
#[test]
fn test_rosenbrock_another_known_value() {
assert!((rosenbrock(&[-1.0, 1.0]) - 4.0).abs() < 1e-10);
}
#[test]
fn test_rosenbrock_single_dim() {
assert!((rosenbrock(&[5.0])).abs() < 1e-10);
}
#[test]
fn test_rosenbrock_empty() {
assert!((rosenbrock(&[])).abs() < 1e-10);
}
#[test]
fn test_rastrigin_optimum() {
let x = vec![0.0; 10];
assert!((rastrigin(&x)).abs() < 1e-10);
}
#[test]
fn test_rastrigin_single_dim() {
assert!((rastrigin(&[1.0]) - 1.0).abs() < 1e-10);
}
#[test]
fn test_rastrigin_at_half() {
assert!((rastrigin(&[0.5]) - 20.25).abs() < 1e-10);
}
#[test]
fn test_rastrigin_empty() {
assert!((rastrigin(&[])).abs() < 1e-10);
}
#[test]
fn test_rastrigin_always_nonnegative() {
let inputs: Vec<Vec<f64>> = vec![vec![1.0, -1.0], vec![5.12, -5.12], vec![0.5, 0.5, 0.5]];
for x in &inputs {
assert!(
rastrigin(x) >= -1e-10,
"rastrigin({x:?}) = {} should be >= 0",
rastrigin(x)
);
}
}
#[test]
fn test_ackley_optimum() {
let x = vec![0.0; 5];
assert!(ackley(&x).abs() < 1e-10);
}
#[test]
fn test_ackley_known_value() {
let expected = 20.0 - 20.0 * (-0.2_f64).exp();
assert!((ackley(&[1.0, 1.0]) - expected).abs() < 1e-10);
}
#[test]
fn test_ackley_single_dim() {
assert!(ackley(&[0.0]).abs() < 1e-10);
}
#[test]
fn test_ackley_always_nonnegative() {
let inputs: Vec<Vec<f64>> = vec![vec![1.0, -1.0, 2.5], vec![32.0, -32.0], vec![0.001]];
for x in &inputs {
assert!(
ackley(x) >= -1e-10,
"ackley({x:?}) = {} should be >= 0",
ackley(x)
);
}
}
#[test]
fn test_schwefel_near_optimum() {
let x = vec![420.9687; 3];
assert!(schwefel(&x).abs() < 1.0);
}
#[test]
fn test_schwefel_single_dim_at_optimum() {
let val = schwefel(&[420.9687]);
assert!(val.abs() < 0.5);
}
#[test]
fn test_schwefel_at_zero() {
assert!((schwefel(&[0.0]) - 418.9829).abs() < 1e-4);
}
#[test]
fn test_schwefel_scales_with_dimension() {
let val_1d = schwefel(&[0.0]);
let val_3d = schwefel(&[0.0, 0.0, 0.0]);
assert!((val_3d - 3.0 * val_1d).abs() < 1e-10);
}
#[test]
fn test_griewank_optimum() {
let x = vec![0.0; 10];
assert!(griewank(&x).abs() < 1e-10);
}
#[test]
fn test_griewank_single_dim_at_origin() {
assert!(griewank(&[0.0]).abs() < 1e-10);
}
#[test]
fn test_griewank_known_value() {
let expected = PI * PI / 4000.0 + 2.0;
assert!((griewank(&[PI]) - expected).abs() < 1e-10);
}
#[test]
fn test_griewank_divisor_index() {
let sum_part = 2.0 / 4000.0;
let prod_part = (1.0_f64).cos() * (1.0 / 2.0_f64.sqrt()).cos();
let expected = sum_part - prod_part + 1.0;
assert!((griewank(&[1.0, 1.0]) - expected).abs() < 1e-10);
}
#[test]
fn test_levy_optimum() {
let x = vec![1.0; 5];
assert!(levy(&x).abs() < 1e-10);
}
#[test]
fn test_levy_known_value_2d() {
let w0 = 0.75;
let term1 = (PI * w0).sin().powi(2);
let term2 = (w0 - 1.0).powi(2) * (1.0 + 10.0 * (PI * w0 + 1.0).sin().powi(2));
let term3 = (w0 - 1.0).powi(2) * (1.0 + (2.0 * PI * w0).sin().powi(2));
let expected = term1 + term2 + term3;
assert!((levy(&[0.0, 0.0]) - expected).abs() < 1e-10);
}
#[test]
fn test_levy_single_dim() {
assert!(levy(&[1.0]).abs() < 1e-10);
}
#[test]
fn test_levy_single_dim_nonzero() {
let expected = 0.5 + 0.125;
assert!((levy(&[0.0]) - expected).abs() < 1e-10);
}
#[test]
fn test_michalewicz_2d_near_known_optimum() {
let val = michalewicz(&[2.20, 1.57]);
assert!(val < -1.7, "Expected < -1.7, got {val}");
assert!(val > -2.0, "Expected > -2.0, got {val}");
}
#[test]
fn test_michalewicz_at_zero() {
assert!(michalewicz(&[0.0]).abs() < 1e-10);
}
#[test]
fn test_michalewicz_at_pi_half() {
let expected = -(2.0_f64.powi(-10));
assert!((michalewicz(&[PI / 2.0]) - expected).abs() < 1e-10);
}
#[test]
fn test_michalewicz_empty() {
assert!(michalewicz(&[]).abs() < 1e-10);
}
#[test]
fn test_zakharov_optimum() {
let x = vec![0.0; 5];
assert!(zakharov(&x).abs() < 1e-10);
}
#[test]
fn test_zakharov_known_value() {
assert!((zakharov(&[1.0, 2.0]) - 50.3125).abs() < 1e-10);
}
#[test]
fn test_zakharov_single_dim() {
assert!((zakharov(&[2.0]) - 6.0).abs() < 1e-10);
}
#[test]
fn test_zakharov_empty() {
assert!(zakharov(&[]).abs() < 1e-10);
}
#[test]
fn test_dixon_price_1d_optimum() {
assert!(dixon_price(&[1.0]).abs() < 1e-10);
}
#[test]
fn test_dixon_price_2d_optimum() {
let x2 = 2.0_f64.powf(-0.5);
assert!(dixon_price(&[1.0, x2]).abs() < 1e-10);
}
#[test]
fn test_dixon_price_known_value() {
assert!((dixon_price(&[2.0, 1.0]) - 1.0).abs() < 1e-10);
}
#[test]
fn test_dixon_price_known_value_2() {
assert!((dixon_price(&[0.0, 0.0]) - 1.0).abs() < 1e-10);
}
#[test]
fn test_dixon_price_3d_exact_optimum() {
let x1 = 1.0;
let x2 = 2.0_f64.powf(-0.5);
let x3 = 2.0_f64.powf(-0.75);
assert!(dixon_price(&[x1, x2, x3]).abs() < 1e-10);
}
#[test]
fn test_all_benchmarks_count() {
assert_eq!(all_benchmarks().len(), 10);
}
#[test]
fn test_all_benchmarks_ids_sequential() {
let benchmarks = all_benchmarks();
for (i, info) in benchmarks.iter().enumerate() {
assert_eq!(
info.id as usize,
i + 1,
"Benchmark '{}' has id {} but expected {}",
info.name,
info.id,
i + 1
);
}
}
#[test]
fn test_all_benchmarks_valid_bounds() {
for info in all_benchmarks() {
assert!(
info.bounds.0 < info.bounds.1,
"{} has invalid bounds: ({}, {})",
info.name,
info.bounds.0,
info.bounds.1
);
}
}
#[test]
fn test_all_benchmarks_names_unique() {
let benchmarks = all_benchmarks();
let names: Vec<&str> = benchmarks.iter().map(|b| b.name).collect();
for (i, name) in names.iter().enumerate() {
assert!(
!names[..i].contains(name),
"Duplicate benchmark name: {name}"
);
}
}
#[test]
fn test_all_benchmarks_expected_names() {
let benchmarks = all_benchmarks();
let names: Vec<&str> = benchmarks.iter().map(|b| b.name).collect();
let expected = [
"Sphere",
"Rosenbrock",
"Rastrigin",
"Ackley",
"Schwefel",
"Griewank",
"Levy",
"Michalewicz",
"Zakharov",
"Dixon-Price",
];
assert_eq!(names, expected);
}
#[test]
fn test_all_benchmarks_modality_flags() {
let benchmarks = all_benchmarks();
assert!(!benchmarks[0].multimodal, "Sphere should be unimodal");
assert!(!benchmarks[1].multimodal, "Rosenbrock should be unimodal");
assert!(benchmarks[2].multimodal, "Rastrigin should be multimodal");
assert!(benchmarks[3].multimodal, "Ackley should be multimodal");
assert!(!benchmarks[8].multimodal, "Zakharov should be unimodal");
assert!(!benchmarks[9].multimodal, "Dixon-Price should be unimodal");
}
#[test]
fn test_all_benchmarks_separability_flags() {
let benchmarks = all_benchmarks();
assert!(benchmarks[0].separable, "Sphere should be separable");
assert!(
!benchmarks[1].separable,
"Rosenbrock should be non-separable"
);
assert!(benchmarks[2].separable, "Rastrigin should be separable");
assert!(!benchmarks[3].separable, "Ackley should be non-separable");
assert!(benchmarks[7].separable, "Michalewicz should be separable");
}
#[test]
fn test_michalewicz_optimum_is_neg_infinity() {
let benchmarks = all_benchmarks();
assert!(
benchmarks[7].optimum.is_infinite() && benchmarks[7].optimum < 0.0,
"Michalewicz optimum should be NEG_INFINITY"
);
}
#[test]
fn test_all_other_benchmarks_optimum_zero() {
for info in all_benchmarks() {
if info.name != "Michalewicz" {
assert!(
(info.optimum).abs() < 1e-10,
"{} should have optimum 0.0 but got {}",
info.name,
info.optimum
);
}
}
}