util.hpp

Go to the documentation of this file.
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_

Generated on Wed Jun 6 17:27:46 2007 for OMNI by  doxygen 1.5.2