math_audio_test_functions/functions/
shekel.rs1use ndarray::Array1;
4
5pub fn shekel(x: &Array1<f64>) -> f64 {
9 let m = 10; let a = [
11 [4.0, 4.0, 4.0, 4.0],
12 [1.0, 1.0, 1.0, 1.0],
13 [8.0, 8.0, 8.0, 8.0],
14 [6.0, 6.0, 6.0, 6.0],
15 [3.0, 7.0, 3.0, 7.0],
16 [2.0, 9.0, 2.0, 9.0],
17 [5.0, 5.0, 3.0, 3.0],
18 [8.0, 1.0, 8.0, 1.0],
19 [6.0, 2.0, 6.0, 2.0],
20 [7.0, 3.6, 7.0, 3.6],
21 ];
22 let c = [0.1, 0.2, 0.2, 0.4, 0.4, 0.6, 0.3, 0.7, 0.5, 0.5];
23
24 let mut sum = 0.0;
25 for i in 0..m.min(10) {
26 let mut inner_sum = 0.0;
27 for j in 0..4.min(x.len()) {
28 inner_sum += (x[j] - a[i][j]).powi(2);
29 }
30 sum += 1.0 / (inner_sum + c[i]);
31 }
32 -sum
33}
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn test_shekel_known_properties() {
40 use crate::{FunctionMetadata, get_function_metadata};
41 use ndarray::Array1;
42
43 let metadata = get_function_metadata();
45 let meta = metadata
46 .get("shekel")
47 .expect("Function shekel should have metadata");
48
49 for (minimum_coords, expected_value) in &meta.global_minima {
51 assert!(
52 minimum_coords.len() >= meta.bounds.len() || meta.bounds.len() == 1,
53 "Global minimum coordinates should match bounds dimensions"
54 );
55
56 for (i, &coord) in minimum_coords.iter().enumerate() {
57 if i < meta.bounds.len() {
58 let (lower, upper) = meta.bounds[i];
59 assert!(
60 coord >= lower && coord <= upper,
61 "Global minimum coordinate {} = {} should be within bounds [{} {}]",
62 i,
63 coord,
64 lower,
65 upper
66 );
67 }
68 }
69 }
70
71 for (minimum_coords, expected_value) in &meta.global_minima {
73 let x = Array1::from_vec(minimum_coords.clone());
74 let actual_value = shekel(&x);
75
76 let error = (actual_value - expected_value).abs();
77 let tolerance = if expected_value.abs() > 1.0 {
79 1e-4 * expected_value.abs() } else {
81 1e-6 };
83
84 assert!(
85 error <= tolerance,
86 "Function value at global minimum {:?} should be {}, got {}, error: {} (tolerance: {})",
87 minimum_coords,
88 expected_value,
89 actual_value,
90 error,
91 tolerance
92 );
93 }
94
95 if !meta.global_minima.is_empty() {
97 let (first_minimum, _) = &meta.global_minima[0];
98 let x = Array1::from_vec(first_minimum.clone());
99 let result = shekel(&x);
100
101 assert!(
102 result.is_finite(),
103 "Function should return finite values at global minimum"
104 );
105 assert!(
106 !result.is_nan(),
107 "Function should not return NaN at global minimum"
108 );
109 }
110 }
111}