Skip to main content

math_audio_test_functions/functions/
langermann.rs

1//! Langermann test function
2
3use ndarray::Array1;
4
5/// Langermann function - complex multimodal with parameters
6/// Global minimum: f(x) ≈ -5.1621 at complex optimum
7/// Bounds: x_i in [0, 10]
8pub fn langermann(x: &Array1<f64>) -> f64 {
9    // Langermann function parameters (for 2D)
10    let a = [[3.0, 5.0], [5.0, 2.0], [2.0, 1.0], [1.0, 4.0], [7.0, 9.0]];
11    let c = [1.0, 2.0, 5.0, 2.0, 3.0];
12
13    let mut sum = 0.0;
14    for i in 0..5 {
15        let mut inner_sum = 0.0;
16        for j in 0..2.min(x.len()) {
17            inner_sum += (x[j] - a[i][j]).powi(2);
18        }
19        sum += c[i]
20            * (-inner_sum / std::f64::consts::PI).exp()
21            * (std::f64::consts::PI * inner_sum).cos();
22    }
23    -sum
24}
25#[cfg(test)]
26mod tests {
27    use super::*;
28
29    #[test]
30    fn test_langermann_known_properties() {
31        // Test some properties of the Langermann function
32        use ndarray::Array1;
33
34        // Test that function is finite at various points within bounds
35        let test_points = vec![
36            vec![2.0, 1.0], // Near one of the parameter points
37            vec![5.0, 2.0], // Near another parameter point
38            vec![7.0, 9.0], // Near the third parameter point
39            vec![1.0, 4.0], // Near the fourth parameter point
40            vec![0.5, 0.5], // Corner region
41            vec![9.5, 9.5], // Other corner
42        ];
43
44        for point in test_points {
45            let x = Array1::from(point.clone());
46            let f = langermann(&x);
47
48            assert!(
49                f.is_finite(),
50                "Function should be finite at {:?}: {}",
51                point,
52                f
53            );
54            // Langermann can have both positive and negative values
55        }
56
57        // Test boundary behavior
58        let x_boundary = Array1::from(vec![0.0, 10.0]);
59        let f_boundary = langermann(&x_boundary);
60        assert!(
61            f_boundary.is_finite(),
62            "Function at boundary should be finite"
63        );
64
65        let x_corner = Array1::from(vec![10.0, 0.0]);
66        let f_corner = langermann(&x_corner);
67        assert!(f_corner.is_finite(), "Function at corner should be finite");
68    }
69}