Skip to main content

mgh/problems/
watson.rs

1pub fn watson(x: &[f64]) -> f64 {
2    if x.len() < 2 || x.len() > 31 {
3        panic!("input dimension must be 2<=n<=31");
4    }
5    let mut res = 0.0;
6    for i in 1..30 {
7        // t_i = i / 29
8        let t = i as f64 / 29.;
9        
10        // term1 = sum_{j=2}^n (j-1) x_j t_i^{j-2}
11        let l1 = {
12            let mut r = 0.0;
13            for j in 2..(x.len() + 1) {
14                let jndex = j - 1;
15                r += (j as f64 - 1.) * x[jndex] * t.powi(j as i32 - 2);
16            }
17            r
18        };
19        
20        // term2 = (sum_{j=1}^n x_j t_i^{j-1})^2
21        let l2 = {
22            let mut r = 0.0;
23            for j in 1..(x.len() + 1) {
24                let jndex = j - 1;
25                r += x[jndex] * t.powi(j as i32 - 1);
26            }
27            r.powi(2)
28        };
29        
30        // f_i(x) = term1 - term2 - 1
31        res += (l1 - l2 - 1.).powi(2);
32    }
33    let x1 = x[0];
34    let x2 = x[1];
35    // f_30(x) = x_1
36    res += x1.powi(2);
37    // f_31(x) = x_2 - x_1^2 - 1
38    res += (x2 - x1.powi(2) - 1.).powi(2);
39    res
40}
41
42pub fn init(n: usize) -> Vec<f64> {
43    vec![0.; n]
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn test_watson() {
52        let n = 3;
53        let x = init(n);
54        let val = watson(&x);
55        assert!(val.is_finite());
56    }
57
58    #[test]
59    fn test_value_n6() {
60        let n = 6;
61        let x = init(n);
62        let val = watson(&x);
63        // At x=0, f = 30.
64        assert_eq!(val, 30.0);
65    }
66}