#[derive(Debug, Clone)]
pub struct Benchmark {
pub name: &'static str,
pub bound: f64,
pub optimum_value: f64,
}
pub fn sphere(x: &[f64]) -> f64 {
x.iter().map(|&xi| xi * xi).sum()
}
pub fn rastrigin(x: &[f64]) -> f64 {
let n = x.len() as f64;
10.0 * n
+ x.iter()
.map(|&xi| xi * xi - 10.0 * (2.0 * std::f64::consts::PI * xi).cos())
.sum::<f64>()
}
pub fn rosenbrock(x: &[f64]) -> f64 {
x.windows(2)
.map(|w| {
let (xi, xj) = (w[0], w[1]);
100.0 * (xj - xi * xi).powi(2) + (1.0 - xi).powi(2)
})
.sum()
}
pub fn ackley(x: &[f64]) -> f64 {
let n = x.len() as f64;
let sum_sq: f64 = x.iter().map(|&xi| xi * xi).sum();
let sum_cos: f64 = x
.iter()
.map(|&xi| (2.0 * std::f64::consts::PI * xi).cos())
.sum();
-20.0 * (-0.2 * (sum_sq / n).sqrt()).exp() - (sum_cos / n).exp() + 20.0 + std::f64::consts::E
}
pub fn griewank(x: &[f64]) -> f64 {
let sum: f64 = x.iter().map(|&xi| xi * xi).sum::<f64>() / 4000.0;
let prod: f64 = x
.iter()
.enumerate()
.map(|(i, &xi)| (xi / ((i + 1) as f64).sqrt()).cos())
.product();
1.0 + sum - prod
}
pub fn schwefel(x: &[f64]) -> f64 {
let n = x.len() as f64;
418.982_887_272_433_8 * n - x.iter().map(|&xi| xi * xi.abs().sqrt().sin()).sum::<f64>()
}
pub const SPHERE: Benchmark = Benchmark {
name: "sphere",
bound: 5.12,
optimum_value: 0.0,
};
pub const RASTRIGIN: Benchmark = Benchmark {
name: "rastrigin",
bound: 5.12,
optimum_value: 0.0,
};
pub const ROSENBROCK: Benchmark = Benchmark {
name: "rosenbrock",
bound: 2.048,
optimum_value: 0.0,
};
pub const ACKLEY: Benchmark = Benchmark {
name: "ackley",
bound: 32.768,
optimum_value: 0.0,
};
pub const GRIEWANK: Benchmark = Benchmark {
name: "griewank",
bound: 600.0,
optimum_value: 0.0,
};
pub const SCHWEFEL: Benchmark = Benchmark {
name: "schwefel",
bound: 500.0,
optimum_value: 0.0,
};
pub const ALL: &[Benchmark] = &[SPHERE, RASTRIGIN, ROSENBROCK, ACKLEY, GRIEWANK, SCHWEFEL];
pub fn meta(name: &str) -> Option<&'static Benchmark> {
ALL.iter().find(|b| b.name == name)
}