Skip to main content

math_audio_test_functions/functions/
ridge.rs

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