MathTL
|
00001 // -*- c++ -*- 00002 00003 // +--------------------------------------------------------------------+ 00004 // | This file is part of MathTL - the Mathematical Template Library | 00005 // | | 00006 // | Copyright (c) 2002-2009 | 00007 // | Thorsten Raasch, Manuel Werner | 00008 // +--------------------------------------------------------------------+ 00009 00010 #ifndef _MATHTL_TINY_TOOLS_H 00011 #define _MATHTL_TINY_TOOLS_H 00012 00013 #include <cassert> 00014 #include <cmath> 00015 #include <functional> 00016 #include <map> 00017 00018 // some utility functions 00019 00021 template <class R> 00022 inline R abs(const R a) 00023 { 00024 return (a > 0 ? a : -a); 00025 } 00026 00028 template <class R> 00029 inline R sign(const R a) 00030 { 00031 return (a > 0 ? 1. : (a < 0 ? -1. : 0.)); 00032 } 00033 00035 00042 template <class R> 00043 inline R hypot(const R a, const R b) 00044 { 00045 R r(0); 00046 if (a == 0) 00047 r = abs(b); 00048 else 00049 { 00050 R c(b/a); 00051 r = abs(a) * sqrt(1+c*c); 00052 } 00053 return r; 00054 } 00055 00057 template <class I> 00058 I factorial(const I n) 00059 { 00060 I r(1); 00061 for (I i(2); i <= n; r *= i, i++); 00062 return r; 00063 } 00064 00076 inline int binomial(const int n, const int k) 00077 { 00078 int r(1); 00079 00080 if (k > n || k < 0) 00081 return 0; 00082 00083 if (k == 0) 00084 return 1; 00085 00086 for (int i(k+1); i <= n; i++) 00087 r *= i; 00088 00089 for (int i(2); i+k <= n; i++) 00090 r /= i; // always possible without remainder 00091 00092 return r; 00093 } 00094 00096 inline int minus1power(const int k) 00097 { 00098 return (k%2==0 ? 1 : -1); 00099 } 00100 00102 template <class I, class J> 00103 int intpower(const I n, const J k) 00104 { 00105 int r(1); 00106 for (J j(1); j <= k; j++) 00107 r *= n; 00108 00109 return r; 00110 } 00111 00116 template <class I, class C> 00117 class threshold_criterion 00118 : public std::unary_function<I, C> 00119 { 00120 public: 00121 threshold_criterion(const double eta) : eta_(eta) {} 00122 bool operator() (std::pair<const I, C>& p) { return fabs(p.second) < eta_; } 00123 00124 private: 00125 const double eta_; 00126 }; 00127 00132 inline 00133 double twotothejhalf(const int j) 00134 { 00135 return j%2 ? M_SQRT2 * (1<<(j>>1)) : 1<<(j>>1); 00136 } 00137 00142 inline 00143 int dyadic_modulo (const int x, const int j) 00144 { 00145 return (x >= 0 00146 ? x-((x>>j)<<j) 00147 : (x+(((-x)>>j)<<j)) ? x+((((-x)>>j)+1)<<j) : 0); 00148 } 00149 00150 00151 /* 00152 * computes floor(log2(n)), where n is a positive integer 00153 * Tested for int n, unsigned int n. 00154 * 2.5 times faster than log2(double) 00155 * 00156 * Be careful with negative arguments and automatic conversion to unsigned int. 00157 * 00158 * There might be more clever alternatives for this function! 00159 * 00160 * Assumption: 00161 * sizeof(int) = sizeof(unsigned int) = 4 00162 * 00163 * Code borrowed from: 00164 * Bit Twiddling Hacks - http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup 00165 * By Sean Eron Anderson 00166 * seander@cs.stanford.edu 00167 * (with additions from Andrew Shapira) 00168 */ 00169 const unsigned int log2Bits[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; //, 0xFFFFFFFF00000000}; // uncomment for 64 bit integers 00170 const unsigned int log2Sizes[] = {1, 2, 4, 8, 16}; //, 32}; // uncomment for 64 bit integers 00171 00172 inline unsigned int log2(const unsigned int n) 00173 { 00174 unsigned int v; // 32-bit value to find the log2 of 00175 v = n; 00176 register unsigned int r = 0; // result of log2(v) will go here 00177 int i; 00178 for (i = 4; i >= 0; i--) // unroll for speed... 00179 { 00180 if (v & log2Bits[i]) 00181 { 00182 v >>= log2Sizes[i]; 00183 r |= log2Sizes[i]; 00184 } 00185 } 00186 return r; 00187 } 00188 00189 #endif