argmin_testfunctions/
matyas.rs1use num::{Float, FromPrimitive};
21
22pub fn matyas<T>(param: &[T; 2]) -> T
34where
35 T: Float + FromPrimitive,
36{
37 let [x1, x2] = *param;
38
39 let n026 = T::from_f64(0.26).unwrap();
40 let n048 = T::from_f64(0.48).unwrap();
41
42 n026 * (x1.powi(2) + x2.powi(2)) - n048 * x1 * x2
43}
44
45pub fn matyas_derivative<T>(param: &[T; 2]) -> [T; 2]
47where
48 T: Float + FromPrimitive,
49{
50 let [x1, x2] = *param;
51
52 let n0_52 = T::from_f64(0.52).unwrap();
53 let n0_48 = T::from_f64(0.48).unwrap();
54
55 [n0_52 * x1 - n0_48 * x2, n0_52 * x2 - n0_48 * x1]
56}
57
58pub fn matyas_hessian<T>(_param: &[T; 2]) -> [[T; 2]; 2]
71where
72 T: Float + FromPrimitive,
73{
74 let n0_52 = T::from_f64(0.52).unwrap();
75 let n0_48 = T::from_f64(0.48).unwrap();
76
77 [[n0_52, -n0_48], [-n0_48, n0_52]]
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use approx::assert_relative_eq;
84 use finitediff::FiniteDiff;
85 use proptest::prelude::*;
86 use std::{f32, f64};
87
88 #[test]
89 fn test_matyas_optimum() {
90 assert_relative_eq!(matyas(&[0_f32, 0_f32]), 0.0, epsilon = f32::EPSILON);
91 assert_relative_eq!(matyas(&[0_f64, 0_f64]), 0.0, epsilon = f64::EPSILON);
92
93 let deriv = matyas_derivative(&[0.0, 0.0]);
94 for i in 0..2 {
95 assert_relative_eq!(deriv[i], 0.0, epsilon = f64::EPSILON);
96 }
97 }
98
99 proptest! {
100 #[test]
101 fn test_matyas_derivative(a in -10.0..10.0, b in -10.0..10.0) {
102 let param = [a, b];
103 let derivative = matyas_derivative(¶m);
104 let derivative_fd = Vec::from(param).central_diff(&|x| matyas(&[x[0], x[1]]));
105 for i in 0..derivative.len() {
106 assert_relative_eq!(
107 derivative[i],
108 derivative_fd[i],
109 epsilon = 1e-5,
110 max_relative = 1e-2
111 );
112 }
113 }
114 }
115
116 proptest! {
117 #[test]
118 fn test_matyas_hessian(a in -10.0..10.0, b in -10.0..10.0) {
119 let param = [a, b];
120 let hessian = matyas_hessian(¶m);
121 let hessian_fd = [[0.52, -0.48], [-0.48, 0.52]];
122 let n = hessian.len();
123 for i in 0..n {
124 assert_eq!(hessian[i].len(), n);
125 for j in 0..n {
126 assert_relative_eq!(
127 hessian[i][j],
128 hessian_fd[i][j],
129 epsilon = 1e-5,
130 max_relative = 1e-2
131 );
132 }
133 }
134 }
135 }
136}