nearly/
nearly_eq.rs

1use crate::tolerance::{
2    EpsTolerance, EpsToleranceType, Tolerance, UlpsTolerance, UlpsToleranceType,
3};
4
5/// A trait for nearly equality comparison based on an absolute epsilon value.
6pub trait NearlyEqEps<Rhs = Self, LhsTol = Self, RhsTol = Rhs>
7where
8    Rhs: ?Sized,
9    LhsTol: ?Sized + EpsTolerance<RhsTol>,
10    RhsTol: ?Sized,
11{
12    /// Returns whether `self` is nearly equal to `other` based on an absolute epsilon value `eps`.
13    fn nearly_eq_eps(&self, other: &Rhs, eps: &EpsToleranceType<LhsTol, RhsTol>) -> bool;
14
15    /// Returns whether `self` is nearly not equal to `other` based on an absolute epsilon value `eps`.
16    #[inline]
17    fn nearly_ne_eps(&self, other: &Rhs, eps: &EpsToleranceType<LhsTol, RhsTol>) -> bool {
18        !self.nearly_eq_eps(other, eps)
19    }
20}
21
22/// A trait for nearly equality comparison based on an ulps value.
23pub trait NearlyEqUlps<Rhs = Self, LhsTol = Self, RhsTol = Rhs>
24where
25    Rhs: ?Sized,
26    LhsTol: ?Sized + UlpsTolerance<RhsTol>,
27    RhsTol: ?Sized,
28{
29    /// Returns whether `self`is nearly equal to `other` based on an ulps value `ulps`.
30    fn nearly_eq_ulps(&self, other: &Rhs, ulps: &UlpsToleranceType<LhsTol, RhsTol>) -> bool;
31
32    /// Returns whether `self`is not nearly equal to `other` based on an ulps value `ulps`.
33    #[inline]
34    fn nearly_ne_ulps(&self, other: &Rhs, ulps: &UlpsToleranceType<LhsTol, RhsTol>) -> bool {
35        !self.nearly_eq_ulps(other, ulps)
36    }
37}
38
39/// A trait for nearly equality comparison based on a tolerance including an absolute epsilon value
40/// and an ulps value.
41///
42/// See [Tolerance].
43/// This trait combines the traits [NearlyEqEps] and [NearlyEqUlps].
44pub trait NearlyEqTol<Rhs = Self, LhsTol = Self, RhsTol = Rhs>:
45    NearlyEqEps<Rhs, LhsTol, RhsTol> + NearlyEqUlps<Rhs, LhsTol, RhsTol>
46where
47    Rhs: ?Sized,
48    LhsTol: ?Sized + EpsTolerance<RhsTol> + UlpsTolerance<RhsTol>,
49    RhsTol: ?Sized,
50{
51    /// Returns whether `self` is nearly equal to `other` based on a tolerance `tol`.
52    ///
53    /// Returns true if either `self` is nearly equal to `other` based on an absolute epsilon value
54    /// `tol.eps` or `self` is nearly equal to `other` based on an ulps value `tol.ulps`.
55    #[inline]
56    fn nearly_eq_tol(&self, other: &Rhs, tol: &Tolerance<LhsTol, RhsTol>) -> bool {
57        self.nearly_eq_eps(other, &tol.eps) || self.nearly_eq_ulps(other, &tol.ulps)
58    }
59
60    /// Returns whether `self` is not nearly equal to `other` based on a tolerance `tol`.
61    ///
62    /// Returns true if both `self` is not nearly equal to `other` based on an absolute epsilon value
63    /// `tol.eps` ans `self`is not nearly equal to `other` based on an ulps value
64    /// `tol.ulps`.
65    #[inline]
66    fn nearly_ne_tol(&self, other: &Rhs, tol: &Tolerance<LhsTol, RhsTol>) -> bool {
67        !self.nearly_eq_tol(other, tol)
68    }
69}
70
71/// A trait for nearly equality comparison based on a default tolerance.
72///
73/// This trait is a convenience trait to use nearly equality comparison with a default tolerances.
74/// This is the same as using the [NearlyEqTol] trait with [Tolerance::default()].
75pub trait NearlyEq<Rhs = Self, LhsTol = Self, RhsTol = Rhs>:
76    NearlyEqTol<Rhs, LhsTol, RhsTol>
77where
78    Rhs: ?Sized,
79    LhsTol: ?Sized + EpsTolerance<RhsTol> + UlpsTolerance<RhsTol>,
80    RhsTol: ?Sized,
81{
82    /// Returns whether `self` is nearly equal to `other` based on the default tolerance for
83    /// comparisons of `Self` with `other`.
84    #[inline]
85    fn nearly_eq(&self, other: &Rhs) -> bool {
86        self.nearly_eq_tol(other, &Tolerance::<LhsTol, RhsTol>::default())
87    }
88
89    /// Returns whether `self` is not nearly equal to `other` based on the default tolerance for
90    /// comparisons of `Self` with `other`.
91    #[inline]
92    fn nearly_ne(&self, other: &Rhs) -> bool {
93        !self.nearly_eq(other)
94    }
95}