USRP Hardware Driver and USRP Manual: math.hpp Source File

| USRP Hardware Driver and USRP Manual Version: 4.9.0.makepkg-0-g9ec1f582 UHD and USRP Manual |

Loading...
Searching...
No Matches
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
14namespace uhd {
15
20namespace math {
21
22static const double PI = 3.14159265358979323846;
23
40static const float SINGLE_PRECISION_EPSILON = 1.19e-7f;
41static const double DOUBLE_PRECISION_EPSILON = 2.22e-16;
42
44//
45// Note that this is a UHD/USRP-specific constant. In UHD, frequencies are on
46// the order of 1e9 (GHz) or below. We will declare frequencies as equal if they
47// are within a millihertz. For the purpose of
48// comparing frequencies, we "lose" 9 decimal places for the integer
49// component of the frequency, so we choose this epsilon value for floating
50// point comparison of frequencies.
51static constexpr double FREQ_COMPARE_EPSILON = 1e-12;
52
53namespace fp_compare {
54
68template <typename float_t>
69 class fp_compare_epsilon
70{
71public:
72 UHD_INLINE fp_compare_epsilon(float_t value);
73 UHD_INLINE fp_compare_epsilon(float_t value, float_t epsilon);
74 UHD_INLINE fp_compare_epsilon(const fp_compare_epsilon<float_t>& copy);
75 UHD_INLINE ~fp_compare_epsilon();
76 UHD_INLINE void operator=(const fp_compare_epsilon& copy);
77
78 float_t _value;
79 float_t _epsilon;
80};
81
82/* A Note on Floating Point Equality with Epsilons
83 *
84 * There are obviously a lot of strategies for defining floating point
85 * equality, and in the end it all comes down to the domain at hand. UHD's
86 * floating-point-with-epsilon comparison algorithm is based on the method
87 * presented in Knuth's "The Art of Computer Science" called "close enough
88 * with tolerance epsilon".
89 *
90 * [(|u - v| / |u|) <= e] || [(|u - v| / |v|) <= e]
91 *
92 * UHD's modification to this algorithm is using the denominator's epsilon
93 * value (since each float_t object has its own epsilon) for each
94 * comparison.
95 */
96
97template <typename float_t>
98 UHD_INLINE bool operator==(
99 fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
100template <typename float_t>
101 UHD_INLINE bool operator!=(
102 fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
103template <typename float_t>
104 UHD_INLINE bool operator<(
105 fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
106template <typename float_t>
107 UHD_INLINE bool operator<=(
108 fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
109template <typename float_t>
110 UHD_INLINE bool operator>(
111 fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
112template <typename float_t>
113 UHD_INLINE bool operator>=(
114 fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
115
116/* If these operators are used with floats, we rely on type promotion to
117 * double. */
118template <typename float_t>
119 UHD_INLINE bool operator==(fp_compare_epsilon<float_t> lhs, double rhs);
120template <typename float_t>
121 UHD_INLINE bool operator!=(fp_compare_epsilon<float_t> lhs, double rhs);
122template <typename float_t>
123 UHD_INLINE bool operator<(fp_compare_epsilon<float_t> lhs, double rhs);
124template <typename float_t>
125 UHD_INLINE bool operator<=(fp_compare_epsilon<float_t> lhs, double rhs);
126template <typename float_t>
127 UHD_INLINE bool operator>(fp_compare_epsilon<float_t> lhs, double rhs);
128template <typename float_t>
129 UHD_INLINE bool operator>=(fp_compare_epsilon<float_t> lhs, double rhs);
130
131template <typename float_t>
132 UHD_INLINE bool operator==(double lhs, fp_compare_epsilon<float_t> rhs);
133template <typename float_t>
134 UHD_INLINE bool operator!=(double lhs, fp_compare_epsilon<float_t> rhs);
135template <typename float_t>
136 UHD_INLINE bool operator<(double lhs, fp_compare_epsilon<float_t> rhs);
137template <typename float_t>
138 UHD_INLINE bool operator<=(double lhs, fp_compare_epsilon<float_t> rhs);
139template <typename float_t>
140 UHD_INLINE bool operator>(double lhs, fp_compare_epsilon<float_t> rhs);
141template <typename float_t>
142 UHD_INLINE bool operator>=(double lhs, fp_compare_epsilon<float_t> rhs);
143
145 class freq_compare_epsilon : public fp_compare_epsilon<double>
146{
147public:
148 UHD_INLINE freq_compare_epsilon(double value)
149 : fp_compare_epsilon<double>(value, FREQ_COMPARE_EPSILON)
150 {
151 }
152
153 UHD_INLINE freq_compare_epsilon(const freq_compare_epsilon& copy)
154 : fp_compare_epsilon<double>(copy)
155 {
156 }
157};
158
159
160} // namespace fp_compare
161
162
169static const float SINGLE_PRECISION_DELTA = 1e-3f;
170static const double DOUBLE_PRECISION_DELTA = 1e-5;
171
173static const double FREQ_COMPARISON_DELTA_HZ = 0.1;
174
175
176namespace fp_compare {
177
191template <typename float_t>
192 class fp_compare_delta
193{
194public:
195 UHD_INLINE fp_compare_delta(float_t value);
196 UHD_INLINE fp_compare_delta(float_t value, float_t delta);
197 UHD_INLINE fp_compare_delta(const fp_compare_delta<float_t>& copy);
198 UHD_INLINE ~fp_compare_delta();
199 UHD_INLINE void operator=(const fp_compare_delta& copy);
200
201 float_t _value;
202 float_t _delta;
203};
204
205template <typename float_t>
206 UHD_INLINE bool operator==(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
207template <typename float_t>
208 UHD_INLINE bool operator!=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
209template <typename float_t>
210 UHD_INLINE bool operator<(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
211template <typename float_t>
212 UHD_INLINE bool operator<=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
213template <typename float_t>
214 UHD_INLINE bool operator>(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
215template <typename float_t>
216 UHD_INLINE bool operator>=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
217
218/* If these operators are used with floats, we rely on type promotion to
219 * double. */
220template <typename float_t>
221 UHD_INLINE bool operator==(fp_compare_delta<float_t> lhs, double rhs);
222template <typename float_t>
223 UHD_INLINE bool operator!=(fp_compare_delta<float_t> lhs, double rhs);
224template <typename float_t>
225 UHD_INLINE bool operator<(fp_compare_delta<float_t> lhs, double rhs);
226template <typename float_t>
227 UHD_INLINE bool operator<=(fp_compare_delta<float_t> lhs, double rhs);
228template <typename float_t>
229 UHD_INLINE bool operator>(fp_compare_delta<float_t> lhs, double rhs);
230template <typename float_t>
231 UHD_INLINE bool operator>=(fp_compare_delta<float_t> lhs, double rhs);
232
233template <typename float_t>
234 UHD_INLINE bool operator==(double lhs, fp_compare_delta<float_t> rhs);
235template <typename float_t>
236 UHD_INLINE bool operator!=(double lhs, fp_compare_delta<float_t> rhs);
237template <typename float_t>
238 UHD_INLINE bool operator<(double lhs, fp_compare_delta<float_t> rhs);
239template <typename float_t>
240 UHD_INLINE bool operator<=(double lhs, fp_compare_delta<float_t> rhs);
241template <typename float_t>
242 UHD_INLINE bool operator>(double lhs, fp_compare_delta<float_t> rhs);
243template <typename float_t>
244 UHD_INLINE bool operator>=(double lhs, fp_compare_delta<float_t> rhs);
245
246} // namespace fp_compare
247
248 UHD_INLINE bool frequencies_are_equal(double lhs, double rhs)
249{
250 return (fp_compare::fp_compare_delta<double>(lhs, FREQ_COMPARISON_DELTA_HZ)
251 == fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ));
252}
253
254 inline double dB_to_lin(const double dB_val)
255{
256 return std::pow(10, (dB_val) / 10.0);
257}
258
259 inline double lin_to_dB(const double val)
260{
261 return 10 * std::log10(val);
262}
263
264
266//
267// Note: This is equivalent to the Boost.Math version, but without the
268// dependency.
269//
270// Returns +1 for positive arguments, -1 for negative arguments, and 0 if x is
271// zero.
272template <typename T>
273 inline constexpr int sign(T x)
274{
275 // Note: If T is unsigned, then this will compile with a warning. Should
276 // we need that, expand the template logic.
277 return (T(0) < x) - (x < T(0));
278}
279
281// Nyquist zone.
282//
283// Examples:
284// - Just above the sampling rate:
285// wrap_frequency(250e6, 200e6) == 50e6
286// - Just outside the Nyquist zone:
287// wrap_frequency(120e6, 200e6) == -80e6
288// - Also works for negative frequencies:
289// wrap_frequency(-250e6, 200e6) == -50e6
290 inline double wrap_frequency(const double requested_freq, const double rate)
291{
292 double freq = std::fmod(requested_freq, rate);
293 if (std::abs(freq) > rate / 2.0)
294 freq -= uhd::math::sign(freq) * rate;
295 return freq;
296}
297
298} // namespace math
299} // namespace uhd
300
301#include <uhd/utils/fp_compare_delta.ipp>
302#include <uhd/utils/fp_compare_epsilon.ipp>
uhd::math::fp_compare::fp_compare_delta
Definition math.hpp:193
uhd::math::fp_compare::fp_compare_delta::fp_compare_delta
UHD_INLINE fp_compare_delta(float_t value)
uhd::math::fp_compare::fp_compare_delta::_delta
float_t _delta
Definition math.hpp:202
uhd::math::fp_compare::fp_compare_delta::operator=
UHD_INLINE void operator=(const fp_compare_delta &copy)
Definition fp_compare_delta.ipp:56
uhd::math::fp_compare::fp_compare_delta::~fp_compare_delta
UHD_INLINE ~fp_compare_delta()
Definition fp_compare_delta.ipp:51
uhd::math::fp_compare::fp_compare_delta::_value
float_t _value
Definition math.hpp:201
uhd::math::fp_compare::fp_compare_epsilon
Definition math.hpp:70
uhd::math::fp_compare::fp_compare_epsilon::_epsilon
float_t _epsilon
Definition math.hpp:79
uhd::math::fp_compare::fp_compare_epsilon::~fp_compare_epsilon
UHD_INLINE ~fp_compare_epsilon()
Definition fp_compare_epsilon.ipp:46
uhd::math::fp_compare::fp_compare_epsilon::operator=
UHD_INLINE void operator=(const fp_compare_epsilon &copy)
Definition fp_compare_epsilon.ipp:51
uhd::math::fp_compare::fp_compare_epsilon::_value
float_t _value
Definition math.hpp:78
uhd::math::fp_compare::fp_compare_epsilon::fp_compare_epsilon
UHD_INLINE fp_compare_epsilon(float_t value)
uhd::math::fp_compare::fp_compare_epsilon< double >::fp_compare_epsilon
UHD_INLINE fp_compare_epsilon(float value)
Definition fp_compare_epsilon.ipp:19
uhd::math::fp_compare::freq_compare_epsilon::freq_compare_epsilon
UHD_INLINE freq_compare_epsilon(const freq_compare_epsilon &copy)
Definition math.hpp:153
uhd::math::fp_compare::freq_compare_epsilon::freq_compare_epsilon
UHD_INLINE freq_compare_epsilon(double value)
Definition math.hpp:148
UHD_INLINE
#define UHD_INLINE
Definition config.h:65
config.hpp
fp_compare_delta.ipp
fp_compare_epsilon.ipp
uhd::math::fp_compare
Definition fp_compare_delta.ipp:15
uhd::math::fp_compare::operator!=
UHD_INLINE bool operator!=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition fp_compare_delta.ipp:71
uhd::math::fp_compare::operator<=
UHD_INLINE bool operator<=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition fp_compare_delta.ipp:84
uhd::math::fp_compare::operator==
UHD_INLINE bool operator==(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition fp_compare_delta.ipp:64
uhd::math::fp_compare::operator<
UHD_INLINE bool operator<(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition fp_compare_delta.ipp:77
uhd::math::fp_compare::operator>
UHD_INLINE bool operator>(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition fp_compare_delta.ipp:90
uhd::math::fp_compare::operator>=
UHD_INLINE bool operator>=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition fp_compare_delta.ipp:97
uhd::math
Definition fp_compare_delta.ipp:15
uhd::math::frequencies_are_equal
UHD_INLINE bool frequencies_are_equal(double lhs, double rhs)
Definition math.hpp:248
uhd::math::dB_to_lin
double dB_to_lin(const double dB_val)
Definition math.hpp:254
uhd::math::sign
constexpr int sign(T x)
Returns the sign of x.
Definition math.hpp:273
uhd::math::lin_to_dB
double lin_to_dB(const double val)
Definition math.hpp:259
uhd::math::wrap_frequency
double wrap_frequency(const double requested_freq, const double rate)
Return a wrapped frequency that is the equivalent frequency in the first.
Definition math.hpp:290
uhd
Definition build_info.hpp:12