Skip to content

Commit

Permalink
Use proptest to compare Rosenbrock derivative and Hessian to finitedi…
Browse files Browse the repository at this point in the history
…ff results
  • Loading branch information
stefan-k committed Feb 3, 2024
1 parent e247521 commit fa33b04
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 42 deletions.
1 change: 1 addition & 0 deletions crates/argmin-testfunctions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ num = "0.4"
approx = "0.5"
finitediff = "0.1.4"
paste = "1.0"
proptest = "1.4.0"

[badges]
maintenance = { status = "actively-developed" }
121 changes: 79 additions & 42 deletions crates/argmin-testfunctions/src/rosenbrock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ mod tests {
use super::*;
use approx::assert_relative_eq;
use finitediff::FiniteDiff;
use proptest::prelude::*;

#[test]
fn test_rosenbrock_optimum() {
Expand Down Expand Up @@ -187,26 +188,6 @@ mod tests {
}
}

#[test]
fn test_rosenbrock_derivative_finitediff() {
let param = [-0.3, 1.0, 0.1, 0.3, 0.2, -0.3, 0.2, 0.7];
let derivative = rosenbrock_derivative(&param, 1.0, 100.0);
let derivative_fd = Vec::from(param).central_diff(&|x| rosenbrock(&x, 1.0, 100.0));
for i in 0..derivative.len() {
assert_relative_eq!(derivative[i], derivative_fd[i], epsilon = 1e-4);
}
}

#[test]
fn test_rosenbrock_derivative_const_finitediff() {
let param = [-0.3, 1.0, 0.1, 0.3, 0.2, -0.3, 0.2, 0.7];
let derivative = rosenbrock_derivative_const(&param, 1.0, 100.0);
let derivative_fd = Vec::from(param).central_diff(&|x| rosenbrock(&x, 1.0, 100.0));
for i in 0..derivative.len() {
assert_relative_eq!(derivative[i], derivative_fd[i], epsilon = 1e-4);
}
}

#[test]
fn test_rosenbrock_hessian() {
// Same testcase as in scipy
Expand Down Expand Up @@ -245,32 +226,88 @@ mod tests {
}
}

#[test]
fn test_rosenbrock_hessian_finitediff() {
let param = [1.2_f64, 0.1, -1.0, 0.1, -0.3, 1.5, 0.9, 1.1];
let hessian = rosenbrock_hessian(&param, 1.0, 100.0);
let hessian_fd =
Vec::from(param).forward_hessian(&|x| rosenbrock_derivative(&x, 1.0, 100.0));
let n = hessian.len();
for i in 0..n {
assert_eq!(hessian[i].len(), n);
for j in 0..n {
assert_relative_eq!(hessian[i][j], hessian_fd[i][j], epsilon = 1e-4);
proptest! {
#[test]
fn test_rosenbrock_derivative_finitediff(a in -1.0..1.0,
b in -1.0..1.0,
c in -1.0..1.0,
d in -1.0..1.0,
e in -1.0..1.0,
f in -1.0..1.0,
g in -1.0..1.0,
h in -1.0..1.0) {
let param = [a, b, c, d, e, f, g, h];
let derivative = rosenbrock_derivative(&param, 1.0, 100.0);
let derivative_fd = Vec::from(param).central_diff(&|x| rosenbrock(&x, 1.0, 100.0));
for i in 0..derivative.len() {
assert_relative_eq!(derivative[i], derivative_fd[i], epsilon = 1e-4);
}
}
}

#[test]
fn test_rosenbrock_hessian_const_finitediff() {
let param = [1.2_f64, 0.1, -1.0, 0.1, -0.3, 1.5, 0.9, 1.1];
let hessian = rosenbrock_hessian_const(&param, 1.0, 100.0);
let hessian_fd =
Vec::from(param).forward_hessian(&|x| rosenbrock_derivative(&x, 1.0, 100.0));
let n = hessian.len();
for i in 0..n {
assert_eq!(hessian[i].len(), n);
for j in 0..n {
assert_relative_eq!(hessian[i][j], hessian_fd[i][j], epsilon = 1e-4);
proptest! {
#[test]
fn test_rosenbrock_derivative_const_finitediff(a in -1.0..1.0,
b in -1.0..1.0,
c in -1.0..1.0,
d in -1.0..1.0,
e in -1.0..1.0,
f in -1.0..1.0,
g in -1.0..1.0,
h in -1.0..1.0) {
let param = [a, b, c, d, e, f, g, h];
let derivative = rosenbrock_derivative_const(&param, 1.0, 100.0);
let derivative_fd = Vec::from(param).central_diff(&|x| rosenbrock(&x, 1.0, 100.0));
for i in 0..derivative.len() {
assert_relative_eq!(derivative[i], derivative_fd[i], epsilon = 1e-4);
}
}
}

proptest! {
#[test]
fn test_rosenbrock_hessian_finitediff(a in -1.0..1.0,
b in -1.0..1.0,
c in -1.0..1.0,
d in -1.0..1.0,
e in -1.0..1.0,
f in -1.0..1.0,
g in -1.0..1.0,
h in -1.0..1.0) {
let param = [a, b, c, d, e, f, g, h];
let hessian = rosenbrock_hessian(&param, 1.0, 100.0);
let hessian_fd =
Vec::from(param).forward_hessian(&|x| rosenbrock_derivative(&x, 1.0, 100.0));
let n = hessian.len();
for i in 0..n {
assert_eq!(hessian[i].len(), n);
for j in 0..n {
assert_relative_eq!(hessian[i][j], hessian_fd[i][j], epsilon = 1e-4);
}
}
}
}

proptest! {
#[test]
fn test_rosenbrock_hessian_const_finitediff(a in -1.0..1.0,
b in -1.0..1.0,
c in -1.0..1.0,
d in -1.0..1.0,
e in -1.0..1.0,
f in -1.0..1.0,
g in -1.0..1.0,
h in -1.0..1.0) {
let param = [a, b, c, d, e, f, g, h];
let hessian = rosenbrock_hessian_const(&param, 1.0, 100.0);
let hessian_fd =
Vec::from(param).forward_hessian(&|x| rosenbrock_derivative(&x, 1.0, 100.0));
let n = hessian.len();
for i in 0..n {
assert_eq!(hessian[i].len(), n);
for j in 0..n {
assert_relative_eq!(hessian[i][j], hessian_fd[i][j], epsilon = 1e-4);
}
}
}
}
Expand Down

0 comments on commit fa33b04

Please sign in to comment.