use std::f64::consts::E;
pub fn brown_and_dennis(x: &[f64], m: usize) -> f64 {
let &[x1, x2, x3, x4] = x else {
panic!("input dimension must be 4");
};
if m < x.len() {
panic!("number of auxiliary function must be at least n");
}
let mut res = 0.;
for i in 1..(m + 1) {
let t = (i as f64) / 5.;
let f = (x1 + t * x2 - E.powf(t)).powi(2) + (x3 + x4 * t.sin() - t.cos()).powi(2);
res += f.powi(2);
}
res
}
pub fn init() -> Vec<f64> {
vec![25., 5., -5., -1.]
}
pub fn min() -> Vec<f64> {
vec![-11.59444, 13.20363, -0.4034395, 0.2367788]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_brown_and_dennis() {
let x = init();
let val = brown_and_dennis(&x, 20);
assert!(val.is_finite());
}
#[test]
fn test_global_minimum() {
let x = min();
let val = brown_and_dennis(&x, 20);
assert!((val - 85822.2).abs() < 1e-1);
}
}