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}