#![doc = include_str!("../README.md")]
#![doc = include_str!("../REFERENCES.md")]
#![allow(unused)]
use ndarray::{Array1, Array2};
use std::collections::HashMap;
pub mod functions;
pub use functions::*;
#[derive(Debug, Clone)]
pub struct FunctionMetadata {
pub name: String,
pub bounds: Vec<(f64, f64)>,
pub global_minima: Vec<(Vec<f64>, f64)>,
pub inequality_constraints: Vec<fn(&Array1<f64>) -> f64>,
pub equality_constraints: Vec<fn(&Array1<f64>) -> f64>,
pub description: String,
pub multimodal: bool,
pub dimensions: Vec<usize>,
}
pub fn create_bounds(n: usize, lower: f64, upper: f64) -> Array2<f64> {
Array2::from_shape_fn((2, n), |(i, _)| if i == 0 { lower } else { upper })
}
pub fn get_function_metadata() -> HashMap<String, FunctionMetadata> {
let mut metadata = HashMap::new();
metadata.insert(
"ackley".to_string(),
FunctionMetadata {
name: "ackley".to_string(),
bounds: vec![(-32.768, 32.768); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Multimodal Ackley function with many local minima".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"ackley_n2".to_string(),
FunctionMetadata {
name: "ackley_n2".to_string(),
bounds: vec![(-32.768, 32.768); 2],
global_minima: vec![(vec![0.0, 0.0], -200.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Modified Ackley N.2 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"ackley_n3".to_string(),
FunctionMetadata {
name: "ackley_n3".to_string(),
bounds: vec![(-32.768, 32.768); 2],
global_minima: vec![(vec![0.682584, -0.36075], -195.629)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Modified Ackley N.3 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"alpine_n1".to_string(),
FunctionMetadata {
name: "alpine_n1".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Alpine N.1 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"alpine_n2".to_string(),
FunctionMetadata {
name: "alpine_n2".to_string(),
bounds: vec![(0.0, 10.0); 2],
global_minima: vec![(vec![7.917, 7.917], -7.885)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Alpine N.2 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"beale".to_string(),
FunctionMetadata {
name: "beale".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![3.0, 0.5], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Beale function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"bent_cigar".to_string(),
FunctionMetadata {
name: "bent_cigar".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Bent Cigar function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"bent_cigar_alt".to_string(),
FunctionMetadata {
name: "bent_cigar_alt".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Alternative Bent Cigar function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"binh_korn_constraint1".to_string(),
FunctionMetadata {
name: "binh_korn_constraint1".to_string(),
bounds: vec![(0.0, 5.0), (0.0, 3.0)],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![binh_korn_constraint1, binh_korn_constraint2],
equality_constraints: vec![],
description: "Binh-Korn constraints: x1^2 + x2^2 <= 25 and (x1-8)^2 + (x2+3)^2 >= 7.7"
.to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"binh_korn_constraint2".to_string(),
FunctionMetadata {
name: "binh_korn_constraint2".to_string(),
bounds: vec![(0.0, 5.0), (0.0, 3.0)],
global_minima: vec![],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Binh-Korn constraint 2 function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"binh_korn_weighted".to_string(),
FunctionMetadata {
name: "binh_korn_weighted".to_string(),
bounds: vec![(0.0, 5.0), (0.0, 3.0)],
global_minima: vec![],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Binh-Korn weighted function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"bird".to_string(),
FunctionMetadata {
name: "bird".to_string(),
bounds: vec![(-2.0 * std::f64::consts::PI, 2.0 * std::f64::consts::PI); 2],
global_minima: vec![
(vec![4.70104, 3.15294], -106.764537),
(vec![-1.58214, -3.13024], -106.764537),
],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Bird function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"bohachevsky1".to_string(),
FunctionMetadata {
name: "bohachevsky1".to_string(),
bounds: vec![(-15.0, 15.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Bohachevsky N.1 function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"bohachevsky2".to_string(),
FunctionMetadata {
name: "bohachevsky2".to_string(),
bounds: vec![(-15.0, 15.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Bohachevsky N.2 function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"bohachevsky3".to_string(),
FunctionMetadata {
name: "bohachevsky3".to_string(),
bounds: vec![(-15.0, 15.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Bohachevsky N.3 function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"booth".to_string(),
FunctionMetadata {
name: "booth".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![1.0, 3.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Booth function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"branin".to_string(),
FunctionMetadata {
name: "branin".to_string(),
bounds: vec![(-5.0, 10.0), (0.0, 15.0)],
global_minima: vec![
(vec![-std::f64::consts::PI, 12.275], 0.397887),
(vec![std::f64::consts::PI, 2.275], 0.397887),
(vec![9.42478, 2.475], 0.397887),
],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Branin function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"brown".to_string(),
FunctionMetadata {
name: "brown".to_string(),
bounds: vec![(-1.0, 4.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Brown function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"bukin_n6".to_string(),
FunctionMetadata {
name: "bukin_n6".to_string(),
bounds: vec![(-15.0, -5.0), (-3.0, 3.0)],
global_minima: vec![(vec![-10.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Bukin N.6 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"chung_reynolds".to_string(),
FunctionMetadata {
name: "chung_reynolds".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Chung Reynolds function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"cigar".to_string(),
FunctionMetadata {
name: "cigar".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Cigar function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"colville".to_string(),
FunctionMetadata {
name: "colville".to_string(),
bounds: vec![(-10.0, 10.0); 4],
global_minima: vec![(vec![1.0, 1.0, 1.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Colville function (4D)".to_string(),
multimodal: false,
dimensions: vec![4],
},
);
metadata.insert(
"cosine_mixture".to_string(),
FunctionMetadata {
name: "cosine_mixture".to_string(),
bounds: vec![(-1.0, 1.0); 2],
global_minima: vec![(vec![0.0, 0.0], -0.2)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Cosine Mixture function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"cross_in_tray".to_string(),
FunctionMetadata {
name: "cross_in_tray".to_string(),
bounds: vec![(-15.0, 15.0); 2],
global_minima: vec![
(vec![1.3491, -1.3491], -2.06261),
(vec![1.3491, 1.3491], -2.06261),
(vec![-1.3491, 1.3491], -2.06261),
(vec![-1.3491, -1.3491], -2.06261),
],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Cross-in-Tray function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"de_jong_step2".to_string(),
FunctionMetadata {
name: "de_jong_step2".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "De Jong Step 2 function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"dejong_f5_foxholes".to_string(),
FunctionMetadata {
name: "dejong_f5_foxholes".to_string(),
bounds: vec![(-65.536, 65.536); 2],
global_minima: vec![(vec![-32.0, -32.0], 0.998003838)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "De Jong F5 (Foxholes) function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"different_powers".to_string(),
FunctionMetadata {
name: "different_powers".to_string(),
bounds: vec![(-1.0, 1.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Different Powers function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"discus".to_string(),
FunctionMetadata {
name: "discus".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Discus function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"dixons_price".to_string(),
FunctionMetadata {
name: "dixons_price".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![1.0, std::f64::consts::FRAC_1_SQRT_2], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Dixon's Price function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"drop_wave".to_string(),
FunctionMetadata {
name: "drop_wave".to_string(),
bounds: vec![(-5.12, 5.12); 2],
global_minima: vec![(vec![0.0, 0.0], -1.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Drop-Wave function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"easom".to_string(),
FunctionMetadata {
name: "easom".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![std::f64::consts::PI, std::f64::consts::PI], -1.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Easom function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"eggholder".to_string(),
FunctionMetadata {
name: "eggholder".to_string(),
bounds: vec![(-512.0, 512.0); 2],
global_minima: vec![(vec![512.0, 404.2319], -959.6407)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Eggholder function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"elliptic".to_string(),
FunctionMetadata {
name: "elliptic".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Elliptic function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"epistatic_michalewicz".to_string(),
FunctionMetadata {
name: "epistatic_michalewicz".to_string(),
bounds: vec![(0.0, std::f64::consts::PI); 2],
global_minima: vec![],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Epistatic Michalewicz function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"expanded_griewank_rosenbrock".to_string(),
FunctionMetadata {
name: "expanded_griewank_rosenbrock".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![1.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Expanded Griewank + Rosenbrock function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"exponential".to_string(),
FunctionMetadata {
name: "exponential".to_string(),
bounds: vec![(-1.0, 1.0); 2],
global_minima: vec![(vec![0.0, 0.0], -1.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Exponential function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"forrester_2008".to_string(),
FunctionMetadata {
name: "forrester_2008".to_string(),
bounds: vec![(0.0, 1.0)],
global_minima: vec![(vec![0.757249], -6.02074)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Forrester et al. (2008) function (1D)".to_string(),
multimodal: true,
dimensions: vec![1],
},
);
metadata.insert(
"freudenstein_roth".to_string(),
FunctionMetadata {
name: "freudenstein_roth".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![5.0, 4.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Freudenstein and Roth function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"goldstein_price".to_string(),
FunctionMetadata {
name: "goldstein_price".to_string(),
bounds: vec![(-2.0, 2.0); 2],
global_minima: vec![(vec![0.0, -1.0], 3.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Goldstein-Price function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"gramacy_lee_2012".to_string(),
FunctionMetadata {
name: "gramacy_lee_2012".to_string(),
bounds: vec![(0.5, 2.5)],
global_minima: vec![(vec![0.548563], -0.869011)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Gramacy & Lee (2012) function (1D)".to_string(),
multimodal: false,
dimensions: vec![1],
},
);
metadata.insert(
"gramacy_lee_function".to_string(),
FunctionMetadata {
name: "gramacy_lee_function".to_string(),
bounds: vec![(0.0, 6.0)],
global_minima: vec![],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Gramacy & Lee function (1D)".to_string(),
multimodal: true,
dimensions: vec![1],
},
);
metadata.insert(
"griewank".to_string(),
FunctionMetadata {
name: "griewank".to_string(),
bounds: vec![(-600.0, 600.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Griewank function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"griewank2".to_string(),
FunctionMetadata {
name: "griewank2".to_string(),
bounds: vec![(-600.0, 600.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Griewank function variant 2".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"happy_cat".to_string(),
FunctionMetadata {
name: "happy_cat".to_string(),
bounds: vec![(-2.0, 2.0); 2],
global_minima: vec![(vec![-1.0, -1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Happy Cat function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"happycat".to_string(),
FunctionMetadata {
name: "happycat".to_string(),
bounds: vec![(-2.0, 2.0); 2],
global_minima: vec![(vec![-1.0, -1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "HappyCat function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"hartman_3d".to_string(),
FunctionMetadata {
name: "hartman_3d".to_string(),
bounds: vec![(0.0, 1.0); 3],
global_minima: vec![(vec![0.114614, 0.555649, 0.852547], -3.86278)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Hartmann 3D function".to_string(),
multimodal: true,
dimensions: vec![3],
},
);
metadata.insert(
"hartman_4d".to_string(),
FunctionMetadata {
name: "hartman_4d".to_string(),
bounds: vec![(0.0, 1.0); 4],
global_minima: vec![(vec![0.1873, 0.1936, 0.5576, 0.2647], -3.72983)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Hartmann 4D function".to_string(),
multimodal: true,
dimensions: vec![4],
},
);
metadata.insert(
"hartman_6d".to_string(),
FunctionMetadata {
name: "hartman_6d".to_string(),
bounds: vec![(0.0, 1.0); 6],
global_minima: vec![(
vec![0.20169, 0.150011, 0.476874, 0.275332, 0.311652, 0.6573],
-3.32237,
)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Hartmann 6D function".to_string(),
multimodal: true,
dimensions: vec![6],
},
);
metadata.insert(
"himmelblau".to_string(),
FunctionMetadata {
name: "himmelblau".to_string(),
bounds: vec![(-6.0, 6.0); 2],
global_minima: vec![
(vec![3.0, 2.0], 0.0),
(vec![-2.805118, 3.131312], 0.0),
(vec![-3.779310, -3.283186], 0.0),
(vec![3.584428, -1.848126], 0.0),
],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Himmelblau's function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"holder_table".to_string(),
FunctionMetadata {
name: "holder_table".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![
(vec![8.05502, 9.66459], -19.2085),
(vec![-8.05502, 9.66459], -19.2085),
(vec![8.05502, -9.66459], -19.2085),
(vec![-8.05502, -9.66459], -19.2085),
],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Holder Table function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"katsuura".to_string(),
FunctionMetadata {
name: "katsuura".to_string(),
bounds: vec![(0.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Katsuura function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"keanes_bump_constraint1".to_string(),
FunctionMetadata {
name: "keanes_bump_constraint1".to_string(),
bounds: vec![(0.0, 10.0); 2],
global_minima: vec![],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Keane's Bump constraint 1 function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"keanes_bump_constraint2".to_string(),
FunctionMetadata {
name: "keanes_bump_constraint2".to_string(),
bounds: vec![(0.0, 10.0); 2],
global_minima: vec![],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Keane's Bump constraint 2 function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"keanes_bump_objective".to_string(),
FunctionMetadata {
name: "keanes_bump_objective".to_string(),
bounds: vec![(0.0, 10.0); 2],
global_minima: vec![(vec![1.393249, 0.0], -0.673668)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Keane's Bump objective function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"lampinen_simplified".to_string(),
FunctionMetadata {
name: "lampinen_simplified".to_string(),
bounds: vec![(0.0, 6.0); 2],
global_minima: vec![],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Lampinen simplified function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"langermann".to_string(),
FunctionMetadata {
name: "langermann".to_string(),
bounds: vec![(0.0, 10.0); 2],
global_minima: vec![(vec![2.00299219, 1.006096], -5.1621259)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Langermann function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"levi13".to_string(),
FunctionMetadata {
name: "levi13".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![1.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Lévi N.13 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"levy".to_string(),
FunctionMetadata {
name: "levy".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![1.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Lévy function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"levy_n13".to_string(),
FunctionMetadata {
name: "levy_n13".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![1.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Lévy N.13 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"matyas".to_string(),
FunctionMetadata {
name: "matyas".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Matyas function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"mccormick".to_string(),
FunctionMetadata {
name: "mccormick".to_string(),
bounds: vec![(-1.5, 4.0), (-3.0, 4.0)],
global_minima: vec![(vec![-0.54719, -1.54719], -1.9133)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "McCormick function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"michalewicz".to_string(),
FunctionMetadata {
name: "michalewicz".to_string(),
bounds: vec![(0.0, std::f64::consts::PI); 2],
global_minima: vec![(vec![2.20, 1.57], -1.8013)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Michalewicz function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"mishras_bird_constraint".to_string(),
FunctionMetadata {
name: "mishras_bird_constraint".to_string(),
bounds: vec![(-10.0, 0.0); 2],
global_minima: vec![],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Mishra's Bird constraint function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"mishras_bird_objective".to_string(),
FunctionMetadata {
name: "mishras_bird_objective".to_string(),
bounds: vec![(-10.0, 0.0); 2],
global_minima: vec![(vec![-3.1302468, -1.5821422], -106.7645367)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Mishra's Bird objective function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"periodic".to_string(),
FunctionMetadata {
name: "periodic".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.9)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Periodic function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"perm_0_d_beta".to_string(),
FunctionMetadata {
name: "perm_0_d_beta".to_string(),
bounds: vec![(-2.0, 2.0); 2],
global_minima: vec![(vec![1.0, 0.5], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Perm 0,d,β function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"perm_d_beta".to_string(),
FunctionMetadata {
name: "perm_d_beta".to_string(),
bounds: vec![(-2.0, 2.0); 2],
global_minima: vec![(vec![1.0, 0.5], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Perm d,β function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"pinter".to_string(),
FunctionMetadata {
name: "pinter".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Pinter function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"powell".to_string(),
FunctionMetadata {
name: "powell".to_string(),
bounds: vec![(-4.0, 5.0); 4],
global_minima: vec![(vec![0.0, 0.0, 0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Powell function (4D)".to_string(),
multimodal: false,
dimensions: vec![4],
},
);
metadata.insert(
"power_sum".to_string(),
FunctionMetadata {
name: "power_sum".to_string(),
bounds: vec![(0.0, 4.0); 4],
global_minima: vec![(vec![1.0, 2.0, 2.0, 3.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Power Sum function (4D)".to_string(),
multimodal: false,
dimensions: vec![4],
},
);
metadata.insert(
"qing".to_string(),
FunctionMetadata {
name: "qing".to_string(),
bounds: vec![(-500.0, 500.0); 2],
global_minima: vec![(vec![1.0, std::f64::consts::SQRT_2], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Qing function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"quadratic".to_string(),
FunctionMetadata {
name: "quadratic".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Quadratic function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"quartic".to_string(),
FunctionMetadata {
name: "quartic".to_string(),
bounds: vec![(-1.28, 1.28); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Quartic function with noise".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"rastrigin".to_string(),
FunctionMetadata {
name: "rastrigin".to_string(),
bounds: vec![(-5.12, 5.12); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Highly multimodal Rastrigin function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"ridge".to_string(),
FunctionMetadata {
name: "ridge".to_string(),
bounds: vec![(-5.0, 5.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Ridge function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"rosenbrock".to_string(),
FunctionMetadata {
name: "rosenbrock".to_string(),
bounds: vec![(-2.048, 2.048); 2],
global_minima: vec![(vec![1.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Classic Rosenbrock banana function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"rosenbrock_disk_constraint".to_string(),
FunctionMetadata {
name: "rosenbrock_disk_constraint".to_string(),
bounds: vec![(-1.5, 1.5); 2],
global_minima: vec![(vec![1.0, 1.0], 0.0)],
inequality_constraints: vec![rosenbrock_disk_constraint],
equality_constraints: vec![],
description: "Disk constraint: x^2 + y^2 <= 2".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"rosenbrock_objective".to_string(),
FunctionMetadata {
name: "rosenbrock_objective".to_string(),
bounds: vec![(-2.048, 2.048); 2],
global_minima: vec![(vec![1.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Rosenbrock objective function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"rotated_hyper_ellipsoid".to_string(),
FunctionMetadata {
name: "rotated_hyper_ellipsoid".to_string(),
bounds: vec![(-65.536, 65.536); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Rotated Hyper-ellipsoid function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"salomon".to_string(),
FunctionMetadata {
name: "salomon".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Salomon function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"salomon_corrected".to_string(),
FunctionMetadata {
name: "salomon_corrected".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Salomon corrected function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"schaffer_n2".to_string(),
FunctionMetadata {
name: "schaffer_n2".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Schaffer N.2 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"schaffer_n4".to_string(),
FunctionMetadata {
name: "schaffer_n4".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![
(vec![0.0, 1.25313], 0.292579),
(vec![0.0, -1.25313], 0.292579),
],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Schaffer N.4 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"schwefel".to_string(),
FunctionMetadata {
name: "schwefel".to_string(),
bounds: vec![(-500.0, 500.0); 2],
global_minima: vec![(vec![420.9687, 420.9687], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Schwefel function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"schwefel2".to_string(),
FunctionMetadata {
name: "schwefel2".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Schwefel 2 function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"sharp_ridge".to_string(),
FunctionMetadata {
name: "sharp_ridge".to_string(),
bounds: vec![(-5.0, 5.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Sharp Ridge function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"shekel".to_string(),
FunctionMetadata {
name: "shekel".to_string(),
bounds: vec![(0.0, 10.0); 4],
global_minima: vec![(vec![4.0, 4.0, 4.0, 4.0], -10.5364)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Shekel function (4D)".to_string(),
multimodal: true,
dimensions: vec![4],
},
);
metadata.insert(
"shubert".to_string(),
FunctionMetadata {
name: "shubert".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![-7.0835, 4.8580], -186.7309)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Shubert function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"six_hump_camel".to_string(),
FunctionMetadata {
name: "six_hump_camel".to_string(),
bounds: vec![(-3.0, 3.0), (-2.0, 2.0)],
global_minima: vec![
(vec![0.0898, -0.7126], -1.0316),
(vec![-0.0898, 0.7126], -1.0316),
],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Six-hump Camel function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"sphere".to_string(),
FunctionMetadata {
name: "sphere".to_string(),
bounds: vec![(-5.0, 5.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Simple quadratic sphere function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"step".to_string(),
FunctionMetadata {
name: "step".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Step function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"styblinski_tang2".to_string(),
FunctionMetadata {
name: "styblinski_tang2".to_string(),
bounds: vec![(-5.0, 5.0); 2],
global_minima: vec![(vec![-2.903534, -2.903534], -78.332)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Styblinski-Tang function (2D)".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"sum_of_different_powers".to_string(),
FunctionMetadata {
name: "sum_of_different_powers".to_string(),
bounds: vec![(-1.0, 1.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Sum of Different Powers function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"sum_squares".to_string(),
FunctionMetadata {
name: "sum_squares".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Sum Squares function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"tablet".to_string(),
FunctionMetadata {
name: "tablet".to_string(),
bounds: vec![(-100.0, 100.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Tablet function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"three_hump_camel".to_string(),
FunctionMetadata {
name: "three_hump_camel".to_string(),
bounds: vec![(-5.0, 5.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Three-hump Camel function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"trid".to_string(),
FunctionMetadata {
name: "trid".to_string(),
bounds: vec![(-4.0, 4.0); 2],
global_minima: vec![(vec![2.0, 2.0], -2.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Trid function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"vincent".to_string(),
FunctionMetadata {
name: "vincent".to_string(),
bounds: vec![(0.25, 10.0); 2],
global_minima: vec![(vec![7.70628, 7.70628], -2.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Vincent function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"whitley".to_string(),
FunctionMetadata {
name: "whitley".to_string(),
bounds: vec![(-10.24, 10.24); 2],
global_minima: vec![(vec![1.0, 1.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Whitley function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"xin_she_yang_n1".to_string(),
FunctionMetadata {
name: "xin_she_yang_n1".to_string(),
bounds: vec![(-2.0 * std::f64::consts::PI, 2.0 * std::f64::consts::PI); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Xin-She Yang N.1 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"xin_she_yang_n2".to_string(),
FunctionMetadata {
name: "xin_she_yang_n2".to_string(),
bounds: vec![(-2.0 * std::f64::consts::PI, 2.0 * std::f64::consts::PI); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Xin-She Yang N.2 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"xin_she_yang_n3".to_string(),
FunctionMetadata {
name: "xin_she_yang_n3".to_string(),
bounds: vec![(-20.0, 20.0); 2],
global_minima: vec![(vec![0.0, 0.0], -1.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Xin-She Yang N.3 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"xin_she_yang_n4".to_string(),
FunctionMetadata {
name: "xin_she_yang_n4".to_string(),
bounds: vec![(-10.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], -1.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Xin-She Yang N.4 function".to_string(),
multimodal: true,
dimensions: vec![2],
},
);
metadata.insert(
"zakharov".to_string(),
FunctionMetadata {
name: "zakharov".to_string(),
bounds: vec![(-5.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Zakharov function".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
metadata.insert(
"zakharov2".to_string(),
FunctionMetadata {
name: "zakharov2".to_string(),
bounds: vec![(-5.0, 10.0); 2],
global_minima: vec![(vec![0.0, 0.0], 0.0)],
inequality_constraints: vec![],
equality_constraints: vec![],
description: "Zakharov function variant 2".to_string(),
multimodal: false,
dimensions: vec![2],
},
);
println!(
"📊 Loaded metadata for {} test functions (explicit definitions)",
metadata.len()
);
metadata
}
pub fn get_function_bounds(function_name: &str) -> Option<Vec<(f64, f64)>> {
let metadata = get_function_metadata();
metadata.get(function_name).map(|meta| meta.bounds.clone())
}
pub fn get_function_bounds_2d(function_name: &str, default_bounds: (f64, f64)) -> [(f64, f64); 2] {
if let Some(bounds) = get_function_bounds(function_name) {
if bounds.len() >= 2 {
[bounds[0], bounds[1]]
} else {
[default_bounds; 2]
}
} else {
[default_bounds; 2]
}
}
pub fn get_function_bounds_vec(function_name: &str, default_bounds: (f64, f64)) -> Vec<(f64, f64)> {
if let Some(bounds) = get_function_bounds(function_name) {
if bounds.len() >= 2 {
bounds
} else {
vec![default_bounds; 2]
}
} else {
vec![default_bounds; 2]
}
}
#[cfg(test)]
mod tests {
use super::*;
use ndarray::Array1;
fn call_function(name: &str, x: &Array1<f64>) -> Option<f64> {
match name {
"ackley" => Some(ackley(x)),
"ackley_n2" => Some(ackley_n2(x)),
"ackley_n3" => Some(ackley_n3(x)),
"alpine_n1" => Some(alpine_n1(x)),
"alpine_n2" => Some(alpine_n2(x)),
"beale" => Some(beale(x)),
"bent_cigar" => Some(bent_cigar(x)),
"bent_cigar_alt" => Some(bent_cigar_alt(x)),
"binh_korn_constraint1" => None,
"binh_korn_constraint2" => None,
"binh_korn_weighted" => None,
"bird" => Some(bird(x)),
"bohachevsky1" => Some(bohachevsky1(x)),
"bohachevsky2" => Some(bohachevsky2(x)),
"bohachevsky3" => Some(bohachevsky3(x)),
"booth" => Some(booth(x)),
"branin" => Some(branin(x)),
"brown" => Some(brown(x)),
"bukin_n6" => Some(bukin_n6(x)),
"chung_reynolds" => Some(chung_reynolds(x)),
"cigar" => Some(cigar(x)),
"colville" => Some(colville(x)),
"cosine_mixture" => Some(cosine_mixture(x)),
"cross_in_tray" => Some(cross_in_tray(x)),
"de_jong_step2" => Some(de_jong_step2(x)),
"dejong_f5_foxholes" => Some(dejong_f5_foxholes(x)),
"different_powers" => Some(different_powers(x)),
"discus" => Some(discus(x)),
"dixons_price" => Some(dixons_price(x)),
"drop_wave" => Some(drop_wave(x)),
"easom" => Some(easom(x)),
"eggholder" => Some(eggholder(x)),
"elliptic" => Some(elliptic(x)),
"epistatic_michalewicz" => Some(epistatic_michalewicz(x)),
"expanded_griewank_rosenbrock" => Some(expanded_griewank_rosenbrock(x)),
"exponential" => Some(exponential(x)),
"forrester_2008" => Some(forrester_2008(x)),
"freudenstein_roth" => Some(freudenstein_roth(x)),
"goldstein_price" => Some(goldstein_price(x)),
"gramacy_lee_2012" => Some(gramacy_lee_2012(x)),
"gramacy_lee_function" => Some(gramacy_lee_function(x)),
"griewank" => Some(griewank(x)),
"griewank2" => Some(griewank2(x)),
"happy_cat" => Some(happy_cat(x)),
"happycat" => Some(happycat(x)),
"hartman_3d" => Some(hartman_3d(x)),
"hartman_4d" => Some(hartman_4d(x)),
"hartman_6d" => Some(hartman_6d(x)),
"himmelblau" => Some(himmelblau(x)),
"holder_table" => Some(holder_table(x)),
"katsuura" => Some(katsuura(x)),
"keanes_bump_constraint1" => None,
"keanes_bump_constraint2" => None,
"keanes_bump_objective" => Some(keanes_bump_objective(x)),
"lampinen_simplified" => Some(lampinen_simplified(x)),
"langermann" => Some(langermann(x)),
"levi13" => Some(levi13(x)),
"levy" => Some(levy(x)),
"levy_n13" => Some(levy_n13(x)),
"matyas" => Some(matyas(x)),
"mccormick" => Some(mccormick(x)),
"michalewicz" => Some(michalewicz(x)),
"mishras_bird_constraint" => None,
"mishras_bird_objective" => None,
"periodic" => Some(periodic(x)),
"perm_0_d_beta" => Some(perm_0_d_beta(x)),
"perm_d_beta" => Some(perm_d_beta(x)),
"pinter" => Some(pinter(x)),
"powell" => Some(powell(x)),
"power_sum" => Some(power_sum(x)),
"qing" => Some(qing(x)),
"quadratic" => Some(quadratic(x)),
"quartic" => Some(quartic(x)),
"rastrigin" => Some(rastrigin(x)),
"ridge" => Some(ridge(x)),
"rosenbrock" => Some(rosenbrock(x)),
"rosenbrock_disk_constraint" => None,
"rosenbrock_objective" => Some(rosenbrock_objective(x)),
"rotated_hyper_ellipsoid" => Some(rotated_hyper_ellipsoid(x)),
"salomon" => Some(salomon(x)),
"salomon_corrected" => Some(salomon_corrected(x)),
"schaffer_n2" => Some(schaffer_n2(x)),
"schaffer_n4" => Some(schaffer_n4(x)),
"schwefel" => Some(schwefel(x)),
"schwefel2" => Some(schwefel2(x)),
"sharp_ridge" => Some(sharp_ridge(x)),
"shekel" => Some(shekel(x)),
"shubert" => Some(shubert(x)),
"six_hump_camel" => Some(six_hump_camel(x)),
"sphere" => Some(sphere(x)),
"step" => Some(step(x)),
"styblinski_tang2" => Some(styblinski_tang2(x)),
"sum_of_different_powers" => Some(sum_of_different_powers(x)),
"sum_squares" => Some(sum_squares(x)),
"tablet" => Some(tablet(x)),
"three_hump_camel" => Some(three_hump_camel(x)),
"trid" => Some(trid(x)),
"vincent" => Some(vincent(x)),
"whitley" => Some(whitley(x)),
"xin_she_yang_n1" => Some(xin_she_yang_n1(x)),
"xin_she_yang_n2" => Some(xin_she_yang_n2(x)),
"xin_she_yang_n3" => Some(xin_she_yang_n3(x)),
"xin_she_yang_n4" => Some(xin_she_yang_n4(x)),
"zakharov" => Some(zakharov(x)),
"zakharov2" => Some(zakharov2(x)),
_ => None,
}
}
#[test]
fn test_all_function_minima() {
let metadata = get_function_metadata();
let tolerance = 1e-10; let loose_tolerance = 1e-3;
for (func_name, meta) in metadata.iter() {
if !meta.inequality_constraints.is_empty() || !meta.equality_constraints.is_empty() {
continue;
}
println!("Testing function: {}", func_name);
for (minimum_location, expected_value) in &meta.global_minima {
let x = Array1::from_vec(minimum_location.clone());
if let Some(actual_value) = call_function(func_name, &x) {
let error = (actual_value - expected_value).abs();
let test_tolerance = if expected_value.abs() > 1.0 {
loose_tolerance * expected_value.abs()
} else {
loose_tolerance
};
println!(
" {} at {:?}: expected {:.6}, got {:.6}, error {:.2e}",
func_name, minimum_location, expected_value, actual_value, error
);
assert!(
error <= test_tolerance,
"Function {} failed: at {:?}, expected {:.10}, got {:.10}, error {:.2e} > tolerance {:.2e}",
func_name,
minimum_location,
expected_value,
actual_value,
error,
test_tolerance
);
println!(" ✓ {} passed with error {:.2e}", func_name, error);
} else {
println!(
" ⚠ Skipped {} (not implemented in test dispatcher)",
func_name
);
}
}
}
println!("\n🎉 All function minima tests completed!");
}
#[test]
fn test_specific_challenging_functions() {
let tolerance = 1e-5;
let x = Array1::from_vec(vec![0.548563444114526]);
let result = gramacy_lee_2012(&x);
let expected = -0.869011134989500;
assert!(
(result - expected).abs() < tolerance,
"Gramacy & Lee 2012: expected {}, got {}",
expected,
result
);
let x = Array1::from_vec(vec![0.757249]);
let result = forrester_2008(&x);
let expected = -6.02074;
assert!(
(result - expected).abs() < tolerance,
"Forrester 2008: expected {}, got {}",
expected,
result
);
let x = Array1::from_vec(vec![0.1873, 0.1936, 0.5576, 0.2647]);
let result = hartman_4d(&x);
let expected = -3.72983;
assert!(
(result - expected).abs() < tolerance,
"Hartmann 4D: expected {}, got {}",
expected,
result
);
let x = Array1::from_vec(vec![4.0, 4.0, 4.0, 4.0]);
let result = shekel(&x);
let expected = -10.5364;
let shekel_tolerance = 1e-3; assert!(
(result - expected).abs() < shekel_tolerance,
"Shekel: expected {}, got {}",
expected,
result
);
}
#[test]
fn test_simple_unimodal_functions() {
let tolerance = 1e-12;
let x = Array1::from_vec(vec![0.0, 0.0]);
assert_eq!(sphere(&x), 0.0);
assert_eq!(sum_squares(&x), 0.0);
assert_eq!(different_powers(&x), 0.0);
assert_eq!(elliptic(&x), 0.0);
assert_eq!(cigar(&x), 0.0);
assert_eq!(tablet(&x), 0.0);
assert_eq!(discus(&x), 0.0);
assert_eq!(ridge(&x), 0.0);
assert_eq!(sharp_ridge(&x), 0.0);
assert_eq!(xin_she_yang_n1(&x), 0.0);
let x = Array1::from_vec(vec![1.0, 1.0]);
assert!((rosenbrock(&x) - 0.0).abs() < tolerance);
assert!((expanded_griewank_rosenbrock(&x) - 0.0).abs() < tolerance);
let x = Array1::from_vec(vec![1.0, 3.0]);
assert!((booth(&x) - 0.0).abs() < tolerance);
let x = Array1::from_vec(vec![0.0, 0.0]);
assert!((matyas(&x) - 0.0).abs() < tolerance);
let x = Array1::from_vec(vec![3.0, 0.5]);
assert!((beale(&x) - 0.0).abs() < tolerance);
}
#[test]
fn test_multimodal_functions() {
let tolerance = 1e-10;
let x = Array1::from_vec(vec![0.0, 0.0]);
assert!((ackley(&x) - 0.0).abs() < tolerance);
assert!((rastrigin(&x) - 0.0).abs() < tolerance);
assert!((griewank(&x) - 0.0).abs() < tolerance);
let x = Array1::from_vec(vec![420.9687, 420.9687]);
assert!((schwefel(&x) - 0.0).abs() < 1e-3); }
#[test]
fn test_perm_functions() {
let tolerance = 1e-12;
let x = Array1::from_vec(vec![1.0, 0.5]);
assert!((perm_0_d_beta(&x) - 0.0).abs() < tolerance);
assert!((perm_d_beta(&x) - 0.0).abs() < tolerance);
}
#[test]
fn test_bird_matches_literature() {
let x = Array1::from_vec(vec![4.70104, 3.15294]);
let val = bird(&x);
assert!(
(val - (-106.764537)).abs() < 1.0,
"bird at (4.70104, 3.15294) should be ~-106.764537, got {}",
val
);
}
#[test]
fn test_gramacy_lee_2012_finite_at_zero() {
let x = Array1::from_vec(vec![0.0]);
let val = gramacy_lee_2012(&x);
assert!(
val.is_finite(),
"gramacy_lee_2012 at 0 should be finite, got {}",
val
);
}
#[test]
fn test_keanes_bump_finite_at_origin() {
let x = Array1::from_vec(vec![0.0, 0.0]);
let val = keanes_bump_objective(&x);
assert!(
val.is_finite(),
"keanes_bump_objective at origin should be finite, got {}",
val
);
let x4 = Array1::from_vec(vec![0.0; 4]);
let val4 = keanes_bump_objective(&x4);
assert!(
val4.is_finite(),
"4D keanes_bump_objective at origin should be finite, got {}",
val4
);
}
#[test]
fn test_constrained_helpers_are_exercised_directly() {
let binh_inside = Array1::from_vec(vec![0.0, 0.0]);
assert!(binh_korn_constraint1(&binh_inside) <= 0.0);
assert!(binh_korn_constraint2(&binh_inside) <= 0.0);
let keane = Array1::from_vec(vec![1.0, 1.0, 1.0, 1.0]);
assert!(keanes_bump_constraint1(&keane) <= 0.0);
assert!(keanes_bump_constraint2(&keane) <= 0.0);
let keane_short = Array1::from_vec(vec![1.0, 1.0]);
assert!(
keanes_bump_constraint1(&keane_short) > 0.0,
"missing Keane dimensions should violate product constraint"
);
let mishra_center = Array1::from_vec(vec![-5.0, -5.0]);
assert!(mishras_bird_constraint(&mishra_center) < 0.0);
let rosenbrock_origin = Array1::from_vec(vec![0.0, 0.0]);
assert!(rosenbrock_disk_constraint(&rosenbrock_origin) <= 0.0);
}
#[test]
fn test_alpine_n2_finite_on_negative() {
let x = Array1::from_vec(vec![-1.0, -1.0]);
let val = alpine_n2(&x);
assert!(
val.is_finite(),
"alpine_n2 on negative input should be finite, got {}",
val
);
}
#[test]
fn test_ackley_n2_correct_minimum() {
let x_good = Array1::from_vec(vec![0.0, 0.0]);
let val_good = ackley_n2(&x_good);
assert!(
(val_good - (-200.0)).abs() < 1e-3,
"ackley_n2 at (0,0) should be -200, got {}",
val_good
);
let x_bad = Array1::from_vec(vec![-1.0, -1.0]);
let val_bad = ackley_n2(&x_bad);
assert!(
(val_bad - (-200.0)).abs() > 1e-3,
"ackley_n2 at (-1,-1) should NOT be -200, got {}",
val_bad
);
}
#[test]
fn test_step_correct_minimum() {
let x_good = Array1::from_vec(vec![0.0, 0.0]);
let val_good = step(&x_good);
assert_eq!(val_good, 0.0, "step at (0,0) should be 0");
let x_bad = Array1::from_vec(vec![0.5, 0.5]);
let val_bad = step(&x_bad);
assert_ne!(val_bad, 0.0, "step at (0.5, 0.5) should NOT be 0");
}
#[test]
fn test_qing_correct_minimum() {
let x_good = Array1::from_vec(vec![1.0, 2.0_f64.sqrt()]);
let val_good = qing(&x_good);
assert!(
val_good.abs() < 1e-10,
"qing at (1, sqrt(2)) should be 0, got {}",
val_good
);
let x_bad = Array1::from_vec(vec![2.0_f64.sqrt(), 2.0]);
let val_bad = qing(&x_bad);
assert!(
val_bad.abs() > 1e-3,
"qing at (sqrt(2), 2.0) should NOT be 0, got {}",
val_bad
);
}
#[test]
fn test_alpine_n2_correct_minimum() {
let x = Array1::from_vec(vec![7.917, 7.917]);
let val = alpine_n2(&x);
assert!(
(val - (-7.885)).abs() < 0.5,
"alpine_n2 at (7.917, 7.917) should be ~-7.885, got {}",
val
);
}
#[test]
fn test_freudenstein_roth_global_minimum() {
let x_global = Array1::from_vec(vec![5.0, 4.0]);
let val_global = freudenstein_roth(&x_global);
assert!(
val_global.abs() < 1e-10,
"freudenstein_roth at (5,4) should be 0, got {}",
val_global
);
let x_local = Array1::from_vec(vec![11.41, -0.8968]);
let val_local = freudenstein_roth(&x_local);
assert!(
val_local.abs() > 1.0,
"freudenstein_roth at (11.41, -0.8968) should NOT be 0 (it's a local min ~48.98), got {}",
val_local
);
}
#[test]
fn test_function_metadata_completeness() {
let metadata = get_function_metadata();
for (name, meta) in metadata.iter() {
assert!(!meta.name.is_empty(), "Function {} has empty name", name);
assert!(!meta.bounds.is_empty(), "Function {} has no bounds", name);
assert!(
!meta.description.is_empty(),
"Function {} has no description",
name
);
assert!(
!meta.dimensions.is_empty(),
"Function {} has no dimensions",
name
);
for (lower, upper) in &meta.bounds {
assert!(
lower < upper,
"Function {} has invalid bounds: {} >= {}",
name,
lower,
upper
);
}
for (location, _value) in &meta.global_minima {
if !meta.bounds.is_empty() {
if location.len() != meta.bounds.len() {
println!(
"⚠️ Function {} has dimension mismatch: global minimum {}D vs bounds {}D",
name,
location.len(),
meta.bounds.len()
);
if location.len() > meta.bounds.len() * 2 {
panic!(
"Function {} has severe dimension mismatch: {} vs bounds {}",
name,
location.len(),
meta.bounds.len()
);
}
}
}
}
}
println!("✓ All {} functions have complete metadata", metadata.len());
}
}