Skip to main content

math_audio_test_functions/functions/
gramacy_lee_function.rs

1//! Gramacy Lee Function test function
2
3use ndarray::Array1;
4
5/// Gramacy & Lee (2012) Function - Alternative test function with noise
6/// This is a variant used specifically for Gaussian process testing
7/// Global minimum varies due to noise component
8/// Bounds: x in [0, 1]
9pub fn gramacy_lee_function(x: &Array1<f64>) -> f64 {
10    let x1 = x[0];
11    (x1 * (x1 - 0.5) * (x1 - 1.0)).exp() + x1.powi(2) / 10.0
12}
13#[cfg(test)]
14mod tests {
15    use super::*;
16
17    #[test]
18    fn test_gramacy_lee_function_known_properties() {
19        use crate::{FunctionMetadata, get_function_metadata};
20        use ndarray::Array1;
21
22        // Get metadata for this function
23        let metadata = get_function_metadata();
24        let meta = metadata
25            .get("gramacy_lee_function")
26            .expect("Function gramacy_lee_function should have metadata");
27
28        // Test 1: Verify global minima are within bounds
29        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        // Test 2: Verify function evaluates to expected values at global minima
51        let tolerance = 1e-6; // Reasonable tolerance for numerical precision
52        for (minimum_coords, expected_value) in &meta.global_minima {
53            let x = Array1::from_vec(minimum_coords.clone());
54            let actual_value = gramacy_lee_function(&x);
55
56            let error = (actual_value - expected_value).abs();
57            assert!(
58                error <= tolerance,
59                "Function value at global minimum {:?} should be {}, got {}, error: {}",
60                minimum_coords,
61                expected_value,
62                actual_value,
63                error
64            );
65        }
66
67        // Test 3: Basic function properties
68        if !meta.global_minima.is_empty() {
69            let (first_minimum, _) = &meta.global_minima[0];
70            let x = Array1::from_vec(first_minimum.clone());
71            let result = gramacy_lee_function(&x);
72
73            assert!(
74                result.is_finite(),
75                "Function should return finite values at global minimum"
76            );
77            assert!(
78                !result.is_nan(),
79                "Function should not return NaN at global minimum"
80            );
81        }
82    }
83}