USRP Hardware Driver and USRP Manual  Version: 3.15.0.HEAD-0-gaea0e2de
UHD and USRP Manual
math.hpp
Go to the documentation of this file.
1 //
2 // Copyright 2014-2015 Ettus Research LLC
3 // Copyright 2018 Ettus Research, a National Instruments Company
4 //
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 
8 #ifndef INCLUDED_UHD_UTILS_MATH_HPP
9 #define INCLUDED_UHD_UTILS_MATH_HPP
10 
11 #include <uhd/config.hpp>
12 #include <stdint.h>
13 #include <boost/numeric/conversion/bounds.hpp>
14 #include <cmath>
15 #if BOOST_VERSION >= 106700
16 # include <boost/integer/common_factor.hpp>
17 // "bmint" for "boost math integer"
18 namespace _bmint = boost::integer;
19 #else
20 # include <boost/math/common_factor.hpp>
21 namespace _bmint = boost::math;
22 #endif
23 
24 
25 namespace uhd {
26 
31 namespace math {
32 
49 static const float SINGLE_PRECISION_EPSILON = 1.19e-7f;
50 static const double DOUBLE_PRECISION_EPSILON = 2.22e-16;
51 
52 namespace fp_compare {
53 
67 template <typename float_t> class fp_compare_epsilon
68 {
69 public:
70  UHD_INLINE fp_compare_epsilon(float_t value);
71  UHD_INLINE fp_compare_epsilon(float_t value, float_t epsilon);
74  UHD_INLINE void operator=(const fp_compare_epsilon& copy);
75 
76  float_t _value;
77  float_t _epsilon;
78 };
79 
80 /* A Note on Floating Point Equality with Epsilons
81  *
82  * There are obviously a lot of strategies for defining floating point
83  * equality, and in the end it all comes down to the domain at hand. UHD's
84  * floating-point-with-epsilon comparison algorithm is based on the method
85  * presented in Knuth's "The Art of Computer Science" called "very close
86  * with tolerance epsilon".
87  *
88  * [(|u - v| / |u|) <= e] && [(|u - v| / |v|) <= e]
89  *
90  * UHD's modification to this algorithm is using the denominator's epsilon
91  * value (since each float_t object has its own epsilon) for each
92  * comparison.
93  */
94 
95 template <typename float_t>
98 template <typename float_t>
101 template <typename float_t>
102 UHD_INLINE bool operator<(
104 template <typename float_t>
107 template <typename float_t>
108 UHD_INLINE bool operator>(
110 template <typename float_t>
113 
114 /* If these operators are used with floats, we rely on type promotion to
115  * double. */
116 template <typename float_t>
118 template <typename float_t>
120 template <typename float_t>
121 UHD_INLINE bool operator<(fp_compare_epsilon<float_t> lhs, double rhs);
122 template <typename float_t>
123 UHD_INLINE bool operator<=(fp_compare_epsilon<float_t> lhs, double rhs);
124 template <typename float_t>
125 UHD_INLINE bool operator>(fp_compare_epsilon<float_t> lhs, double rhs);
126 template <typename float_t>
128 
129 template <typename float_t>
131 template <typename float_t>
133 template <typename float_t>
134 UHD_INLINE bool operator<(double lhs, fp_compare_epsilon<float_t> rhs);
135 template <typename float_t>
136 UHD_INLINE bool operator<=(double lhs, fp_compare_epsilon<float_t> rhs);
137 template <typename float_t>
138 UHD_INLINE bool operator>(double lhs, fp_compare_epsilon<float_t> rhs);
139 template <typename float_t>
141 
142 } // namespace fp_compare
143 
144 
151 static const float SINGLE_PRECISION_DELTA = 1e-3f;
152 static const double DOUBLE_PRECISION_DELTA = 1e-5;
153 
155 static const double FREQ_COMPARISON_DELTA_HZ = 0.1;
156 
157 
158 namespace fp_compare {
159 
173 template <typename float_t> class fp_compare_delta
174 {
175 public:
176  UHD_INLINE fp_compare_delta(float_t value);
177  UHD_INLINE fp_compare_delta(float_t value, float_t delta);
178  UHD_INLINE fp_compare_delta(const fp_compare_delta<float_t>& copy);
179  UHD_INLINE ~fp_compare_delta();
180  UHD_INLINE void operator=(const fp_compare_delta& copy);
181 
182  float_t _value;
183  float_t _delta;
184 };
185 
186 template <typename float_t>
188 template <typename float_t>
190 template <typename float_t>
191 UHD_INLINE bool operator<(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
192 template <typename float_t>
193 UHD_INLINE bool operator<=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
194 template <typename float_t>
196 template <typename float_t>
198 
199 /* If these operators are used with floats, we rely on type promotion to
200  * double. */
201 template <typename float_t>
202 UHD_INLINE bool operator==(fp_compare_delta<float_t> lhs, double rhs);
203 template <typename float_t>
204 UHD_INLINE bool operator!=(fp_compare_delta<float_t> lhs, double rhs);
205 template <typename float_t>
206 UHD_INLINE bool operator<(fp_compare_delta<float_t> lhs, double rhs);
207 template <typename float_t>
208 UHD_INLINE bool operator<=(fp_compare_delta<float_t> lhs, double rhs);
209 template <typename float_t>
210 UHD_INLINE bool operator>(fp_compare_delta<float_t> lhs, double rhs);
211 template <typename float_t>
212 UHD_INLINE bool operator>=(fp_compare_delta<float_t> lhs, double rhs);
213 
214 template <typename float_t>
215 UHD_INLINE bool operator==(double lhs, fp_compare_delta<float_t> rhs);
216 template <typename float_t>
217 UHD_INLINE bool operator!=(double lhs, fp_compare_delta<float_t> rhs);
218 template <typename float_t>
219 UHD_INLINE bool operator<(double lhs, fp_compare_delta<float_t> rhs);
220 template <typename float_t>
221 UHD_INLINE bool operator<=(double lhs, fp_compare_delta<float_t> rhs);
222 template <typename float_t>
223 UHD_INLINE bool operator>(double lhs, fp_compare_delta<float_t> rhs);
224 template <typename float_t>
225 UHD_INLINE bool operator>=(double lhs, fp_compare_delta<float_t> rhs);
226 
227 } // namespace fp_compare
228 
229 UHD_INLINE bool frequencies_are_equal(double lhs, double rhs)
230 {
231  return (fp_compare::fp_compare_delta<double>(lhs, FREQ_COMPARISON_DELTA_HZ)
232  == fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ));
233 }
234 
236 template <typename IntegerType> inline IntegerType lcm(IntegerType x, IntegerType y)
237 {
238  // Note: _bmint is defined conditionally at the top of the file
239  return _bmint::lcm<IntegerType>(x, y);
240 }
241 
243 template <typename IntegerType> inline IntegerType gcd(IntegerType x, IntegerType y)
244 {
245  // Note: _bmint is defined conditionally at the top of the file
246  return _bmint::gcd<IntegerType>(x, y);
247 }
248 
249 } // namespace math
250 } // namespace uhd
251 
254 
255 #endif /* INCLUDED_UHD_UTILS_MATH_HPP */
UHD_INLINE bool frequencies_are_equal(double lhs, double rhs)
Definition: math.hpp:229
UHD_INLINE bool operator<=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:76
float_t _value
Definition: math.hpp:182
UHD_INLINE bool operator>=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:87
IntegerType gcd(IntegerType x, IntegerType y)
Portable version of gcd() across Boost versions.
Definition: math.hpp:243
UHD_INLINE bool operator>(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:81
UHD_INLINE bool operator!=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:65
float_t _delta
Definition: math.hpp:183
float_t _epsilon
Definition: math.hpp:77
Definition: build_info.hpp:13
UHD_INLINE bool operator<(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:70
#define UHD_INLINE
Definition: config.h:53
UHD_INLINE ~fp_compare_epsilon()
Definition: fp_compare_epsilon.ipp:44
float_t _value
Definition: math.hpp:76
UHD_INLINE void operator=(const fp_compare_epsilon &copy)
Definition: fp_compare_epsilon.ipp:48
UHD_INLINE fp_compare_epsilon(float_t value)
UHD_INLINE bool operator==(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:59
IntegerType lcm(IntegerType x, IntegerType y)
Portable version of lcm() across Boost versions.
Definition: math.hpp:236