00001 ////////////////////////////////////////////////////////////////////////// 00002 // This material is provided "as is", with absolutely no warranty 00003 // expressed or implied. Any use is at your own risk. 00004 // 00005 // Permission to use or copy this software for any purpose is hereby 00006 // granted without fee, provided the above notices are retained on all 00007 // copies. Permission to modify the code and to distribute modified code 00008 // is granted, provided the above notices are retained, and a notice that 00009 // the code was modified is included with the above copyright notice. 00010 ////////////////////////////////////////////////////////////////////////// 00011 /** @file 00012 @brief Auxiliary constants and functions. 00013 00014 This header file contains declaration of the 00015 some useful constants and auxiliary functions. 00016 00017 @author Sergey Polichnoy 00018 */ 00019 #ifndef __OMNI_UTIL_HPP_ 00020 #define __OMNI_UTIL_HPP_ 00021 00022 #include <omni/defs.hpp> 00023 00024 #include <assert.h> 00025 00026 namespace omni 00027 { 00028 namespace util 00029 { /// @name Constants 00030 00031 ////////////////////////////////////////////////////////////////////////// 00032 /// @brief Square root of 2. @hideinitializer 00033 const double SQRT2 = 1.4142135623730950488016887242097; 00034 00035 ////////////////////////////////////////////////////////////////////////// 00036 /// @brief Square root of 3. @hideinitializer 00037 const double SQRT3 = 1.7320508075688772935274463415059; 00038 00039 ////////////////////////////////////////////////////////////////////////// 00040 /// @brief Decimal logarithm of 2. @hideinitializer 00041 const double LG2 = 0.3010299956639811952137388947245; 00042 00043 ////////////////////////////////////////////////////////////////////////// 00044 /// @brief Natural logarithm of 2. @hideinitializer 00045 const double LN2 = 0.6931471805599453094172321214582; 00046 00047 ////////////////////////////////////////////////////////////////////////// 00048 /// @brief The @b Pi value. @hideinitializer 00049 const double PI = 3.1415926535897932384626433832795; 00050 00051 } // Constants 00052 00053 00054 namespace util 00055 { /// @name Conversions 00056 00057 // radians and degrees 00058 double deg2rad(double deg); ///< @brief Convert degrees to the radians. 00059 double rad2deg(double rad); ///< @brief Convert radians to the degrees. 00060 00061 // dB and line 00062 double dB2line(double dB); ///< @brief Convert @b dB to the value in linear scale. 00063 double line2dB(double L); ///< @brief Convert value in linear scale to the @b dB. 00064 00065 // dBm and watt 00066 double dBm2watt(double dBm); ///< @brief Convert @b dBm to the watts. 00067 double watt2dBm(double W); ///< @brief Convert watts to the @b dBm. 00068 00069 // kph and mps 00070 double kph2mps(double kph); ///< @brief Convert @b kph to the @b mps. 00071 double mps2kph(double mps); ///< @brief Convert @b mps to the @b kph. 00072 00073 } // Conversions 00074 00075 00076 namespace util 00077 { /// @name Power of two and parity 00078 00079 ////////////////////////////////////////////////////////////////////////// 00080 /// @brief Is integer power of two? 00081 /** 00082 This functions checks the @a x arguments - is it integer power of two? 00083 00084 The valid integer powers of two: 0, 1, 2, 4, 8, 16, 32, 64, 128, etc... 00085 00086 @note The template argument @a T should be unsigned integer type. 00087 00088 @param[in] x The unsigned integer. 00089 @return @b true if argument is integer power of two, otherwise @b false. 00090 00091 @see log2() 00092 @see flp2() 00093 @see clp2() 00094 */ 00095 template<typename T> inline 00096 bool is_ipow2(T x) 00097 { 00098 return !(x & (x-1)); 00099 } 00100 00101 00102 ////////////////////////////////////////////////////////////////////////// 00103 /// @brief Binary integer logarithm. 00104 /** 00105 This function calculates a binary integer logarithm 00106 of the @a x argument. The input argument should be 00107 integer power of two and can't be zero. 00108 00109 @code 00110 log2(1) == 0; 00111 log2(2) == 1; 00112 log2(4) == 2; 00113 log2(8) == 3; 00114 @endcode 00115 00116 @note The template argument @a T should be unsigned integer type. 00117 00118 @param[in] x The unsigned integer. 00119 @return The binary logarithm. 00120 00121 @see is_ipow2() 00122 @see flp2() 00123 @see clp2() 00124 */ 00125 template<typename T> 00126 T log2(T x) 00127 { 00128 assert(x!=T() && is_ipow2(x) 00129 && "log2() argument should " 00130 "be integer power of two"); 00131 00132 T res = T(); 00133 while (!(x&1)) 00134 { 00135 x >>= 1; 00136 ++res; 00137 } 00138 00139 return res; 00140 } 00141 00142 00143 // disable some MSVC++ warnings 00144 #if defined(_MSC_VER) 00145 # pragma warning(push) 00146 # if (1400 == _MSC_VER) 00147 # pragma warning(disable: 4293) // warning C4293: '>>' : shift count negative or too big, undefined behavior 00148 # pragma warning(disable: 4333) // warning C4333: '>>' : right shift by too large amount, data loss 00149 # endif // 1400 == _MSC_VER 00150 # pragma warning(disable: 4127) // warning C4127: conditional expression is constant 00151 #endif // (MSC_VER) 00152 00153 00154 ////////////////////////////////////////////////////////////////////////// 00155 /// @brief Nearest (floor) integer power of two. 00156 /** 00157 This function calculates an integer value representing the largest 00158 integer power of two that is less than or equal to @a x argument. 00159 00160 @code 00161 flp2(4) == 4; 00162 flp2(5) == 4; 00163 flp2(7) == 4; 00164 flp2(9) == 8; 00165 @endcode 00166 00167 @note The template argument @a T should be unsigned integer type. 00168 00169 @param[in] x The unsigned integer. 00170 @return The nearest (floor) integer power of two. 00171 00172 @see is_ipow2() 00173 @see log2() 00174 @see clp2() 00175 */ 00176 template<typename T> 00177 T flp2(T x) 00178 { 00179 x |= x >> 1; 00180 x |= x >> 2; 00181 x |= x >> 4; 00182 00183 if (1 < sizeof(T)) 00184 x |= x >> 8; 00185 if (2 < sizeof(T)) 00186 x |= x >> 16; 00187 if (4 < sizeof(T)) 00188 x |= x >> 32; 00189 00190 return x - (x>>1); 00191 } 00192 00193 00194 ////////////////////////////////////////////////////////////////////////// 00195 /// @brief Nearest (ceil) integer power of two. 00196 /** 00197 This function calculates an integer value representing the smallest 00198 integer power of two that is greater than or equal to @a x argument. 00199 00200 @code 00201 clp2(4) == 4; 00202 clp2(5) == 8; 00203 clp2(7) == 8; 00204 clp2(9) == 16; 00205 @endcode 00206 00207 @note The template argument @a T should be unsigned integer type. 00208 00209 @param[in] x The unsigned integer. 00210 @return The nearest (ceil) integer power of two. 00211 00212 @see is_ipow2() 00213 @see log2() 00214 @see flp2() 00215 */ 00216 template<typename T> 00217 T clp2(T x) 00218 { 00219 x -= 1; 00220 00221 x |= x >> 1; 00222 x |= x >> 2; 00223 x |= x >> 4; 00224 00225 if (1 < sizeof(T)) 00226 x |= x >> 8; 00227 if (2 < sizeof(T)) 00228 x |= x >> 16; 00229 if (4 < sizeof(T)) 00230 x |= x >> 32; 00231 00232 return x + 1; 00233 } 00234 00235 00236 ////////////////////////////////////////////////////////////////////////// 00237 /// @brief Parity bit. 00238 /** 00239 This function calculates a parity bit of the input argument @a x. 00240 00241 The parity bit is equal to: 00242 - @b 1, if @a x has even number of nonzero bits, 00243 - @b 0, if @a x has odd number of nonzero bits. 00244 00245 @note The template argument @a T should be unsigned integer type. 00246 00247 @param[in] x The unsigned integer. 00248 @return The parity bit. 00249 */ 00250 template<typename T> 00251 T parity(T x) 00252 { 00253 if (4 < sizeof(T)) 00254 x ^= x >> 32; 00255 if (2 < sizeof(T)) 00256 x ^= x >> 16; 00257 if (1 < sizeof(T)) 00258 x ^= x >> 8; 00259 00260 x ^= x >> 4; 00261 x ^= x >> 2; 00262 x ^= x >> 1; 00263 00264 return (x&1); 00265 } 00266 00267 // restore some MSVC++ warnings 00268 #if defined(_MSC_VER) 00269 # pragma warning(pop) 00270 #endif // (MSC_VER) 00271 00272 } // Power of two and parity 00273 00274 00275 namespace util 00276 { /// @name Bits packing/unpacking and flip 00277 00278 ////////////////////////////////////////////////////////////////////////// 00279 /// @brief Binary to decimal (MSB first). 00280 /** 00281 This function converts input binary sequence [@a first, 00282 @a first + @a Nbits) to the one "decimal" value. First element 00283 of the input bit sequence is correspond to the most significant 00284 bit of the returned "decimal" value. 00285 00286 The number of bits @a Nbits should be less than or equal 00287 to the size of returned "decimal" value (i.e. 8*sizeof(T)). 00288 00289 For example, the following code will print "13" (1101b): 00290 00291 @code 00292 const int bits[] = { 1, 1, 0, 1 }; 00293 std::cout << bi2de_msb<unsigned>(bits, 4) << "\n"; 00294 @endcode 00295 00296 The last argument @a x is used for result type deduction. 00297 The following two lines are equivalent: 00298 00299 @code 00300 bi2de_msb<unsigned>(bits, 4); 00301 bi2de_msb(bits, 4, unsigned(0)); 00302 @endcode 00303 00304 @note The template argument @a T should be unsigned integer type. 00305 00306 @param[in] first Begin of the input bit sequence. 00307 @param[in] Nbits Number of bits to converting. 00308 @param[in] x Initial value, by default is zero. 00309 @return The "decimal" value. 00310 */ 00311 template<typename T, typename In> 00312 T bi2de_msb(In first, size_t Nbits, T x = T()) 00313 { 00314 assert(Nbits <= 8*sizeof(T) 00315 && "number of bits too big"); 00316 00317 for (; Nbits; --Nbits) 00318 { 00319 x <<= 1; 00320 if (*first) 00321 x |= 1; 00322 00323 ++first; 00324 } 00325 00326 return x; 00327 } 00328 00329 00330 ////////////////////////////////////////////////////////////////////////// 00331 /// @brief Decimal to binary (MSB first). 00332 /** 00333 This function convert "decimal" value @a x to the output bit 00334 sequence [@a first, @a first + @a Nbits). First element of the 00335 output bit sequence is correspond to the most significant bit 00336 of the input "decimal" value. 00337 00338 The number of bits @a Nbits should be less than or equal 00339 to the size of input "decimal" value (i.e. 8*sizeof(T)). 00340 00341 For example, the following code will print "1101b" (13): 00342 00343 @code 00344 std::vector<int> bits(4); 00345 de2bi_msb(13, bits.size(), bits.begin()); 00346 std::copy(bits.begin(), bits.end(), 00347 std::ostream_iterator<int>(std::cout, "")); 00348 std::cout << "b\n"; 00349 @endcode 00350 00351 @note The template argument @a T should be unsigned integer type. 00352 00353 @param[in] x Input "decimal" value. 00354 @param[in] Nbits Number of bits to converting. 00355 @param[in] first Begin of the output bit sequence. 00356 @return End of the output bit sequence. 00357 */ 00358 template<typename T, typename Out> 00359 Out de2bi_msb(T x, size_t Nbits, Out first) 00360 { 00361 assert(Nbits <= 8*sizeof(T) 00362 && "number of bits too big"); 00363 00364 T b = T(1) << Nbits; 00365 00366 for (; Nbits; --Nbits) 00367 { 00368 b >>= 1; 00369 *first = 0 < (x&b); 00370 00371 ++first; 00372 } 00373 00374 return first; 00375 } 00376 00377 00378 ////////////////////////////////////////////////////////////////////////// 00379 /// @brief Binary to decimal (LSB first). 00380 /** 00381 This function converts input binary sequence [@a first, 00382 @a first + @a Nbits) to the one "decimal" value. First element 00383 of the input bit sequence is correspond to the least significant 00384 bit of the returned "decimal" value. 00385 00386 The number of bits @a Nbits should be less than or equal 00387 to the size of returned "decimal" value (i.e. 8*sizeof(T)). 00388 00389 For example, the following code will print "13" (1101b): 00390 00391 @code 00392 const int bits[] = { 1, 0, 1, 1 }; 00393 std::cout << bi2de_lsb<unsigned>(bits, 4) << "\n"; 00394 @endcode 00395 00396 The last argument @a x is used for result type deduction. 00397 The following two lines are equivalent: 00398 00399 @code 00400 bi2de_lsb<unsigned>(bits, 4); 00401 bi2de_lsb(bits, 4, unsigned(0)); 00402 @endcode 00403 00404 @note The template argument @a T should be unsigned integer type. 00405 00406 @param[in] first Begin of the input bit sequence. 00407 @param[in] Nbits Number of bits to converting. 00408 @param[in] x Initial value, by default is zero. 00409 @return The "decimal" value. 00410 */ 00411 template<typename T, typename In> 00412 T bi2de_lsb(In first, size_t Nbits, T x = T()) 00413 { 00414 assert(Nbits <= 8*sizeof(T) 00415 && "number of bits too big"); 00416 00417 T b = T(1); 00418 00419 for (; Nbits; --Nbits) 00420 { 00421 if (*first) 00422 x |= b; 00423 00424 ++first; 00425 b <<= 1; 00426 } 00427 00428 return x; 00429 } 00430 00431 00432 ////////////////////////////////////////////////////////////////////////// 00433 /// @brief Decimal to binary (LSB first). 00434 /** 00435 This function convert "decimal" value @a x to the output bit 00436 sequence [@a first, @a first + @a Nbits). First element of the 00437 output bit sequence is correspond to the least significant bit 00438 of the input "decimal" value. 00439 00440 The number of bits @a Nbits should be less than or equal 00441 to the size of input "decimal" value (i.e. 8*sizeof(T)). 00442 00443 For example, the following code will print "1011b" (13): 00444 00445 @code 00446 std::vector<int> bits(4); 00447 de2bi_lsb(13, bits.size(), bits.begin()); 00448 std::copy(bits.begin(), bits.end(), 00449 std::ostream_iterator<int>(std::cout, "")); 00450 std::cout << "b\n"; 00451 @endcode 00452 00453 @note The template argument @a T should be unsigned integer type. 00454 00455 @param[in] x Input "decimal" value. 00456 @param[in] Nbits Number of bits to converting. 00457 @param[in] first Begin of the output bit sequence. 00458 @return End of the output bit sequence. 00459 */ 00460 template<typename T, typename Out> 00461 Out de2bi_lsb(T x, size_t Nbits, Out first) 00462 { 00463 assert(Nbits <= 8*sizeof(T) 00464 && "number of bits too big"); 00465 00466 T b = T(1); 00467 00468 for (; Nbits; --Nbits) 00469 { 00470 *first = 0 < (x&b); 00471 00472 ++first; 00473 b <<= 1; 00474 } 00475 00476 return first; 00477 } 00478 00479 00480 ////////////////////////////////////////////////////////////////////////// 00481 /// @brief Reverse the bit order. 00482 /** 00483 This function returns the flipped @a Nbits 00484 least significant bits of the argument @a x. 00485 00486 To flip all bits, you can use the following code: 00487 00488 @code 00489 bits_flip(x, sizeof(x)*8); 00490 @endcode 00491 00492 @note The template argument @a T should be unsigned integer type. 00493 00494 @param[in] x The input integer value. 00495 @param[in] Nbits Number of least significant bits. 00496 @return The flipped value. 00497 */ 00498 template<typename T> 00499 T bits_flip(T x, size_t Nbits) 00500 { 00501 assert(Nbits <= 8*sizeof(T) 00502 && "number of bits too big"); 00503 00504 T res = T(); 00505 while (Nbits--) 00506 { 00507 res <<= 1; 00508 res |= x&1; 00509 x >>= 1; 00510 } 00511 00512 return res; 00513 } 00514 00515 } // Bits packing/unpacking and flip 00516 00517 00518 namespace util 00519 { /// @name Polynomials 00520 00521 ////////////////////////////////////////////////////////////////////////// 00522 /// @brief Calculate the polynomial's function. 00523 /** 00524 This function calculates the value of polynomial's function: 00525 00526 @code 00527 A[0]*pow(x,N-1) + A[1]*pow(x,N-2)... + A[N-2]*x + A[N-1] 00528 @endcode 00529 00530 where 00531 - @b A is a polynomial's coefficients 00532 defined by sequence [@a first, @a last), 00533 - @b N is polynomial's order. 00534 00535 The last argument is used for result type deduction. 00536 00537 @param[in] x The polynomial's argument. 00538 @param[in] first Begin of polynomial's coefficients. 00539 @param[in] last End of polynomial's coefficients. 00540 @return The value of polynomial's function. 00541 */ 00542 template<typename TY, typename TX, typename Bi> 00543 TY poly(const TX &x, Bi first, Bi last, const TY&) 00544 { 00545 if (first != last) 00546 { 00547 TY y = (*first); 00548 ++first; 00549 00550 for (; first != last; ++first) 00551 y = y*x + (*first); 00552 00553 return y; 00554 } 00555 else 00556 return TY(); 00557 } 00558 00559 00560 ////////////////////////////////////////////////////////////////////////// 00561 /// @brief Calculate the polynomial's function. 00562 /** 00563 This function calculates the value of polynomial's function: 00564 00565 @code 00566 A[0]*pow(x,N-1) + A[1]*pow(x,N-2)... + A[N-2]*x + A[N-1] 00567 @endcode 00568 00569 where 00570 - @b A is a polynomial's coefficients 00571 defined by sequence [@a first, @a last), 00572 - @b N is polynomial's order. 00573 00574 @note The result's type is equal to the @a x argument's type. 00575 00576 @param[in] x The polynomial's argument. 00577 @param[in] first Begin of polynomial's coefficients. 00578 @param[in] last End of polynomial's coefficients. 00579 @return The value of polynomial's function. 00580 */ 00581 template<typename T, typename Bi> inline 00582 T poly(const T &x, Bi first, Bi last) 00583 { 00584 return poly(x, first, last, x); 00585 } 00586 00587 } // Polynomials 00588 00589 } // omni namespace 00590 00591 #endif // __OMNI_UTIL_HPP_