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