USRP Hardware Driver and USRP Manual  Version: 003.010.001.HEAD-0-g929e3b32
UHD and USRP Manual
math.hpp
Go to the documentation of this file.
1 //
2 // Copyright 2014-2015 Ettus Research LLC
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17 
18 #ifndef INCLUDED_UHD_UTILS_MATH_HPP
19 #define INCLUDED_UHD_UTILS_MATH_HPP
20 
21 #include <cmath>
22 #include <uhd/config.hpp>
23 #include <boost/cstdint.hpp>
24 #include <boost/numeric/conversion/bounds.hpp>
25 
26 namespace uhd {
27 
32 namespace math {
33 
50  static const float SINGLE_PRECISION_EPSILON = 1.19e-7f;
51  static const double DOUBLE_PRECISION_EPSILON = 2.22e-16;
52 
53 namespace fp_compare {
54 
68  template<typename float_t> class fp_compare_epsilon {
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> UHD_INLINE
97  template<typename float_t> UHD_INLINE
99  template<typename float_t> UHD_INLINE
100  bool operator<(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
101  template<typename float_t> UHD_INLINE
102  bool operator<=(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
103  template<typename float_t> UHD_INLINE
105  template<typename float_t> UHD_INLINE
107 
108  /* If these operators are used with floats, we rely on type promotion to
109  * double. */
110  template<typename float_t> UHD_INLINE
111  bool operator==(fp_compare_epsilon<float_t> lhs, double rhs);
112  template<typename float_t> UHD_INLINE
113  bool operator!=(fp_compare_epsilon<float_t> lhs, double rhs);
114  template<typename float_t> UHD_INLINE
115  bool operator<(fp_compare_epsilon<float_t> lhs, double rhs);
116  template<typename float_t> UHD_INLINE
117  bool operator<=(fp_compare_epsilon<float_t> lhs, double rhs);
118  template<typename float_t> UHD_INLINE
119  bool operator>(fp_compare_epsilon<float_t> lhs, double rhs);
120  template<typename float_t> UHD_INLINE
121  bool operator>=(fp_compare_epsilon<float_t> lhs, double rhs);
122 
123  template<typename float_t> UHD_INLINE
124  bool operator==(double lhs, fp_compare_epsilon<float_t> rhs);
125  template<typename float_t> UHD_INLINE
126  bool operator!=(double lhs, fp_compare_epsilon<float_t> rhs);
127  template<typename float_t> UHD_INLINE
128  bool operator<(double lhs, fp_compare_epsilon<float_t> rhs);
129  template<typename float_t> UHD_INLINE
130  bool operator<=(double lhs, fp_compare_epsilon<float_t> rhs);
131  template<typename float_t> UHD_INLINE
132  bool operator>(double lhs, fp_compare_epsilon<float_t> rhs);
133  template<typename float_t> UHD_INLINE
134  bool operator>=(double lhs, fp_compare_epsilon<float_t> rhs);
135 
136 } // namespace fp_compare
137 
138 
145  static const float SINGLE_PRECISION_DELTA = 1e-3f;
146  static const double DOUBLE_PRECISION_DELTA = 1e-5;
147 
149  static const double FREQ_COMPARISON_DELTA_HZ = 0.1;
150 
151 
152 namespace fp_compare {
153 
167  template<typename float_t> class fp_compare_delta {
168  public:
169  UHD_INLINE fp_compare_delta(float_t value);
170  UHD_INLINE fp_compare_delta(float_t value, float_t delta);
171  UHD_INLINE fp_compare_delta(const fp_compare_delta<float_t>& copy);
172  UHD_INLINE ~fp_compare_delta();
173  UHD_INLINE void operator=(const fp_compare_delta& copy);
174 
175  float_t _value;
176  float_t _delta;
177  };
178 
179  template<typename float_t> UHD_INLINE
181  template<typename float_t> UHD_INLINE
183  template<typename float_t> UHD_INLINE
184  bool operator<(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
185  template<typename float_t> UHD_INLINE
186  bool operator<=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
187  template<typename float_t> UHD_INLINE
189  template<typename float_t> UHD_INLINE
191 
192  /* If these operators are used with floats, we rely on type promotion to
193  * double. */
194  template<typename float_t> UHD_INLINE
195  bool operator==(fp_compare_delta<float_t> lhs, double rhs);
196  template<typename float_t> UHD_INLINE
197  bool operator!=(fp_compare_delta<float_t> lhs, double rhs);
198  template<typename float_t> UHD_INLINE
199  bool operator<(fp_compare_delta<float_t> lhs, double rhs);
200  template<typename float_t> UHD_INLINE
201  bool operator<=(fp_compare_delta<float_t> lhs, double rhs);
202  template<typename float_t> UHD_INLINE
203  bool operator>(fp_compare_delta<float_t> lhs, double rhs);
204  template<typename float_t> UHD_INLINE
205  bool operator>=(fp_compare_delta<float_t> lhs, double rhs);
206 
207  template<typename float_t> UHD_INLINE
208  bool operator==(double lhs, fp_compare_delta<float_t> rhs);
209  template<typename float_t> UHD_INLINE
210  bool operator!=(double lhs, fp_compare_delta<float_t> rhs);
211  template<typename float_t> UHD_INLINE
212  bool operator<(double lhs, fp_compare_delta<float_t> rhs);
213  template<typename float_t> UHD_INLINE
214  bool operator<=(double lhs, fp_compare_delta<float_t> rhs);
215  template<typename float_t> UHD_INLINE
216  bool operator>(double lhs, fp_compare_delta<float_t> rhs);
217  template<typename float_t> UHD_INLINE
218  bool operator>=(double lhs, fp_compare_delta<float_t> rhs);
219 
220 } // namespace fp_compare
221 
222  UHD_INLINE bool frequencies_are_equal(double lhs, double rhs) {
223  return(fp_compare::fp_compare_delta<double>(lhs, FREQ_COMPARISON_DELTA_HZ)
224  == fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ));
225  }
226 
228  template <typename float_t> UHD_INLINE
229  float_t log2(float_t x)
230  {
231  // C++11 defines std::log2(), when that's universally supported
232  // we can switch over.
233  return std::log(x) / std::log(float_t(2));
234  }
235 
236 
237 } // namespace math
238 } // namespace uhd
239 
242 
243 #endif /* INCLUDED_UHD_UTILS_MATH_HPP */
UHD_INLINE bool frequencies_are_equal(double lhs, double rhs)
Definition: math.hpp:222
float_t _value
Definition: math.hpp:175
UHD_INLINE float_t log2(float_t x)
Portable log2()
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:97
UHD_INLINE bool operator>(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:91
UHD_INLINE bool operator!=(fp_compare_delta< float_t > lhs, fp_compare_delta< float_t > rhs)
Definition: fp_compare_delta.ipp:75
float_t _delta
Definition: math.hpp:176
float_t _epsilon
Definition: math.hpp:77
Definition: build_info.hpp:25
#define UHD_INLINE
Definition: config.h:63
UHD_INLINE ~fp_compare_epsilon()
Definition: fp_compare_epsilon.ipp:54
float_t _value
Definition: math.hpp:76
UHD_INLINE void operator=(const fp_compare_epsilon &copy)
Definition: fp_compare_epsilon.ipp:58
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:69