Skip to main content

math_audio_test_functions/functions/
pinter.rs

1//! Pinter test function
2
3use ndarray::Array1;
4
5/// Pinter function - challenging multimodal function
6/// Global minimum: f(x) = 0 at x = (0, 0, ..., 0)
7/// Bounds: x_i in [-10, 10]
8pub fn pinter(x: &Array1<f64>) -> f64 {
9    let n = x.len();
10    let mut sum1 = 0.0;
11    let mut sum2 = 0.0;
12    let mut sum3 = 0.0;
13
14    for i in 0..n {
15        let ii = (i + 1) as f64;
16        let xi = x[i];
17        let x_prev = if i == 0 { x[n - 1] } else { x[i - 1] };
18        let x_next = if i == n - 1 { x[0] } else { x[i + 1] };
19
20        let ai = x_prev * xi.sin() + (x_next - xi).sin();
21        let bi = x_prev.powi(2) - 2.0 * xi + 3.0 * x_next - (1.0 + xi).cos() + 1.0;
22
23        sum1 += ii * xi.powi(2);
24        sum2 += 20.0 * ii * ai.powi(2).sin();
25        sum3 += ii * (1.0 + ii).ln() * bi.powi(2);
26    }
27
28    sum1 + sum2 + sum3
29}
30#[cfg(test)]
31mod tests {
32    use super::*;
33
34    #[test]
35    fn test_pinter_known_properties() {
36        // Test some properties of the Pinter function
37        use ndarray::Array1;
38
39        // Test the function at origin point
40        let x_origin = Array1::from(vec![0.0, 0.0]);
41        let f_origin = pinter(&x_origin);
42
43        // Function should be finite at origin
44        assert!(
45            f_origin.is_finite(),
46            "Function should be finite at origin: {}",
47            f_origin
48        );
49
50        // Test boundary behavior - should be finite
51        let x_bound = Array1::from(vec![-10.0, 10.0]);
52        let f_bound = pinter(&x_bound);
53        assert!(f_bound.is_finite(), "Function at boundary should be finite");
54
55        // Test a point away from optimum - should be positive
56        let x_away = Array1::from(vec![1.0, 1.0]);
57        let f_away = pinter(&x_away);
58        assert!(
59            f_away > 0.0,
60            "Function away from optimum should be positive: {}",
61            f_away
62        );
63    }
64}