Skip to content

Commit 544732b

Browse files
committed
Added derivative and Hessian for threehumpcamel test function
1 parent f255ade commit 544732b

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Seeds for failure cases proptest has generated in the past. It is
2+
# automatically read and these particular cases re-run before any
3+
# novel cases are generated.
4+
#
5+
# It is recommended to check this file in to source control so that
6+
# everyone who runs the test benefits from these saved cases.
7+
cc 9076a0773c14764cdd90e176eea628f6a23e94485a9abdf98ebb23f295b3148d # shrinks to a = 4.762068035560005, b = 0.0
8+
cc 14f333bf7f7348d8cfbb3732499c69387c1e1f92de37b7347296df760f7f4019 # shrinks to a = 4.183760169614706, b = -2.0285743566314984
9+
cc 19d4b7948cc1fd0ea46016d4f357b24aa6d1a37d8afdbfe980f2e93c7d648b7e # shrinks to a = 4.672572529015701, b = 0.0
10+
cc e58163502f9d04f24664ffb602f05bb5daad2f84d94f07e2522b49446b17249f # shrinks to a = 4.954327515861796, b = -2.4636603000647304
11+
cc d3ae78f96834a1bf181153d45c51e444cf398b326c10e7eb429ededc47801e4c # shrinks to a = 1.4578585137075646, b = 0.0
12+
cc fe1b1bc0615cb469d0e3fbc77d571548ac20f458ec2009d30a6f80daaf966e5e

crates/argmin-testfunctions/src/threehumpcamel.rs

+84
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,46 @@ where
3838
+ x2.powi(2)
3939
}
4040

41+
/// Derivative of Three-hump camel test function
42+
pub fn threehumpcamel_derivative<T>(param: &[T; 2]) -> [T; 2]
43+
where
44+
T: Float + FromPrimitive,
45+
{
46+
let [x1, x2] = *param;
47+
48+
let n2 = T::from_f64(2.0).unwrap();
49+
let n4 = T::from_f64(4.0).unwrap();
50+
let n4_2 = T::from_f64(4.2).unwrap();
51+
52+
[x1.powi(5) - n4_2 * x1.powi(3) + n4 * x1 + x2, n2 * x2 + x1]
53+
}
54+
55+
/// Hessian of Three-hump camel test function
56+
pub fn threehumpcamel_hessian<T>(param: &[T; 2]) -> [[T; 2]; 2]
57+
where
58+
T: Float + FromPrimitive,
59+
{
60+
let [x1, _] = *param;
61+
62+
let n1 = T::from_f64(1.0).unwrap();
63+
let n2 = T::from_f64(2.0).unwrap();
64+
let n4 = T::from_f64(4.0).unwrap();
65+
let n5 = T::from_f64(5.0).unwrap();
66+
let n12_6 = T::from_f64(12.6).unwrap();
67+
68+
let a = n5 * x1.powi(4) - n12_6 * x1.powi(2) + n4;
69+
let b = n2;
70+
let offdiag = n1;
71+
72+
[[a, offdiag], [offdiag, b]]
73+
}
74+
4175
#[cfg(test)]
4276
mod tests {
4377
use super::*;
4478
use approx::assert_relative_eq;
79+
use finitediff::FiniteDiff;
80+
use proptest::prelude::*;
4581
use std::{f32, f64};
4682

4783
#[test]
@@ -56,5 +92,53 @@ mod tests {
5692
0.0,
5793
epsilon = f64::EPSILON
5894
);
95+
96+
let deriv = threehumpcamel_derivative(&[0.0, 0.0]);
97+
for i in 0..2 {
98+
assert_relative_eq!(deriv[i], 0.0, epsilon = f64::EPSILON);
99+
}
100+
}
101+
102+
proptest! {
103+
#[test]
104+
fn test_threehumpcamel_derivative(a in -5.0..5.0, b in -5.0..5.0) {
105+
let param = [a, b];
106+
let derivative = threehumpcamel_derivative(&param);
107+
let derivative_fd = Vec::from(param).central_diff(&|x| threehumpcamel(&[x[0], x[1]]));
108+
for i in 0..derivative.len() {
109+
assert_relative_eq!(
110+
derivative[i],
111+
derivative_fd[i],
112+
epsilon = f64::EPSILON,
113+
max_relative = 1e-3
114+
);
115+
}
116+
}
117+
}
118+
119+
proptest! {
120+
#[test]
121+
fn test_threehumpcamel_hessian_finitediff(a in -5.0..5.0, b in -5.0..5.0) {
122+
let param = [a, b];
123+
let hessian = threehumpcamel_hessian(&param);
124+
let hessian_fd =
125+
Vec::from(param).central_hessian(&|x| threehumpcamel_derivative(&[x[0], x[1]]).to_vec());
126+
let n = hessian.len();
127+
println!("1: {hessian:?} at {a}/{b}");
128+
println!("2: {hessian_fd:?} at {a}/{b}");
129+
for i in 0..n {
130+
assert_eq!(hessian[i].len(), n);
131+
for j in 0..n {
132+
if hessian_fd[i][j].is_finite() {
133+
assert_relative_eq!(
134+
hessian[i][j],
135+
hessian_fd[i][j],
136+
epsilon = f64::EPSILON,
137+
max_relative = 1e-5
138+
);
139+
}
140+
}
141+
}
142+
}
59143
}
60144
}

0 commit comments

Comments
 (0)