math_audio_test_functions/functions/
ackley.rs1use ndarray::Array1;
4
5pub fn ackley(x: &Array1<f64>) -> f64 {
9 let n = x.len() as f64;
10 let sum_sq: f64 = x.iter().map(|&xi| xi.powi(2)).sum();
11 let sum_cos: f64 = x
12 .iter()
13 .map(|&xi| (2.0 * std::f64::consts::PI * xi).cos())
14 .sum();
15
16 -20.0 * (-0.2 * (sum_sq / n).sqrt()).exp() - (sum_cos / n).exp() + 20.0 + std::f64::consts::E
17}
18#[cfg(test)]
19mod tests {
20 use super::*;
21
22 #[test]
23 fn test_ackley_known_properties() {
24 use crate::{FunctionMetadata, get_function_metadata};
25 use ndarray::Array1;
26
27 let metadata = get_function_metadata();
29 let meta = metadata
30 .get("ackley")
31 .expect("Function ackley should have metadata");
32
33 for (minimum_coords, expected_value) in &meta.global_minima {
35 assert!(
36 minimum_coords.len() >= meta.bounds.len() || meta.bounds.len() == 1,
37 "Global minimum coordinates should match bounds dimensions"
38 );
39
40 for (i, &coord) in minimum_coords.iter().enumerate() {
41 if i < meta.bounds.len() {
42 let (lower, upper) = meta.bounds[i];
43 assert!(
44 coord >= lower && coord <= upper,
45 "Global minimum coordinate {} = {} should be within bounds [{} {}]",
46 i,
47 coord,
48 lower,
49 upper
50 );
51 }
52 }
53 }
54
55 let tolerance = 1e-6; for (minimum_coords, expected_value) in &meta.global_minima {
58 let x = Array1::from_vec(minimum_coords.clone());
59 let actual_value = ackley(&x);
60
61 let error = (actual_value - expected_value).abs();
62 assert!(
63 error <= tolerance,
64 "Function value at global minimum {:?} should be {}, got {}, error: {}",
65 minimum_coords,
66 expected_value,
67 actual_value,
68 error
69 );
70 }
71
72 if !meta.global_minima.is_empty() {
74 let (first_minimum, _) = &meta.global_minima[0];
75 let x = Array1::from_vec(first_minimum.clone());
76 let result = ackley(&x);
77
78 assert!(
79 result.is_finite(),
80 "Function should return finite values at global minimum"
81 );
82 assert!(
83 !result.is_nan(),
84 "Function should not return NaN at global minimum"
85 );
86 }
87 }
88}