nux-1.16.0
MathUtility.h
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #ifndef MATHUTILITY_H
00024 #define MATHUTILITY_H
00025 
00026 #include <cstdio>
00027 #include <cstdlib>
00028 #include <cstdarg>
00029 #include <cmath>
00030 #include <cstring>
00031 #include <ctime>
00032 
00033 #include "Constants.h"
00034 
00035 namespace nux
00036 {
00037   template<typename T> inline T Square (const T A)
00038   {
00039     return A * A;
00040   }
00041   template<typename T> inline T Clamp (const T X, const T min_value, const T max_value)
00042   {
00043     return X < min_value ? min_value : X < max_value ? X : max_value;
00044   }
00045 
00046   template<typename T> inline T ClampUp (const T X, const T min_value)
00047   {
00048     return X < min_value ? min_value : X;
00049   }
00050 
00051   template<typename T> inline T ClampDown (const T X, const T max_value)
00052   {
00053     return X > max_value ? max_value : X;
00054   }
00055 
00056   template<typename T> inline T Align (const T Ptr, int Alignment)
00057   {
00058     return (T) (((NUX_POINTER) Ptr + Alignment - 1) & ~ (Alignment - 1));
00059   }
00060 
00061   //Bitwise rotation on the left.
00062   template<typename T> inline const T Rol (const T &a, const unsigned int n = 1)
00063   {
00064     return (a << n) | (a >> ((sizeof (T) << 3) - n));
00065   }
00066   //Bitwise rotation on the right.
00067   template<typename T> inline const T Ror (const T &a, const unsigned int n = 1)
00068   {
00069     return (a >> n) | (a << ((sizeof (T) << 3) - n));
00070   }
00071 
00073   template<typename T> inline const T Abs (const T &a)
00074   {
00075     return a >= 0 ? a : -a;
00076   }
00078   template<typename T> inline const T &Min (const T &a, const T &b)
00079   {
00080     return a <= b ? a : b;
00081   }
00083   template<typename T> inline const T &Min (const T &a, const T &b, const T &c)
00084   {
00085     return Min<T> (Min<T> (a, b), c);
00086   }
00088   template<typename T> inline const T &Min (const T &a, const T &b, const T &c, const T &d)
00089   {
00090     return Min<T> (Min<T> (Min<T> (a, b), c), d);
00091   }
00093   template<typename T> inline const T &Max (const T &a, const T &b)
00094   {
00095     return a >= b ? a : b;
00096   }
00098   template<typename T> inline const T &Max (const T &a, const T &b, const T &c)
00099   {
00100     return Max<T> (Max<T> (a, b), c);
00101   }
00103   template<typename T> inline const T &Max (const T &a, const T &b, const T &c, const T &d)
00104   {
00105     return Max<T> (Max<T> (a, b, c), d);
00106   }
00107 
00108   template<typename T> inline T Max3 (const T A, const T B, const T C)
00109   {
00110     return Max<T> (Max<T> (A, B), C);
00111   }
00112 
00113   template<typename T> inline T Min3 (const T A, const T B, const T C)
00114   {
00115     return Min<T> (Min<T> (A, B), C);
00116   }
00117 
00119   template<typename T> inline T Sign (const T &x)
00120   {
00121     return (x < 0) ? -1 : (x == 0 ? 0 : 1);
00122   }
00123 
00124 
00125   template<typename T> inline T Modulo (const T &x, const T &m)
00126   {
00127     return x - m * (T) std::floor ((double) x / m);
00128   }
00129 
00130   inline int ModuloInt (const int x, const int m)
00131   {
00132     return x >= 0 ? x % m : (x % m ? m + x % m : 0);
00133   }
00134 
00135   template<typename T> inline T MinMod (const T &a, const T &b)
00136   {
00137     return a * b <= 0 ? 0 : (a > 0 ? (a < b ? a : b) : (a < b ? b : a));
00138   }
00139 
00141 
00144   inline double Random()
00145   {
00146     return (double) std::rand() / RAND_MAX;
00147   }
00148 
00150 
00153   inline double CRandom()
00154   {
00155     return 1 - 2 * (std::rand() / RAND_MAX);
00156   }
00157 
00159 
00162   inline double RandomGaussian()
00163   {
00164     return std::sqrt (-2 * std::log ((double) (1e-10 + (1 - 2e-10) * std::rand()))) * std::cos ((double) (2 * 3.14f/*Const::pi*/*std::rand()));
00165   }
00166 
00167   inline unsigned int RandomUInt()
00168   {
00169     return std::rand();
00170   }
00171 
00172   inline unsigned int RandomUInt (unsigned int max_random)
00173   {
00174     return std::rand() % max_random;
00175   }
00176 
00177   inline t_size DiffPointer (void *Ptr0, void *Ptr1)
00178   {
00179     if ((t_size) Ptr0 >= (t_size) Ptr1) return (t_size) ((t_size) Ptr0 - (t_size) Ptr1);
00180 
00181     return (t_size) ((t_size) Ptr1 - (t_size) Ptr0);
00182   }
00183   // Dangerous to use!
00184   template<typename T> inline T SubstractPointer (void *Ptr, t_size Value)
00185   {
00186     return (T) (((t_size) Ptr) - Value);
00187   }
00188   template<typename T> inline T AddPointer (void *Ptr, t_size Value)
00189   {
00190     return (T) (((t_size) Ptr) + Value);
00191   }
00192 
00194 
00197   template<typename T> inline T RoundUp (T Value, int Alignment)
00198   {
00199     return (Value + (Alignment - 1)) & ~ (Alignment - 1);
00200   }
00201 
00203 
00206   template<typename T> inline T RoundDown (T Value, int Alignment)
00207   {
00208     return ((Value) & ~ (Alignment - 1));
00209   }
00210 
00212 
00215   template<typename T> inline bool IsAligned (T Value, int Alignment)
00216   {
00217     return (((Value) & ~ (Alignment - 1)) == 0);
00218   }
00219 
00224   inline t_u16 ReverseByteOrdering (t_u16 value)
00225   {
00226     t_u16 temp;
00227     t_u8 *src = (t_u8 *) &value;
00228     t_u8 *dest = (t_u8 *) &temp;
00229 
00230     dest[0] = src[1];
00231     dest[1] = src[0];
00232 
00233     return temp;
00234   }
00235 
00240   inline t_u32 ReverseByteOrdering (t_u32 value)
00241   {
00242     t_u32 temp;
00243     t_u8 *src = (t_u8 *) &value;
00244     t_u8 *dest = (t_u8 *) &temp;
00245 
00246     dest[0] = src[3];
00247     dest[1] = src[2];
00248     dest[2] = src[1];
00249     dest[3] = src[0];
00250 
00251     return temp;
00252   }
00253 
00258   inline t_u64 ReverseByteOrdering (t_u64 value)
00259   {
00260     t_u64 temp;
00261     t_u8 *src = (t_u8 *) &value;
00262     t_u8 *dest = (t_u8 *) &temp;
00263 
00264     dest[0] = src[7];
00265     dest[1] = src[6];
00266     dest[2] = src[5];
00267     dest[3] = src[4];
00268     dest[4] = src[3];
00269     dest[5] = src[2];
00270     dest[6] = src[1];
00271     dest[7] = src[0];
00272 
00273     return temp;
00274   }
00275 
00276   // Bit Hack
00277 
00278   // Determining if an integer is a power of 2
00279   // http://graphics.stanford.edu/~seander/bithacks.html
00280   inline bool IsPowerOf2 (unsigned int n)
00281   {
00282     // The algorithm does not 0 consider 0 a power of two. (this is right)
00283     return ! (n & (n - 1)) && n;
00284   }
00285 
00286   // Compute the next highest power of 2 of 32-bit v
00287   // http://graphics.stanford.edu/~seander/bithacks.html
00288   inline unsigned int NextPowerOfTwo (unsigned int x)
00289   {
00290     x = x - 1;
00291     x = x | (x >> 1);
00292     x = x | (x >> 2);
00293     x = x | (x >> 4);
00294     x = x | (x >> 8);
00295     x = x | (x >> 16);
00296     return x + 1;
00297   }
00298 
00299   inline unsigned int GetLowerPowerOfTwoExponent (unsigned int x)
00300   {
00301     int count = 0;
00302 
00303     while (x > 1)
00304     {
00305       x >>= 1;
00306       count++;
00307     }
00308 
00309     return count;
00310   }
00311 
00312   inline unsigned int PowerOfTwo (int i)
00313   {
00314     int e = 0;
00315     unsigned int power = 1;
00316 
00317     while (e < i)
00318     {
00319       power = power << 1;
00320       e++;
00321     }
00322 
00323     return power;
00324   }
00325 
00326   // ClearLSBBit(0x01001100) = 0x01001000
00327   inline unsigned int Hak32_ClearLSBBit (unsigned int N)
00328   {
00329     return N & (N - 1);
00330   }
00331 
00332   // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
00333   // Hak32_CountNumBits(0x01001100) = 3
00334   inline unsigned int Hak32_CountNumBits (unsigned int N)
00335   {
00336     unsigned int v = N; // count the number of bits set in v
00337     unsigned int c; // c accumulates the total bits set in v
00338 
00339     for (c = 0; v; c++)
00340     {
00341       v &= v - 1; // clear the least significant bit set
00342     }
00343 
00344     return c;
00345   }
00346 
00347   // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan : Compute parity in parallel
00348   inline unsigned int Hak32_BitParity (unsigned int N)
00349   {
00350     unsigned int v = N;  // word value to compute the parity of
00351     v ^= v >> 16;
00352     v ^= v >> 8;
00353     v ^= v >> 4;
00354     v &= 0xf;
00355     return (0x6996 >> v) & 1;
00356   }
00357 
00358 #define HAK32_SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
00359 
00360   // Return true if the CPU is little endian
00361   inline bool Hak32_CPULittleEndian()
00362   {
00363     const int x = 1;
00364     return ((unsigned char *) &x) [0] ? true : false;
00365   }
00366 
00367   // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
00368   // Find the log base 10 of an N-bit integer in O(lg(N))
00369   inline unsigned int Hak32_Log2 (unsigned int N)
00370   {
00371     unsigned int v = N; // find the log base 2 of 32-bit v
00372     int r;          // result goes here
00373 
00374     static const int MultiplyDeBruijnBitPosition[32] =
00375     {
00376       0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
00377       31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
00378     };
00379 
00380     v |= v >> 1; // first round down to power of 2
00381     v |= v >> 2;
00382     v |= v >> 4;
00383     v |= v >> 8;
00384     v |= v >> 16;
00385     v = (v >> 1) + 1;
00386 
00387     r = MultiplyDeBruijnBitPosition[static_cast<unsigned int> (v * 0x077CB531UL) >> 27];
00388     return r;
00389   }
00390 
00391   // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
00392   // Find the log base 2 of an N-bit integer in O(lg(N))
00393   inline unsigned int Hak32_Log10 (unsigned int N)
00394   {
00395     unsigned int v = N; // non-zero 32-bit integer value to compute the log base 10 of
00396     int r;          // result goes here
00397     int t;          // temporary
00398 
00399     static unsigned int const PowersOf10[] =
00400     {
00401       1, 10, 100, 1000, 10000, 100000,
00402       1000000, 10000000, 100000000, 1000000000
00403     };
00404 
00405     t = (Hak32_Log2 (v) + 1) * 1233 >> 12; // (use a lg2 method from above)
00406     r = t - (v < PowersOf10[t]);
00407 
00408     return r;
00409   }
00410 
00411   // http://graphics.stanford.edu/~seander/bithacks.html
00412   // Count the consecutive zero bits (trailing) on the right by binary search
00413   inline unsigned int Hack32_TrailingZeroRight (unsigned int N)
00414   {
00415     unsigned int v = N;     // 32-bit word input to count zero bits on right
00416     unsigned int c;     // c will be the number of zero bits on the right,
00417     // so if v is 1101000 (base 2), then c will be 3
00418     // NOTE: if 0 == v, then c = 31.
00419     if (v & 0x1)
00420     {
00421       // special case for odd v (assumed to happen half of the time)
00422       c = 0;
00423     }
00424     else
00425     {
00426       c = 1;
00427 
00428       if ((v & 0xffff) == 0)
00429       {
00430         v >>= 16;
00431         c += 16;
00432       }
00433 
00434       if ((v & 0xff) == 0)
00435       {
00436         v >>= 8;
00437         c += 8;
00438       }
00439 
00440       if ((v & 0xf) == 0)
00441       {
00442         v >>= 4;
00443         c += 4;
00444       }
00445 
00446       if ((v & 0x3) == 0)
00447       {
00448         v >>= 2;
00449         c += 2;
00450       }
00451 
00452       c -= v & 0x1;
00453     }
00454 
00455     return c;
00456   }
00457 
00458 }
00459 
00460 #endif // MATHUTILITY_H
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends