/usr/include/uhd/utils/math.hpp is in libuhd-dev 3.10.3.0-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | //
// Copyright 2014-2015 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef INCLUDED_UHD_UTILS_MATH_HPP
#define INCLUDED_UHD_UTILS_MATH_HPP
#include <cmath>
#include <uhd/config.hpp>
#include <stdint.h>
#include <boost/numeric/conversion/bounds.hpp>
namespace uhd {
/*!
* Contains useful mathematical functions, classes, and constants, which should
* be used in UHD when portable / `std` options are not available.
*/
namespace math {
/*!
* Define epsilon values for floating point comparisons.
*
* There are a lot of different sources for epsilon values that we could use
* for this. For single-precision (f32), most machines will report an
* epsilon of 1.192e-7, and for double-precision (f64) most machines will
* report an epsilon of 2.220e-16. The issue is that these are not always
* appropriate, depending on the scale of the operands and how they have
* been rounded in previous calculations. The values defined here are
* defaults, but should be overridden for calculations depending on the
* application.
*
* If a particular comparison is operating using very small or very large
* values, a custom epsilon should be defined for those computations. This
* use-case is provided for in the `fp_compare_epsilon` class constructor.
*/
static const float SINGLE_PRECISION_EPSILON = 1.19e-7f;
static const double DOUBLE_PRECISION_EPSILON = 2.22e-16;
namespace fp_compare {
/*!
* Class for floating-point comparisons using an epsilon.
*
* At construction, you can specify the epsilon to use for the comparisons.
* This class, combined with the operators under it, allow for
* epsilon-comparisons of floats. An example is:
*
* // Compare floats 'x' and 'y'.
* bool x_equals_y = (fp_compare_epsilon<float>(x) == y);
*
* // Compare doubles 'x' and 'y'.
* bool x_equals_y = (fp_compare_epsilon<double>(x) == y);
*/
template<typename float_t> class fp_compare_epsilon {
public:
UHD_INLINE fp_compare_epsilon(float_t value);
UHD_INLINE fp_compare_epsilon(float_t value, float_t epsilon);
UHD_INLINE fp_compare_epsilon(const fp_compare_epsilon<float_t>& copy);
UHD_INLINE ~fp_compare_epsilon();
UHD_INLINE void operator=(const fp_compare_epsilon& copy);
float_t _value;
float_t _epsilon;
};
/* A Note on Floating Point Equality with Epsilons
*
* There are obviously a lot of strategies for defining floating point
* equality, and in the end it all comes down to the domain at hand. UHD's
* floating-point-with-epsilon comparison algorithm is based on the method
* presented in Knuth's "The Art of Computer Science" called "very close
* with tolerance epsilon".
*
* [(|u - v| / |u|) <= e] && [(|u - v| / |v|) <= e]
*
* UHD's modification to this algorithm is using the denominator's epsilon
* value (since each float_t object has its own epsilon) for each
* comparison.
*/
template<typename float_t> UHD_INLINE
bool operator==(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator!=(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator<(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator<=(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator>(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator>=(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs);
/* If these operators are used with floats, we rely on type promotion to
* double. */
template<typename float_t> UHD_INLINE
bool operator==(fp_compare_epsilon<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator!=(fp_compare_epsilon<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator<(fp_compare_epsilon<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator<=(fp_compare_epsilon<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator>(fp_compare_epsilon<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator>=(fp_compare_epsilon<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator==(double lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator!=(double lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator<(double lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator<=(double lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator>(double lhs, fp_compare_epsilon<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator>=(double lhs, fp_compare_epsilon<float_t> rhs);
} // namespace fp_compare
/*!
* Define delta values for floating point comparisons.
*
* These are the default deltas used by the 'fp_compare_delta' class for
* single and double-precision floating point comparisons.
*/
static const float SINGLE_PRECISION_DELTA = 1e-3f;
static const double DOUBLE_PRECISION_DELTA = 1e-5;
/*! Floating-point delta to use for frequency comparisons. */
static const double FREQ_COMPARISON_DELTA_HZ = 0.1;
namespace fp_compare {
/*!
* Class for floating-point comparisons using a delta.
*
* At construction, you can specify the delta to use for the comparisons.
* This class, combined with the operators under it, allow for
* delta-comparisons of floats. An example is:
*
* // Compare floats 'x' and 'y'.
* bool x_equals_y = (fp_compare_delta<float>(x) == y);
*
* // Compare doubles 'x' and 'y'.
* bool x_equals_y = (fp_compare_delta<double>(x) == y);
*/
template<typename float_t> class fp_compare_delta {
public:
UHD_INLINE fp_compare_delta(float_t value);
UHD_INLINE fp_compare_delta(float_t value, float_t delta);
UHD_INLINE fp_compare_delta(const fp_compare_delta<float_t>& copy);
UHD_INLINE ~fp_compare_delta();
UHD_INLINE void operator=(const fp_compare_delta& copy);
float_t _value;
float_t _delta;
};
template<typename float_t> UHD_INLINE
bool operator==(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator!=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator<(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator<=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator>(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator>=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs);
/* If these operators are used with floats, we rely on type promotion to
* double. */
template<typename float_t> UHD_INLINE
bool operator==(fp_compare_delta<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator!=(fp_compare_delta<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator<(fp_compare_delta<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator<=(fp_compare_delta<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator>(fp_compare_delta<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator>=(fp_compare_delta<float_t> lhs, double rhs);
template<typename float_t> UHD_INLINE
bool operator==(double lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator!=(double lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator<(double lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator<=(double lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator>(double lhs, fp_compare_delta<float_t> rhs);
template<typename float_t> UHD_INLINE
bool operator>=(double lhs, fp_compare_delta<float_t> rhs);
} // namespace fp_compare
UHD_INLINE bool frequencies_are_equal(double lhs, double rhs) {
return(fp_compare::fp_compare_delta<double>(lhs, FREQ_COMPARISON_DELTA_HZ)
== fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ));
}
//! Portable log2()
template <typename float_t> UHD_INLINE
float_t log2(float_t x)
{
// C++11 defines std::log2(), when that's universally supported
// we can switch over.
return std::log(x) / std::log(float_t(2));
}
} // namespace math
} // namespace uhd
#include <uhd/utils/fp_compare_epsilon.ipp>
#include <uhd/utils/fp_compare_delta.ipp>
#endif /* INCLUDED_UHD_UTILS_MATH_HPP */
|