diff --git a/src/bin/flat/main.rs b/src/bin/flat/main.rs index a3e28bb..9421d6e 100644 --- a/src/bin/flat/main.rs +++ b/src/bin/flat/main.rs @@ -666,7 +666,33 @@ mod fns { #[cfg(test)] mod test { - use approx::{abs_diff_eq, assert_abs_diff_eq}; + use approx::{abs_diff_eq, AbsDiffEq, assert_abs_diff_eq}; + + #[test] + fn test_tube_x() { + let testee = super::TubeX { min: 20.0, max: 30.0 }; + let ε = 1.0e-4f32; + let δ = 1.0 / 8.0; // Mathematically, you want this to be small. Computationally, you don’t. + let margin = 1.0 / 16.0; + let mul = 1.0 + margin; + for x in itertools_num::linspace(0., testee.min, 10) { + assert_abs_diff_eq!(testee.value(x), 0., epsilon = ε); + assert_abs_diff_eq!(testee.value(-x), 0., epsilon = ε); + } + for x in itertools_num::linspace(testee.max, mul * testee.max, 10) { + assert_abs_diff_eq!(testee.value(x), 1., epsilon = ε); + assert_abs_diff_eq!(testee.value(-x), 1., epsilon = ε); + } + for x in itertools_num::linspace(-mul * testee.max, mul * testee.max, 100) { + // Currently, the derivative is discontinuous at ±min and ±max... let’s just skip these for now. + if x.abs().abs_diff_eq(&testee.min, δ) || x.abs().abs_diff_eq(&testee.max, δ) { + continue; + } + let df_num = (testee.value(x + δ) - testee.value(x - δ)) / (2. * δ); + let df_expl = testee.derivative(x); + assert!(abs_diff_eq!(df_expl, df_num, epsilon = ε), "At x={}, df/dx:\nnumerical: {}\nexplicit: {}\n", x, df_num, df_expl); + } + } #[test] fn test_tube_y() {