USRP Hardware Driver and USRP Manual  Version: 003.009.004-0-g2b5a88bb
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 
44  static const boost::int32_t BOOST_INT32_MAX = boost::numeric::bounds<boost::int32_t>::highest();
45  static const boost::int32_t BOOST_INT32_MIN = boost::numeric::bounds<boost::int32_t>::lowest();
46 
63  static const float SINGLE_PRECISION_EPSILON = 1.19e-7f;
64  static const double DOUBLE_PRECISION_EPSILON = 2.22e-16;
65 
66 namespace fp_compare {
67 
81  template<typename float_t> class fp_compare_epsilon {
82  public:
83  UHD_INLINE fp_compare_epsilon(float_t value);
84  UHD_INLINE fp_compare_epsilon(float_t value, float_t epsilon);
87  UHD_INLINE void operator=(const fp_compare_epsilon& copy);
88 
89  float_t _value;
90  float_t _epsilon;
91  };
92 
93  /* A Note on Floating Point Equality with Epsilons
94  *
95  * There are obviously a lot of strategies for defining floating point
96  * equality, and in the end it all comes down to the domain at hand. UHD's
97  * floating-point-with-epsilon comparison algorithm is based on the method
98  * presented in Knuth's "The Art of Computer Science" called "very close
99  * with tolerance epsilon".
100  *
101  * [(|u - v| / |u|) <= e] && [(|u - v| / |v|) <= e]
102  *
103  * UHD's modification to this algorithm is using the denominator's epsilon
104  * value (since each float_t object has its own epsilon) for each
105  * comparison.
106  */
107 
108  template<typename float_t> UHD_INLINE
110  template<typename float_t> UHD_INLINE
112  template<typename float_t> UHD_INLINE
113  bool operator<(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
114  template<typename float_t> UHD_INLINE
115  bool operator<=(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
116  template<typename float_t> UHD_INLINE
118  template<typename float_t> UHD_INLINE
120 
121  /* If these operators are used with floats, we rely on type promotion to
122  * double. */
123  template<typename float_t> UHD_INLINE
124  bool operator==(fp_compare_epsilon<float_t> lhs, double rhs);
125  template<typename float_t> UHD_INLINE
126  bool operator!=(fp_compare_epsilon<float_t> lhs, double rhs);
127  template<typename float_t> UHD_INLINE
128  bool operator<(fp_compare_epsilon<float_t> lhs, double rhs);
129  template<typename float_t> UHD_INLINE
130  bool operator<=(fp_compare_epsilon<float_t> lhs, double rhs);
131  template<typename float_t> UHD_INLINE
132  bool operator>(fp_compare_epsilon<float_t> lhs, double rhs);
133  template<typename float_t> UHD_INLINE
134  bool operator>=(fp_compare_epsilon<float_t> lhs, double rhs);
135 
136  template<typename float_t> UHD_INLINE
137  bool operator==(double lhs, fp_compare_epsilon<float_t> rhs);
138  template<typename float_t> UHD_INLINE
139  bool operator!=(double lhs, fp_compare_epsilon<float_t> rhs);
140  template<typename float_t> UHD_INLINE
141  bool operator<(double lhs, fp_compare_epsilon<float_t> rhs);
142  template<typename float_t> UHD_INLINE
143  bool operator<=(double lhs, fp_compare_epsilon<float_t> rhs);
144  template<typename float_t> UHD_INLINE
145  bool operator>(double lhs, fp_compare_epsilon<float_t> rhs);
146  template<typename float_t> UHD_INLINE
147  bool operator>=(double lhs, fp_compare_epsilon<float_t> rhs);
148 
149 } // namespace fp_compare
150 
151 
158  static const float SINGLE_PRECISION_DELTA = 1e-3f;
159  static const double DOUBLE_PRECISION_DELTA = 1e-5;
160 
162  static const double FREQ_COMPARISON_DELTA_HZ = 0.1;
163 
164 
165 namespace fp_compare {
166 
180  template<typename float_t> class fp_compare_delta {
181  public:
182  UHD_INLINE fp_compare_delta(float_t value);
183  UHD_INLINE fp_compare_delta(float_t value, float_t delta);
184  UHD_INLINE fp_compare_delta(const fp_compare_delta<float_t>& copy);
185  UHD_INLINE ~fp_compare_delta();
186  UHD_INLINE void operator=(const fp_compare_delta& copy);
187 
188  float_t _value;
189  float_t _delta;
190  };
191 
192  template<typename float_t> UHD_INLINE
194  template<typename float_t> UHD_INLINE
196  template<typename float_t> UHD_INLINE
197  bool operator<(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
198  template<typename float_t> UHD_INLINE
199  bool operator<=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
200  template<typename float_t> UHD_INLINE
202  template<typename float_t> UHD_INLINE
204 
205  /* If these operators are used with floats, we rely on type promotion to
206  * double. */
207  template<typename float_t> UHD_INLINE
208  bool operator==(fp_compare_delta<float_t> lhs, double rhs);
209  template<typename float_t> UHD_INLINE
210  bool operator!=(fp_compare_delta<float_t> lhs, double rhs);
211  template<typename float_t> UHD_INLINE
212  bool operator<(fp_compare_delta<float_t> lhs, double rhs);
213  template<typename float_t> UHD_INLINE
214  bool operator<=(fp_compare_delta<float_t> lhs, double rhs);
215  template<typename float_t> UHD_INLINE
216  bool operator>(fp_compare_delta<float_t> lhs, double rhs);
217  template<typename float_t> UHD_INLINE
218  bool operator>=(fp_compare_delta<float_t> lhs, double rhs);
219 
220  template<typename float_t> UHD_INLINE
221  bool operator==(double lhs, fp_compare_delta<float_t> rhs);
222  template<typename float_t> UHD_INLINE
223  bool operator!=(double lhs, fp_compare_delta<float_t> rhs);
224  template<typename float_t> UHD_INLINE
225  bool operator<(double lhs, fp_compare_delta<float_t> rhs);
226  template<typename float_t> UHD_INLINE
227  bool operator<=(double lhs, fp_compare_delta<float_t> rhs);
228  template<typename float_t> UHD_INLINE
229  bool operator>(double lhs, fp_compare_delta<float_t> rhs);
230  template<typename float_t> UHD_INLINE
231  bool operator>=(double lhs, fp_compare_delta<float_t> rhs);
232 
233 } // namespace fp_compare
234 
235  UHD_INLINE bool frequencies_are_equal(double lhs, double rhs) {
236  return(fp_compare::fp_compare_delta<double>(lhs, FREQ_COMPARISON_DELTA_HZ)
237  == fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ));
238  }
239 
241  template <typename float_t> UHD_INLINE
242  float_t log2(float_t x)
243  {
244  // C++11 defines std::log2(), when that's universally supported
245  // we can switch over.
246  return std::log(x) / std::log(float_t(2));
247  }
248 
249 
250 } // namespace math
251 } // namespace uhd
252 
255 
256 #endif /* INCLUDED_UHD_UTILS_MATH_HPP */
UHD_INLINE bool frequencies_are_equal(double lhs, double rhs)
Definition: math.hpp:235
float_t _value
Definition: math.hpp:188
UHD_INLINE float_t log2(float_t x)
Portable log2()
Definition: math.hpp:242
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:189
float_t _epsilon
Definition: math.hpp:90
Definition: convert.hpp:28
#define UHD_INLINE
Definition: config.h:56
UHD_INLINE ~fp_compare_epsilon()
Definition: fp_compare_epsilon.ipp:54
float_t _value
Definition: math.hpp:89
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