Skip to main content

math_audio_test_functions/functions/
sphere.rs

1//! Sphere test function
2
3use ndarray::Array1;
4
5/// Basic sphere function for testing
6/// f(x) = sum(x\[i\]^2)
7/// Same as quadratic, but kept separate for clarity in different test contexts
8pub fn sphere(x: &Array1<f64>) -> f64 {
9    x.iter().map(|&v| v * v).sum()
10}
11#[cfg(test)]
12mod tests {
13    use super::*;
14
15    #[test]
16    fn test_sphere_known_properties() {
17        use crate::{FunctionMetadata, get_function_metadata};
18        use ndarray::Array1;
19
20        // Get metadata for this function
21        let metadata = get_function_metadata();
22        let meta = metadata
23            .get("sphere")
24            .expect("Function sphere should have metadata");
25
26        // Test 1: Verify global minima are within bounds
27        for (minimum_coords, expected_value) in &meta.global_minima {
28            assert!(
29                minimum_coords.len() >= meta.bounds.len() || meta.bounds.len() == 1,
30                "Global minimum coordinates should match bounds dimensions"
31            );
32
33            for (i, &coord) in minimum_coords.iter().enumerate() {
34                if i < meta.bounds.len() {
35                    let (lower, upper) = meta.bounds[i];
36                    assert!(
37                        coord >= lower && coord <= upper,
38                        "Global minimum coordinate {} = {} should be within bounds [{} {}]",
39                        i,
40                        coord,
41                        lower,
42                        upper
43                    );
44                }
45            }
46        }
47
48        // Test 2: Verify function evaluates to expected values at global minima
49        let tolerance = 1e-6; // Reasonable tolerance for numerical precision
50        for (minimum_coords, expected_value) in &meta.global_minima {
51            let x = Array1::from_vec(minimum_coords.clone());
52            let actual_value = sphere(&x);
53
54            let error = (actual_value - expected_value).abs();
55            assert!(
56                error <= tolerance,
57                "Function value at global minimum {:?} should be {}, got {}, error: {}",
58                minimum_coords,
59                expected_value,
60                actual_value,
61                error
62            );
63        }
64
65        // Test 3: Basic function properties
66        if !meta.global_minima.is_empty() {
67            let (first_minimum, _) = &meta.global_minima[0];
68            let x = Array1::from_vec(first_minimum.clone());
69            let result = sphere(&x);
70
71            assert!(
72                result.is_finite(),
73                "Function should return finite values at global minimum"
74            );
75            assert!(
76                !result.is_nan(),
77                "Function should not return NaN at global minimum"
78            );
79        }
80    }
81}