USRP Hardware Driver and Device Manual  Version: 4.11.0.0-0-g0d7ed3b1
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 #pragma once
9 
10 #include <uhd/config.hpp>
11 #include <cmath>
12 
13 
14 namespace uhd {
15 
20 namespace math {
21 
22 static const double PI = 3.14159265358979323846;
23 
40 static const float SINGLE_PRECISION_EPSILON = 1.19e-7f;
41 static const double DOUBLE_PRECISION_EPSILON = 2.22e-16;
42 
52 static constexpr double FREQ_COMPARE_EPSILON = 1e-12;
53 
54 namespace fp_compare {
55 
69 template <typename float_t>
71 {
72 public:
74  UHD_INLINE fp_compare_epsilon(float_t value, float_t epsilon);
77  UHD_INLINE void operator=(const fp_compare_epsilon& copy);
78 
79  float_t _value;
80  float_t _epsilon;
81 };
82 
83 /* A Note on Floating Point Equality with Epsilons
84  *
85  * There are obviously a lot of strategies for defining floating point
86  * equality, and in the end it all comes down to the domain at hand. UHD's
87  * floating-point-with-epsilon comparison algorithm is based on the method
88  * presented in Knuth's "The Art of Computer Science" called "close enough
89  * with tolerance epsilon".
90  *
91  * [(|u - v| / |u|) <= e] || [(|u - v| / |v|) <= e]
92  *
93  * UHD's modification to this algorithm is using the denominator's epsilon
94  * value (since each float_t object has its own epsilon) for each
95  * comparison.
96  */
97 
98 template <typename float_t>
101 template <typename float_t>
104 template <typename float_t>
105 UHD_INLINE bool operator<(
107 template <typename float_t>
110 template <typename float_t>
111 UHD_INLINE bool operator>(
113 template <typename float_t>
116 
117 /* If these operators are used with floats, we rely on type promotion to
118  * double. */
119 template <typename float_t>
121 template <typename float_t>
123 template <typename float_t>
124 UHD_INLINE bool operator<(fp_compare_epsilon<float_t> lhs, double rhs);
125 template <typename float_t>
127 template <typename float_t>
128 UHD_INLINE bool operator>(fp_compare_epsilon<float_t> lhs, double rhs);
129 template <typename float_t>
131 
132 template <typename float_t>
134 template <typename float_t>
136 template <typename float_t>
137 UHD_INLINE bool operator<(double lhs, fp_compare_epsilon<float_t> rhs);
138 template <typename float_t>
140 template <typename float_t>
141 UHD_INLINE bool operator>(double lhs, fp_compare_epsilon<float_t> rhs);
142 template <typename float_t>
144 
147 {
148 public:
150  : fp_compare_epsilon<double>(value, FREQ_COMPARE_EPSILON)
151  {
152  }
153 
155  : fp_compare_epsilon<double>(copy)
156  {
157  }
158 };
159 
160 
161 } // namespace fp_compare
162 
163 
170 static const float SINGLE_PRECISION_DELTA = 1e-3f;
171 static const double DOUBLE_PRECISION_DELTA = 1e-5;
172 
174 static const double FREQ_COMPARISON_DELTA_HZ = 0.1;
175 
176 
177 namespace fp_compare {
178 
192 template <typename float_t>
194 {
195 public:
196  UHD_INLINE fp_compare_delta(float_t value);
197  UHD_INLINE fp_compare_delta(float_t value, float_t delta);
200  UHD_INLINE void operator=(const fp_compare_delta& copy);
201 
202  float_t _value;
203  float_t _delta;
204 };
205 
206 template <typename float_t>
208 template <typename float_t>
210 template <typename float_t>
212 template <typename float_t>
214 template <typename float_t>
216 template <typename float_t>
218 
219 /* If these operators are used with floats, we rely on type promotion to
220  * double. */
221 template <typename float_t>
222 UHD_INLINE bool operator==(fp_compare_delta<float_t> lhs, double rhs);
223 template <typename float_t>
224 UHD_INLINE bool operator!=(fp_compare_delta<float_t> lhs, double rhs);
225 template <typename float_t>
226 UHD_INLINE bool operator<(fp_compare_delta<float_t> lhs, double rhs);
227 template <typename float_t>
228 UHD_INLINE bool operator<=(fp_compare_delta<float_t> lhs, double rhs);
229 template <typename float_t>
230 UHD_INLINE bool operator>(fp_compare_delta<float_t> lhs, double rhs);
231 template <typename float_t>
232 UHD_INLINE bool operator>=(fp_compare_delta<float_t> lhs, double rhs);
233 
234 template <typename float_t>
235 UHD_INLINE bool operator==(double lhs, fp_compare_delta<float_t> rhs);
236 template <typename float_t>
237 UHD_INLINE bool operator!=(double lhs, fp_compare_delta<float_t> rhs);
238 template <typename float_t>
239 UHD_INLINE bool operator<(double lhs, fp_compare_delta<float_t> rhs);
240 template <typename float_t>
241 UHD_INLINE bool operator<=(double lhs, fp_compare_delta<float_t> rhs);
242 template <typename float_t>
243 UHD_INLINE bool operator>(double lhs, fp_compare_delta<float_t> rhs);
244 template <typename float_t>
245 UHD_INLINE bool operator>=(double lhs, fp_compare_delta<float_t> rhs);
246 
247 } // namespace fp_compare
248 
249 UHD_INLINE bool frequencies_are_equal(double lhs, double rhs)
250 {
251  return (fp_compare::fp_compare_delta<double>(lhs, FREQ_COMPARISON_DELTA_HZ)
252  == fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ));
253 }
254 
255 inline double dB_to_lin(const double dB_val)
256 {
257  return std::pow(10, (dB_val) / 10.0);
258 }
259 
260 inline double lin_to_dB(const double val)
261 {
262  return 10 * std::log10(val);
263 }
264 
265 
274 template <typename T>
275 inline constexpr int sign(T x)
276 {
277  // Note: If T is unsigned, then this will compile with a warning. Should
278  // we need that, expand the template logic.
279  return (T(0) < x) - (x < T(0));
280 }
281 
293 inline double wrap_frequency(const double requested_freq, const double rate)
294 {
295  double freq = std::fmod(requested_freq, rate);
296  if (std::abs(freq) > rate / 2.0)
297  freq -= uhd::math::sign(freq) * rate;
298  return freq;
299 }
300 
301 } // namespace math
302 } // namespace uhd
303 
UHD_INLINE fp_compare_delta(float_t value)
float_t _delta
Definition: math.hpp:203
UHD_INLINE void operator=(const fp_compare_delta &copy)
Definition: fp_compare_delta.ipp:56
UHD_INLINE ~fp_compare_delta()
Definition: fp_compare_delta.ipp:51
float_t _value
Definition: math.hpp:202
float_t _epsilon
Definition: math.hpp:80
UHD_INLINE ~fp_compare_epsilon()
Definition: fp_compare_epsilon.ipp:46
UHD_INLINE void operator=(const fp_compare_epsilon &copy)
Definition: fp_compare_epsilon.ipp:51
float_t _value
Definition: math.hpp:79
UHD_INLINE fp_compare_epsilon(float_t value)
An alias for fp_compare_epsilon, but with defaults for frequencies.
Definition: math.hpp:147
UHD_INLINE freq_compare_epsilon(const freq_compare_epsilon &copy)
Definition: math.hpp:154
UHD_INLINE freq_compare_epsilon(double value)
Definition: math.hpp:149
#define UHD_INLINE
Definition: config.h:65
UHD_INLINE bool operator!=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:71
UHD_INLINE bool operator<=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:84
UHD_INLINE bool operator==(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:64
UHD_INLINE bool operator<(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:77
UHD_INLINE bool operator>(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:90
UHD_INLINE bool operator>=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:97
UHD_INLINE bool frequencies_are_equal(double lhs, double rhs)
Definition: math.hpp:249
double dB_to_lin(const double dB_val)
Definition: math.hpp:255
constexpr int sign(T x)
Returns the sign of x.
Definition: math.hpp:275
double lin_to_dB(const double val)
Definition: math.hpp:260
double wrap_frequency(const double requested_freq, const double rate)
Return a wrapped frequency that is the equivalent frequency in the first Nyquist zone.
Definition: math.hpp:293
Definition: build_info.hpp:12