#[cfg(test)]
use std::f64::{MIN_POSITIVE, MAX};
pub fn is_saddle_point(gradient: &[f64], tolerance: f64) -> bool {
gradient.iter().all(|dx| dx.abs() <= tolerance)
}
#[cfg(test)]
#[allow(clippy::float_cmp)]
pub fn are_close(a: f64, b: f64, eps: f64) -> bool {
assert!(eps.is_finite());
let d = (a - b).abs();
a == b
|| ((a == 0.0 || b == 0.0 || d < MIN_POSITIVE) &&
d < eps * MIN_POSITIVE)
|| d / (a + b).min(MAX) < eps
}
#[cfg(test)]
mod tests {
use std::f64::{INFINITY, NAN};
use super::{is_saddle_point, are_close};
#[test]
fn test_is_saddle_point() {
assert!(is_saddle_point(&[1.0, 2.0], 2.0));
assert!(is_saddle_point(&[1.0, -2.0], 2.0));
assert!(!is_saddle_point(&[1.0, 2.1], 2.0));
assert!(!is_saddle_point(&[1.0, -2.1], 2.0));
}
#[test]
fn test_are_close() {
assert!(are_close(1.0, 1.0, 0.00001));
assert!(are_close(INFINITY, INFINITY, 0.00001));
assert!(are_close(1.0e-1000, 0.0, 0.1));
assert!(!are_close(1.0e-40, 0.0, 0.000_001));
assert!(!are_close(2.0, 1.0, 0.00001));
assert!(!are_close(NAN, NAN, 0.00001));
}
}