Skip to main content

mgh/problems/
gaussian.rs

1use std::f64::consts::E;
2
3pub fn gaussian(x: &[f64]) -> f64 {
4    let &[x1, x2, x3] = x else {
5        panic!("input dimension must be 3");
6    };
7    let y = vec![
8        0.0009, 0.0044, 0.0175, 0.0540, 0.1295, 0.2420, 0.3521, 0.3989, 0.3521, 0.2420, 0.1295,
9        0.0540, 0.0175, 0.0044, 0.0009,
10    ];
11
12    let mut res = 0.0;
13
14    for (index, item) in y.iter().enumerate().take(15) {
15        let i = index as f64 + 1.;
16
17        // t_i = (8 - i) / 2
18        let t = (8. - i) / 2.;
19
20        // f_i(x) = x_1 exp[-x_2(t_i - x_3)^2 / 2] - y_i
21        let f = x1 * E.powf((-x2 * (t - x3).powi(2)) / 2.) - item;
22        res += f.powi(2);
23    }
24    res
25}
26
27pub fn init() -> Vec<f64> {
28    vec![0.4, 1., 0.]
29}
30
31pub fn min() -> Vec<f64> {
32    vec![0.3989561, 1.0000191, 2.787451e-20]
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn test_gaussian() {
41        let x = init();
42        let val = gaussian(&x);
43        assert!(val.is_finite());
44    }
45
46    #[test]
47    fn test_global_minimum() {
48        let x = min();
49        let val = gaussian(&x);
50        assert!((val - 1.12793e-8).abs() < 1e-10);
51    }
52}