RealComparisons.h
Go to the documentation of this file.
1 /**
2  * @file RealComparisons.h
3  * @brief Class for approximate comparisons
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date November 2, 2016
6  *
7  * This is a header-only library.
8  *
9  */
10 
11 #ifndef LARCORE_COREUTILS_REALCOMPARISONS_H
12 #define LARCORE_COREUTILS_REALCOMPARISONS_H
13 
14 // C/C++ standard libraries
15 #include <cmath> // std::abs()
16 #include <utility> // std::move()
17 
18 
19 namespace lar {
20  namespace util {
21 
22  /** ************************************************************************
23  * @brief Provides simple real number checks
24  * @tparam RealType type of value to operate on
25  *
26  * This class provides some members to perform comparisons between real
27  * numbers, allowing for some tolerance for rounding errors.
28  *
29  * The tolerance parameter is fixed.
30  * Example of usage:
31  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32  *
33  * lar::util::RealComparisons<float> check(1e-5);
34  *
35  * double const sqrt2 = std::sqrt(2);
36  *
37  * // it should print the message
38  * if (check.equal(sqrt2, 1.4142)) {
39  * std::cout
40  * << "Square root of 2 is not even close to 1.4142." << std::endl;
41  * }
42  *
43  * // it should not print the message
44  * if (check.equal(sqrt2, 1.414213)) {
45  * std::cout
46  * << "Square root of 2 is not even close to 1.414213." << std::endl;
47  * }
48  *
49  * // this should print the message
50  * if (check.within(std::sqrt(2), 0., 1.41421)) {
51  * std::cout
52  * << "Square root of 2 is between 0 and 1.41421 (tops)." << std::endl;
53  * }
54  *
55  * // this will probably print the message
56  * double const epsilon = 2.0 - (sqrt2 * sqrt2);
57  * if (check.zero(epsilon)) {
58  * std::cout
59  * << "The square of the square root of 2 is roughly 2." << std::endl;
60  * }
61  *
62  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63  *
64  */
65  template <typename RealType>
66  struct RealComparisons {
67  using Value_t = RealType; /// type of values being compered
68 
69  /// Constructor: specify the threshold
70  constexpr RealComparisons(Value_t threshold): threshold(threshold) {}
71 
72  /// Returns whether the value is no farther from 0 than the threshold
73  constexpr bool zero(Value_t value) const
74  { return std::abs(value) <= threshold; }
75 
76  /// Returns whether the value is farther from 0 than the threshold
77  constexpr bool nonZero(Value_t value) const
78  { return !zero(value); }
79 
80  /// Returns whether a and b are no farther than the threshold
81  constexpr bool equal(Value_t a, Value_t b) const
82  { return zero(a - b); }
83 
84  /// Returns whether a and b are farther than the threshold
85  constexpr bool nonEqual(Value_t a, Value_t b) const
86  { return !equal(a, b); }
87 
88  /// Returns whether value is larger than zero beyond tolerance
89  constexpr bool strictlyNegative(Value_t value) const
90  { return value < -threshold; }
91 
92  /// Returns whether value is smaller than zero beyond tolerance
93  constexpr bool strictlyPositive(Value_t value) const
94  { return value > threshold; }
95 
96  /// Returns whether value is larger than or `equal()` to zero
97  constexpr bool nonNegative(Value_t value) const
98  { return value >= -threshold; }
99 
100  /// Returns whether value is smaller than or `equal()` to zero
101  constexpr bool nonPositive(Value_t value) const
102  { return value <= threshold; }
103 
104  /// Returns whether a is strictly smaller than b
105  constexpr bool strictlySmaller(Value_t a, Value_t b) const
106  { return strictlyNegative(a - b); }
107 
108  /// Returns whether a is greater than (or equal to) b
109  constexpr bool nonSmaller(Value_t a, Value_t b) const
110  { return nonNegative(a - b); }
111 
112  /// Returns whether a is strictly greater than b
113  constexpr bool strictlyGreater(Value_t a, Value_t b) const
114  { return strictlyPositive(a - b); }
115 
116  /// Returns whether a is smaller than (or equal to) b
117  constexpr bool nonGreater(Value_t a, Value_t b) const
118  { return nonPositive(a - b); }
119 
120  /// Returns whether value is between the bounds (included)
121  constexpr bool within(Value_t value, Value_t lower, Value_t upper) const
122  { return nonNegative(value - lower) && nonPositive(value - upper); }
123 
124  /// Returns whether value is between bounds (included); bounds are sorted
125  constexpr bool withinSorted
126  (Value_t value, Value_t lower, Value_t upper) const
127  {
128  return (lower < upper)
129  ? within(value, lower, upper)
130  : within(value, upper, lower)
131  ;
132  } // sortedWithin
133 
134  Value_t threshold; /// Threshold to compare the values to
135 
136  }; // struct RealComparisons<>
137 
138 
139  //--------------------------------------------------------------------------
140  /// Class comparing 2D vectors
141  template <typename RealType>
143 
145 
146  /// Copy the specified comparison.
147  constexpr Vector2DComparison(Comp_t const& comparer)
148  : comparer(comparer) {}
149 
150  /// Steal the specified comparison.
151  Vector2DComparison(Comp_t&& comparer): comparer(std::move(comparer)) {}
152 
153  /// Use the specified threshold.
154  constexpr Vector2DComparison(RealType threshold): comparer(threshold) {}
155 
156  /// Returns the basic value comparer.
157  constexpr Comp_t comp() const { return comparer; }
158 
159  /// Returns whether the specified vector is null (within tolerance).
160  template <typename Vect>
161  constexpr bool zero(Vect const& v) const
162  { return comp().zero(v.X()) && comp().zero(v.Y()); }
163 
164  /// Returns whether the specified vector is not null (within tolerance).
165  template <typename Vect>
166  constexpr bool nonZero(Vect const& v) const { return !zero(v); }
167 
168  /// Returns whether the specified vectors match (within tolerance).
169  template <typename VectA, typename VectB>
170  constexpr bool equal(VectA const& a, VectB const& b) const
171  { return comp().equal(a.X(), b.X()) && comp().equal(a.Y(), b.Y()); }
172 
173  /// Returns whether the specified vectors do not match (within tolerance).
174  template <typename VectA, typename VectB>
175  constexpr bool nonEqual(VectA const& a, VectB const& b) const
176  { return !equal(a, b); }
177 
178  private:
179  Comp_t const comparer; ///< Comparison object.
180 
181  }; // struct Vector2DComparison
182 
183 
184  //--------------------------------------------------------------------------
185  /// Creates a `Vector2DComparison` from a `RealComparisons` object.
186  template <typename RealType>
189 
190  /// Creates a `Vector2DComparison` from a `RealComparisons` object.
191  template <typename RealType>
194  { return Vector2DComparison<RealType>(comp); }
195 
196 
197  //--------------------------------------------------------------------------
198  /// Class comparing 2D vectors.
199  template <typename RealType>
201 
202  /// Type of base value comparer.
204 
205  /// Type of 2D vector comparer.
207 
208  /// Copy the specified comparison.
209  constexpr Vector3DComparison(Comp_t const& comparer)
210  : comparer(comparer) {}
211 
212  /// Steal the specified comparison.
213  Vector3DComparison(Comp_t&& comparer): comparer(std::move(comparer)) {}
214 
215  /// Use the specified threshold.
216  constexpr Vector3DComparison(RealType threshold): comparer(threshold) {}
217 
218  /// Returns the base value comparer.
219  constexpr Comp_t comp() const { return comp2D().comp(); }
220 
221  /// Returns the 2D vector comparer.
222  constexpr Comp2D_t comp2D() const { return comparer; }
223 
224  /// Returns whether the specified vector is null (within tolerance).
225  template <typename Vect>
226  constexpr bool zero(Vect const& v) const
227  { return comp2D().zero(v) && comp().zero(v.Z()); }
228 
229  /// Returns whether the specified vector is not null (within tolerance).
230  template <typename Vect>
231  constexpr bool nonZero(Vect const& v) const { return !zero(v); }
232 
233  /// Returns whether the specified vectors match (within tolerance).
234  template <typename VectA, typename VectB>
235  constexpr bool equal(VectA const& a, VectB const& b) const
236  { return comp2D().equal(a, b) && comp().equal(a.Z(), b.Z()); }
237 
238  /// Returns whether the specified vectors do not match (within tolerance).
239  template <typename VectA, typename VectB>
240  constexpr bool nonEqual(VectA const& a, VectB const& b) const
241  { return !equal(a, b); }
242 
243  private:
245 
246  }; // struct Vector3DComparison
247 
248 
249  //--------------------------------------------------------------------------
250  /// Creates a `Vector3DComparison` from a `RealComparisons` object.
251  template <typename RealType>
254 
255  /// Creates a `Vector3DComparison` from a `RealComparisons` object.
256  template <typename RealType>
259  { return Vector3DComparison<RealType>(comp); }
260 
261 
262  //--------------------------------------------------------------------------
263 
264 
265  } // namespace util
266 } // namespace lar
267 
268 
269 #endif // LARCORE_COREUTILS_REALCOMPARISONS_H
constexpr Vector3DComparison(Comp_t const &comparer)
Copy the specified comparison.
Namespace for general, non-LArSoft-specific utilities.
constexpr bool nonEqual(Value_t a, Value_t b) const
Returns whether a and b are farther than the threshold.
constexpr bool zero(Vect const &v) const
Returns whether the specified vector is null (within tolerance).
Class comparing 2D vectors.
Provides simple real number checks.
constexpr Comp_t comp() const
Returns the basic value comparer.
constexpr bool zero(Value_t value) const
Returns whether the value is no farther from 0 than the threshold.
auto makeVector2DComparison(RealType threshold)
Creates a Vector2DComparison from a RealComparisons object.
STL namespace.
Comp_t const comparer
Comparison object.
constexpr Vector3DComparison(RealType threshold)
Use the specified threshold.
constexpr bool equal(VectA const &a, VectB const &b) const
Returns whether the specified vectors match (within tolerance).
constexpr bool withinSorted(Value_t value, Value_t lower, Value_t upper) const
Returns whether value is between bounds (included); bounds are sorted.
constexpr bool nonEqual(VectA const &a, VectB const &b) const
Returns whether the specified vectors do not match (within tolerance).
constexpr RealComparisons(Value_t threshold)
type of values being compered
constexpr bool strictlySmaller(Value_t a, Value_t b) const
Returns whether a is strictly smaller than b.
constexpr bool strictlyGreater(Value_t a, Value_t b) const
Returns whether a is strictly greater than b.
T abs(T value)
auto makeVector3DComparison(RealType threshold)
Creates a Vector3DComparison from a RealComparisons object.
const double a
def move(depos, offset)
Definition: depos.py:107
constexpr Vector2DComparison(Comp_t const &comparer)
Copy the specified comparison.
Vector2DComparison(Comp_t &&comparer)
Steal the specified comparison.
Class comparing 2D vectors.
constexpr bool strictlyNegative(Value_t value) const
Returns whether value is larger than zero beyond tolerance.
constexpr bool nonGreater(Value_t a, Value_t b) const
Returns whether a is smaller than (or equal to) b.
constexpr Comp_t comp() const
Returns the base value comparer.
constexpr bool strictlyPositive(Value_t value) const
Returns whether value is smaller than zero beyond tolerance.
Vector3DComparison(Comp_t &&comparer)
Steal the specified comparison.
constexpr Vector2DComparison(RealType threshold)
Use the specified threshold.
LArSoft-specific namespace.
constexpr bool nonEqual(VectA const &a, VectB const &b) const
Returns whether the specified vectors do not match (within tolerance).
constexpr bool nonNegative(Value_t value) const
Returns whether value is larger than or equal() to zero.
constexpr bool nonZero(Value_t value) const
Returns whether the value is farther from 0 than the threshold.
constexpr bool zero(Vect const &v) const
Returns whether the specified vector is null (within tolerance).
constexpr bool nonZero(Vect const &v) const
Returns whether the specified vector is not null (within tolerance).
static bool * b
Definition: config.cpp:1043
constexpr bool nonSmaller(Value_t a, Value_t b) const
Returns whether a is greater than (or equal to) b.
constexpr Comp2D_t comp2D() const
Returns the 2D vector comparer.
constexpr bool equal(Value_t a, Value_t b) const
Returns whether a and b are no farther than the threshold.
constexpr bool nonPositive(Value_t value) const
Returns whether value is smaller than or equal() to zero.
constexpr bool within(Value_t value, Value_t lower, Value_t upper) const
Returns whether value is between the bounds (included)
constexpr bool equal(VectA const &a, VectB const &b) const
Returns whether the specified vectors match (within tolerance).
constexpr bool nonZero(Vect const &v) const
Returns whether the specified vector is not null (within tolerance).