basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : defaults.hpp 00004 * DESCRIPTION: Templates and default implementations of several operations 00005 * COPYRIGHT : (C) 2003 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #ifndef __MMX_DEFAULTS_HPP 00014 #define __MMX_DEFAULTS_HPP 00015 #include <basix/basix.hpp> 00016 00018 00019 namespace mmx { 00020 00021 /****************************************************************************** 00022 * Formatted conversions 00023 ******************************************************************************/ 00024 00025 template<typename T,typename F> inline T as (const F& x); 00026 template<typename T,typename F> inline T promote (const F& x, const T& y); 00027 00028 template<typename F> inline bool 00029 promote (const F& x, const bool&) { return as<bool> (x); } 00030 template<typename F> inline char 00031 promote (const F& x, const char&) { return as<char> (x); } 00032 template<typename F> inline signed char 00033 promote (const F& x, const signed char&) { return as<signed char> (x); } 00034 template<typename F> inline unsigned char 00035 promote (const F& x, const unsigned char&) { return as<unsigned char> (x); } 00036 template<typename F> inline int 00037 promote (const F& x, const int&) { return as<int> (x); } 00038 template<typename F> inline unsigned int 00039 promote (const F& x, const unsigned int&) { return as<unsigned int> (x); } 00040 template<typename F> inline long int 00041 promote (const F& x, const long int&) { return as<long int> (x); } 00042 template<typename F> inline unsigned long int 00043 promote (const F& x, const unsigned long int&) { 00044 return as<unsigned long int> (x); } 00045 template<typename F> inline long long int 00046 promote (const F& x, const long long int&) { return as<long long int> (x); } 00047 template<typename F> inline unsigned long long int 00048 promote (const F& x, const unsigned long long int&) { 00049 return as<unsigned long long int> (x); } 00050 template<typename F> inline float 00051 promote (const F& x, const float&) { return as<float> (x); } 00052 template<typename F> inline double 00053 promote (const F& x, const double&) { return as<double> (x); } 00054 00055 /****************************************************************************** 00056 * Hash functions and equality testing 00057 ******************************************************************************/ 00058 00059 typedef void* void_ptr; 00060 typedef char* char_ptr; 00061 00062 inline nat hash (char c) { return (nat) c; } 00063 inline nat hash (signed char c) { return (nat) c; } 00064 inline nat hash (unsigned char c) { return (nat) c; } 00065 inline nat hash (short int c) { return (nat) c; } 00066 inline nat hash (short unsigned int c) { return (nat) c; } 00067 inline nat hash (int c) { return (nat) c; } 00068 inline nat hash (unsigned int c) { return (nat) c; } 00069 inline nat hash (long int c) { return (nat) c; } 00070 inline nat hash (long unsigned int c) { return (nat) c; } 00071 inline nat hash (long long int c) { 00072 nat h = (nat) ((c >> (4 * sizeof (long int))) >> (4 * sizeof (long int))); 00073 return (h<<1) ^ (h<<5) ^ (h>>27) ^ ((nat) c); } 00074 inline nat hash (long long unsigned int c) { 00075 nat h = (nat) ((c >> (4 * sizeof (long int))) >> (4 * sizeof (long int))); 00076 return (h<<1) ^ (h<<5) ^ (h>>27) ^ ((nat) c); } 00077 inline nat hash (const float& x) { 00078 return (*((nat*) ((void*) &x))) & 0xffffffff; } 00079 inline nat hash (const double& x) { 00080 union { nat n; double d; } u; 00081 u.d= x; return u.n; } 00082 template<typename C> inline nat hash (C* p) { return as_hash (p); } 00083 00084 inline nat exact_hash (char c) { return (nat) c; } 00085 inline nat exact_hash (signed char c) { return (nat) c; } 00086 inline nat exact_hash (unsigned char c) { return (nat) c; } 00087 inline nat exact_hash (short int c) { return (nat) c; } 00088 inline nat exact_hash (short unsigned int c) { return (nat) c; } 00089 inline nat exact_hash (int c) { return (nat) c; } 00090 inline nat exact_hash (unsigned int c) { return (nat) c; } 00091 inline nat exact_hash (long int c) { return (nat) c; } 00092 inline nat exact_hash (long unsigned int c) { return (nat) c; } 00093 inline nat exact_hash (long long int c) { 00094 nat h = (nat) ((c >> (4 * sizeof (long int))) >> (4 * sizeof (long int))); 00095 return (h<<1) ^ (h<<5) ^ (h>>27) ^ ((nat) c); } 00096 inline nat exact_hash (long long unsigned int c) { 00097 nat h = (nat) ((c >> (4 * sizeof (long int))) >> (4 * sizeof (long int))); 00098 return (h<<1) ^ (h<<5) ^ (h>>27) ^ ((nat) c); } 00099 inline nat exact_hash (const float& x) { 00100 return (*((nat*) ((void*) &x))) & 0xffffffff; } 00101 inline nat exact_hash (const double& x) { 00102 union { nat n; double d; } u; 00103 u.d= x; return u.n; } 00104 template<typename C> inline nat exact_hash (C* p) { return as_hash (p); } 00105 00106 inline bool exact_eq (char c1, char c2) { return c1 == c2; } 00107 inline bool exact_eq (signed char c1, signed char c2) { return c1 == c2; } 00108 inline bool exact_eq (unsigned char c1, unsigned char c2) { return c1 == c2; } 00109 inline bool exact_eq (short int c1, short int c2) { return c1 == c2; } 00110 inline bool exact_eq (short unsigned int c1, short unsigned int c2) { 00111 return c1 == c2; } 00112 inline bool exact_eq (int c1, int c2) { return c1 == c2; } 00113 inline bool exact_eq (unsigned int c1, unsigned int c2) { return c1 == c2; } 00114 inline bool exact_eq (long int c1, long int c2) { return c1 == c2; } 00115 inline bool exact_eq (long unsigned int c1, long unsigned int c2) { 00116 return c1 == c2; } 00117 inline bool exact_eq (long long int c1, long long int c2) { return c1 == c2; } 00118 inline bool exact_eq (long long unsigned int c1, long long unsigned int c2) { 00119 return c1 == c2; } 00120 00121 inline bool exact_eq (float x, float y) { return x == y; } 00122 inline bool exact_eq (double x, double y) { return x == y; } 00123 template<typename C> inline bool exact_eq (C* p1, C* p2) { return p1 == p2; } 00124 00125 inline bool exact_neq (char c1, char c2) { return c1 != c2; } 00126 inline bool exact_neq (signed char c1, signed char c2) { return c1 != c2; } 00127 inline bool exact_neq (unsigned char c1, unsigned char c2) { return c1 != c2; } 00128 inline bool exact_neq (short int c1, short int c2) { return c1 != c2; } 00129 inline bool exact_neq (short unsigned int c1, short unsigned int c2) { 00130 return c1 != c2; } 00131 inline bool exact_neq (int c1, int c2) { return c1 != c2; } 00132 inline bool exact_neq (unsigned int c1, unsigned int c2) { return c1 != c2; } 00133 inline bool exact_neq (long int c1, long int c2) { return c1 != c2; } 00134 inline bool exact_neq (long unsigned int c1, long unsigned int c2) { 00135 return c1 != c2; } 00136 inline bool exact_neq (long long int c1, long long int c2) { return c1 != c2; } 00137 inline bool exact_neq (long long unsigned int c1, long long unsigned int c2) { 00138 return c1 != c2; } 00139 00140 inline bool exact_neq (float x, float y) { return x != y; } 00141 inline bool exact_neq (double x, double y) { return x != y; } 00142 template<typename C> inline bool exact_neq (C* p1, C* p2) { return p1 != p2; } 00143 00144 #define TRUE_TO_EXACT_IDENTITY_SUGAR(TMPL,T) \ 00145 TMPL inline nat exact_hash (const T& x) { \ 00146 return hash (x); } \ 00147 TMPL inline bool exact_eq (const T& x, const T& y) { \ 00148 return x == y; } \ 00149 TMPL inline bool exact_neq (const T& x, const T& y) { \ 00150 return x != y; } 00151 00152 #define HARD_TO_EXACT_IDENTITY_SUGAR(TMPL,T) \ 00153 TMPL inline nat exact_hash (const T& x) { \ 00154 return hard_hash (x); } \ 00155 TMPL inline bool exact_eq (const T& x, const T& y) { \ 00156 return hard_eq (x, y); } \ 00157 TMPL inline bool exact_neq (const T& x, const T& y) { \ 00158 return hard_neq (x, y); } 00159 00160 #define HARD_TO_TRUE_IDENTITY_SUGAR(TMPL,T) \ 00161 TMPL inline nat hash (const T& x) { \ 00162 return hard_hash (x); } \ 00163 TMPL inline bool operator == (const T& x, const T& y) { \ 00164 return hard_eq (x, y); } \ 00165 TMPL inline bool operator != (const T& x, const T& y) { \ 00166 return hard_neq (x, y); } 00167 00168 #define TRUE_IDENTITY_OP_SUGAR(TMPL,T) \ 00169 TMPL inline nat hash (const T& x) { \ 00170 return unary_hash<hash_op> (x); } \ 00171 TMPL inline bool operator == (const T& x, const T& y) { \ 00172 return binary_test<equal_op> (x, y); } \ 00173 TMPL inline bool operator != (const T& x, const T& y) { \ 00174 return !binary_test<equal_op> (x, y); } 00175 00176 #define EXACT_IDENTITY_OP_SUGAR(TMPL,T) \ 00177 TMPL inline nat exact_hash (const T& x) { \ 00178 return unary_hash<exact_hash_op> (x); } \ 00179 TMPL inline bool exact_eq (const T& x, const T& y) { \ 00180 return binary_test<exact_eq_op> (x, y); } \ 00181 TMPL inline bool exact_neq (const T& x, const T& y) { \ 00182 return !binary_test<exact_eq_op> (x, y); } 00183 00184 #define HARD_IDENTITY_OP_SUGAR(TMPL,T) \ 00185 TMPL inline nat hard_hash (const T& x) { \ 00186 return unary_hash<hard_hash_op> (x); } \ 00187 TMPL inline bool hard_eq (const T& x, const T& y) { \ 00188 return binary_test<hard_eq_op> (x, y); } \ 00189 TMPL inline bool hard_neq (const T& x, const T& y) { \ 00190 return !binary_test<hard_eq_op> (x, y); } 00191 00192 #define EQUAL_INT_SUGAR(TMPL,T) \ 00193 TMPL inline bool operator == (const T& x, const int& y) { \ 00194 return x == promote (y, x); } \ 00195 TMPL inline bool operator != (const T& x, const int& y) { \ 00196 return x != promote (y, x); } \ 00197 TMPL inline bool exact_eq (const T& x, const int& y) { \ 00198 return exact_eq (x, promote (y, x)); } \ 00199 TMPL inline bool exact_neq (const T& x, const int& y) { \ 00200 return exact_neq (x, promote (y, x)); } 00201 00202 #define EQUAL_SCALAR_SUGAR(TMPL,T,C) \ 00203 TMPL inline bool operator == (const T& x, const C& y) { \ 00204 return x == T(y); } \ 00205 TMPL inline bool operator != (const T& x, const C& y) { \ 00206 return x != T(y); } \ 00207 TMPL inline bool exact_eq (const T& x, const C& y) { \ 00208 return exact_eq (x, T(y)); } \ 00209 TMPL inline bool exact_neq (const T& x, const C& y) { \ 00210 return exact_neq (x, T(y)); } 00211 00212 template<typename C> bool inline is_exact_zero (const C& x) { 00213 return exact_eq (x, promote (0, x)); } 00214 00215 /****************************************************************************** 00216 * Copy 00217 ******************************************************************************/ 00218 00219 inline char copy (char c) { return c; } 00220 inline signed char copy (signed char c) { return c; } 00221 inline unsigned char copy (unsigned char c) { return c; } 00222 inline short int copy (short int c) { return c; } 00223 inline short unsigned int copy (short unsigned int c) { return c; } 00224 inline int copy (int c) { return c; } 00225 inline unsigned int copy (unsigned int c) { return c; } 00226 inline long int copy (long int c) { return c; } 00227 inline long unsigned int copy (long unsigned int c) { return c; } 00228 inline long long int copy (long long int c) { return c; } 00229 inline long long unsigned int copy (long long unsigned int c) { return c; } 00230 00231 inline float copy (float c) { return c; } 00232 inline double copy (double c) { return c; } 00233 00234 template<typename C> inline void* copy (C* p) { return p; } 00235 template<typename C> inline C duplicate (const C& x) { return x; } 00236 template<typename C> inline void clear (C& x) { x= promote (0, x); } 00237 00238 #define COPY_OP_SUGAR(TMPL,T) \ 00239 TMPL inline T copy (const T& x) { \ 00240 return unary_map<id_op> (x); } \ 00241 TMPL inline T duplicate (const T& x) { \ 00242 return unary_map<duplicate_op> (x); } 00243 00244 /****************************************************************************** 00245 * Arithmetic 00246 ******************************************************************************/ 00247 00248 #define ADDITIVE_INT_SUGAR(TMPL,T) \ 00249 TMPL inline T operator + (const T& x, const int& y) { \ 00250 return x + promote (y, x); } \ 00251 TMPL inline T operator + (const int& x, const T& y) { \ 00252 return promote (x, y) + y; } \ 00253 TMPL inline T operator - (const T& x, const int& y) { \ 00254 return x - promote (y, x); } \ 00255 TMPL inline T operator - (const int& x, const T& y) { \ 00256 return promote (x, y) - y; } 00257 00258 #define ADDITIVE_SCALAR_INT_SUGAR(TMPL,T) \ 00259 TMPL inline T operator + (const T& x, const int& y) { \ 00260 return x + promote_scalar (y, x); } \ 00261 TMPL inline T operator + (const int& x, const T& y) { \ 00262 return promote_scalar (x, y) + y; } \ 00263 TMPL inline T operator - (const T& x, const int& y) { \ 00264 return x - promote_scalar (y, x); } \ 00265 TMPL inline T operator - (const int& x, const T& y) { \ 00266 return promote_scalar (x, y) - y; } 00267 00268 #define ADDITIVE_SCALAR_SUGAR(TMPL,T,C) \ 00269 TMPL inline T operator + (const T& x, const C& y) { return x + T(y); } \ 00270 TMPL inline T operator + (const C& x, const T& y) { return T(x) + y; } \ 00271 TMPL inline T operator - (const T& x, const C& y) { return x - T(y); } \ 00272 TMPL inline T operator - (const C& x, const T& y) { return T(x) - y; } 00273 00274 #define ARITH_INT_SUGAR(TMPL,T) \ 00275 TMPL inline T operator + (const T& x, const int& y) { \ 00276 return x + promote (y, x); } \ 00277 TMPL inline T operator + (const int& x, const T& y) { \ 00278 return promote (x, y) + y; } \ 00279 TMPL inline T operator - (const T& x, const int& y) { \ 00280 return x - promote (y, x); } \ 00281 TMPL inline T operator - (const int& x, const T& y) { \ 00282 return promote (x, y) - y; } \ 00283 TMPL inline T operator * (const T& x, const int& y) { \ 00284 return x * promote (y, x); } \ 00285 TMPL inline T operator * (const int& x, const T& y) { \ 00286 return promote (x, y) * y; } \ 00287 TMPL inline T operator / (const T& x, const int& y) { \ 00288 return x / promote (y, x); } \ 00289 TMPL inline T operator / (const int& x, const T& y) { \ 00290 return promote (x, y) / y; } 00291 00292 #define ARITH_SCALAR_INT_SUGAR(TMPL,T) \ 00293 TMPL inline T operator + (const T& x, const int& y) { \ 00294 return x + promote_scalar (y, x); } \ 00295 TMPL inline T operator + (const int& x, const T& y) { \ 00296 return promote_scalar (x, y) + y; } \ 00297 TMPL inline T operator - (const T& x, const int& y) { \ 00298 return x - promote_scalar (y, x); } \ 00299 TMPL inline T operator - (const int& x, const T& y) { \ 00300 return promote_scalar (x, y) - y; } \ 00301 TMPL inline T operator * (const T& x, const int& y) { \ 00302 return x * promote_scalar (y, x); } \ 00303 TMPL inline T operator * (const int& x, const T& y) { \ 00304 return promote_scalar (x, y) * y; } \ 00305 TMPL inline T operator / (const T& x, const int& y) { \ 00306 return x / promote_scalar (y, x); } \ 00307 TMPL inline T operator / (const int& x, const T& y) { \ 00308 return promote_scalar (x, y) / y; } 00309 00310 #define ARITH_SCALAR_SUGAR(TMPL,T,C) \ 00311 TMPL inline T operator + (const T& x, const C& y) { return x + T(y); } \ 00312 TMPL inline T operator + (const C& x, const T& y) { return T(x) + y; } \ 00313 TMPL inline T operator - (const T& x, const C& y) { return x - T(y); } \ 00314 TMPL inline T operator - (const C& x, const T& y) { return T(x) - y; } \ 00315 TMPL inline T operator * (const T& x, const C& y) { return x * T(y); } \ 00316 TMPL inline T operator * (const C& x, const T& y) { return T(x) * y; } \ 00317 TMPL inline T operator / (const T& x, const C& y) { return x / T(y); } \ 00318 TMPL inline T operator / (const C& x, const T& y) { return T(x) / y; } 00319 00320 #define SHIFT_INT_SUGAR(TMPL,T) \ 00321 TMPL inline T& operator <<= (T& x, const int& y) { return x= x << y; } \ 00322 TMPL inline T& operator >>= (T& x, const int& y) { return x= x >> y; } \ 00323 TMPL inline T& operator <<= (T& x, const long int& y) { return x= x << y; } \ 00324 TMPL inline T& operator >>= (T& x, const long int& y) { return x= x >> y; } 00325 00326 #define ARITH_SWAP_TIMES_SUGAR(TMPL,T,C) \ 00327 TMPL inline T operator * (const C& x, const T& y) { return y * x; } 00328 00329 template<typename C, typename D> inline C& 00330 operator += (C& x, const D& y) { return x= x+y; } 00331 template<typename C, typename D> inline C& 00332 operator -= (C& x, const D& y) { return x= x-y; } 00333 template<typename C, typename D> inline C& 00334 operator *= (C& x, const D& y) { return x= x*y; } 00335 template<typename C, typename D> inline C& 00336 operator /= (C& x, const D& y) { return x= x/y; } 00337 00338 template<typename C, typename D> inline C 00339 quo (const C& x, const D& y) { // NOTE: by default we divide on the right 00340 if (y == promote (0, y)) return promote (0, x); else return x/y; } 00341 template<typename C, typename D> inline C 00342 rem (const C& x, const D& y) { // NOTE: by default we divide on the right 00343 if (y == promote (0, y)) return x; else return promote (0, x); } 00344 template<typename C> inline C 00345 skew_div (const C& x, const C& y, bool left= false) { 00346 (void) left; return x / y; } 00347 template<typename C> inline C 00348 skew_quo (const C& x, const C& y, bool left= false) { 00349 (void) left; return quo (x, y); } 00350 template<typename C> inline C 00351 skew_rem (const C& x, const C& y, bool left= false) { 00352 (void) left; return rem (x, y); } 00353 00354 /****************************************************************************** 00355 * Shifting 00356 ******************************************************************************/ 00357 00358 template<typename C, typename S> inline C 00359 lshift2 (const C& x, const S& y) { return x << y; } 00360 template<typename C> inline C 00361 lshift2 (const C& x) { return lshift2<C,int> (x, 1); } 00362 template<typename C, typename S> inline void 00363 lshift2_assign (C& x, const S& y) { x <<= y; } 00364 template<typename C, typename S> inline void 00365 lshift2 (C& x, const C& y, const S& z) { x= y << z; } 00366 template<typename C, typename S> inline C 00367 rshift2 (const C& x, const S& y) { return x >> y; } 00368 template<typename C> inline C 00369 rshift2 (const C& x) { return rshift2<C,int> (x, 1); } 00370 template<typename C, typename S> inline void 00371 rshift2_assign (C& x, const S& y) { x >>= y; } 00372 template<typename C, typename S> inline void 00373 rshift2 (C& x, const C& y, const S& z) { x= y >> z; } 00374 00375 template<typename C, typename S> inline C 00376 lshiftz (const C& x, const S& y) { return x << y; } 00377 template<typename C> inline C 00378 lshiftz (const C& x) { return lshiftz<C,int> (x, 1); } 00379 template<typename C, typename S> inline void 00380 lshiftz_assign (C& x, const S& y) { x <<= y; } 00381 template<typename C, typename S> inline void 00382 lshiftz (C& x, const C& y, const S& z) { x= y << z; } 00383 template<typename C, typename S> inline C 00384 rshiftz (const C& x, const S& y) { return lshiftz (x, -y); } 00385 template<typename C> inline C 00386 rshiftz (const C& x) { return rshiftz<C,int> (x, 1); } 00387 template<typename C, typename S> inline void 00388 rshiftz_assign (C& x, const S& y= 1) { lshiftz_assign (x, -y); } 00389 template<typename C, typename S> inline void 00390 rshiftz (C& x, const C& y, const S& z) { lshiftz (x, y, -z); } 00391 00392 template<typename C, typename S> inline C 00393 incexp2 (const C& x, const S& y) { return x << y; } 00394 template<typename C> inline C 00395 incexp2 (const C& x) { return incexp2<C,xint> (x, 1); } 00396 template<typename C, typename S> inline void 00397 incexp2_assign (C& x, const S& y) { x <<= y; } 00398 template<typename C, typename S> inline void 00399 incexp2 (C& x, const C& y, const S& z) { x= y << z; } 00400 template<typename C, typename S> inline C 00401 decexp2 (const C& x, const S& y) { return x >> y; } 00402 template<typename C> inline C 00403 decexp2 (const C& x) { return decexp2<C,xint> (x, 1); } 00404 template<typename C, typename S> inline void 00405 decexp2_assign (C& x, const S& y) { x >>= y; } 00406 template<typename C, typename S> inline void 00407 decexp2 (C& x, const C& y, const S& z) { x= y >> z; } 00408 00409 /****************************************************************************** 00410 * Greatest common divisors and least common multiples 00411 ******************************************************************************/ 00412 00413 template<typename C> 00414 struct xgcd_matrix { 00415 MMX_ALLOCATORS 00416 C a, b, c, d; 00417 // NOTE: the xgcd matrix is an invertible matrix with 00418 // a x + b y = gcd (x, y), c x + d y = 0 and d y = lcm (x, y). 00419 00420 inline xgcd_matrix<C> () {} 00421 inline xgcd_matrix<C> (const C& a2, const C& b2, const C& c2, const C& d2): 00422 a (a2), b (b2), c (c2), d (d2) {} 00423 inline xgcd_matrix<C> (const xgcd_matrix& m): 00424 a (m.a), b (m.b), c (m.c), d (m.d) {} 00425 inline xgcd_matrix<C>& operator = (const xgcd_matrix& m) { 00426 a= m.a; b= m.b; c= m.c; d= m.d; return m; } 00427 }; 00428 00429 #define GCD_SUGAR(TMPL,C) \ 00430 TMPL inline C gcd (const C& x, const C& y) { \ 00431 return (x == promote (0, x) && y == promote (0, x))? \ 00432 promote (0, x): promote (1, x); } \ 00433 TMPL inline C lcm (const C& x, const C& y) { \ 00434 return (x == promote (0, x) || y == promote (0, x))? \ 00435 promote (0, x): x*y; } \ 00436 TMPL inline xgcd_matrix<C> xgcd (const C& x, const C& y) { \ 00437 if (x == 0) { \ 00438 if (y == 0) \ 00439 return xgcd_matrix<C> (promote (1, x), promote (0, x), \ 00440 promote (0, x), promote (1, x)); \ 00441 else \ 00442 return xgcd_matrix<C> (promote (0, x), promote (1, x) / y, \ 00443 promote (1, x), promote (0, x)); \ 00444 } \ 00445 else { \ 00446 if (y == 0) \ 00447 return xgcd_matrix<C> (promote (1, x) / x, promote (0, x), \ 00448 promote (0, x), promote (1, x)); \ 00449 else \ 00450 return xgcd_matrix<C> (promote (1, x) / x, promote (0, x), \ 00451 -y, x); \ 00452 } \ 00453 } 00454 00455 /****************************************************************************** 00456 * Comparisons 00457 ******************************************************************************/ 00458 00459 #ifndef MMX_SIGN_FCT 00460 #define MMX_SIGN_FCT 00461 template<typename C> inline int 00462 sign (const C& x) { 00463 if (x>0) return 1; 00464 if (x<0) return -1; 00465 return 0; 00466 } 00467 00468 template<> inline int 00469 sign (const unsigned char& x) { return (x == 0) ? 0 : 1; } 00470 00471 template<> inline int 00472 sign (const short unsigned int& x) { return (x == 0) ? 0 : 1; } 00473 00474 template<> inline int 00475 sign (const unsigned int& x) { return (x == 0) ? 0 : 1; } 00476 00477 template<> inline int 00478 sign (const long unsigned int& x) { return (x == 0) ? 0 : 1; } 00479 00480 template<> inline int 00481 sign (const long long unsigned int& x) { return (x == 0) ? 0 : 1; } 00482 #endif 00483 00484 template<typename C> inline int 00485 compare (const C& x, const C& y) { 00486 return sign (x-y); 00487 } 00488 00489 #ifndef MMX_ABS_FCT 00490 #define MMX_ABS_FCT 00491 template<typename C> inline C 00492 abs (const C& x) { return x>=0? x: -x; } 00493 00494 template<> inline unsigned char 00495 abs (const unsigned char& x) { return x; } 00496 00497 template<> inline short unsigned int 00498 abs (const short unsigned int& x) { return x; } 00499 00500 template<> inline unsigned int 00501 abs (const unsigned int& x) { return x; } 00502 00503 template<> inline long unsigned int 00504 abs (const long unsigned int& x) { return x; } 00505 00506 template<> inline long long unsigned int 00507 abs (const long long unsigned int& x) { return x; } 00508 #endif 00509 00510 template<typename C> C min (const C& x, const C& y) { return x<y? x: y; } 00511 template<typename C> C max (const C& x, const C& y) { return x>y? x: y; } 00512 template<typename C> C inf (const C& x, const C& y) { return min (x, y); } 00513 template<typename C> C sup (const C& x, const C& y) { return max (x, y); } 00514 00515 #define COMPARE_SUGAR(TMPL,T) \ 00516 TMPL inline bool operator < (const T& x, const T& y) { \ 00517 return compare (x,y) < 0; } \ 00518 TMPL inline bool operator <= (const T& x, const T& y) { \ 00519 return compare (x,y) <= 0; } \ 00520 TMPL inline bool operator > (const T& x, const T& y) { \ 00521 return compare (x,y) > 0; } \ 00522 TMPL inline bool operator >= (const T& x, const T& y) { \ 00523 return compare (x,y) >= 0; } 00524 00525 #define STRICT_COMPARE_SUGAR(TMPL,T) \ 00526 TMPL inline bool operator < (const T& x, const T& y) { \ 00527 return x<=y && !(x==y); } \ 00528 TMPL inline bool operator > (const T& x, const T& y) { \ 00529 return x>=y && !(x==y); } 00530 00531 #define COMPARE_INT_SUGAR(TMPL,T) \ 00532 TMPL inline bool operator < (const T& x, const int& y) { \ 00533 return x < promote (y, x); } \ 00534 TMPL inline bool operator <= (const T& x, const int& y) { \ 00535 return x <= promote (y, x); } \ 00536 TMPL inline bool operator > (const T& x, const int& y) { \ 00537 return x > promote (y, x); } \ 00538 TMPL inline bool operator >= (const T& x, const int& y) { \ 00539 return x >= promote (y, x); } 00540 00541 #define COMPARE_SCALAR_SUGAR(TMPL,T, C) \ 00542 TMPL inline bool operator < (const T& x, const C& y) { return x < T(y); } \ 00543 TMPL inline bool operator <= (const T& x, const C& y) { return x <= T(y); } \ 00544 TMPL inline bool operator > (const T& x, const C& y) { return x > T(y); } \ 00545 TMPL inline bool operator >= (const T& x, const C& y) { return x >= T(y); } 00546 00547 /****************************************************************************** 00548 * Elementary functions defaults 00549 ******************************************************************************/ 00550 00551 template<typename C> inline C 00552 square (const C& x) { 00553 return x * x; 00554 } 00555 00556 template<typename C> inline C 00557 invert (const C& x) { 00558 return promote (1, x) / x; 00559 } 00560 00561 template<typename C> C 00562 binpow (const C& i, const nat& n) { 00563 // FIXME: how to merge with pow? 00564 if (n <= 1) return n==0? promote (1, i): i; 00565 C j= square (binpow (i, n >> 1)); 00566 if ((n&1) == 0) return j; 00567 else return i * j; 00568 } 00569 00570 template<typename C> inline C 00571 hypot (const C& x, const C& y) { 00572 return sqrt (square (x) + square (y)); 00573 } 00574 00575 template<typename C> C atan2 (const C& y, const C& x) { 00576 if (x > promote (0, x)) 00577 return atan (y/x); 00578 else if (y == promote (0, x)) 00579 return x == promote (0, x)? 00580 promote (0, x): promote (-4, x) * atan (promote (1, x)); 00581 else if (x == promote (0, x)) 00582 return promote (2 * sign (y), x) * atan (promote (1, x)); 00583 else 00584 return promote (sign (y), x) * 00585 (promote (4, x) * atan (promote (1, x)) - atan (abs (y/x))); } 00586 00587 template<typename C> inline C cosh (const C& x) { 00588 return (exp (x) + exp (-x)) / promote (2, x); } 00589 template<typename C> inline C sinh (const C& x) { 00590 return (exp (x) - exp (-x)) / promote (2, x); } 00591 template<typename C> inline C tanh (const C& x) { 00592 return (exp (x) - exp (-x)) / (exp (x) + exp (-x)); } 00593 template<typename C> inline C acosh (const C& x) { 00594 return log (x + sqrt (square (x) - promote (1, x))); } 00595 template<typename C> inline C asinh (const C& x) { 00596 return log (x + sqrt (square (x) + promote (1, x))); } 00597 template<typename C> inline C atanh (const C& x) { 00598 return log ((promote (1, x) + x) / (promote (1, x) - x)) / promote (2, x); } 00599 00600 /****************************************************************************** 00601 * Elementary functions sugar 00602 ******************************************************************************/ 00603 00604 #define POOR_MAN_SQRT_SUGAR(TMPL,C) \ 00605 TMPL inline C sqrt (const C& x) { \ 00606 ASSERT (x == (C)(0) || x == (C)(1), "zero or one expected"); return x; } 00607 00608 #define POOR_MAN_ELEMENTARY_SUGAR(TMPL,C) \ 00609 TMPL inline C exp (const C& x) { \ 00610 ASSERT (x == (promote (0, x)), "zero expected"); \ 00611 return promote (1, x); } \ 00612 TMPL inline C log (const C& x) { \ 00613 ASSERT (x == (promote (1, x)), "one expected"); \ 00614 return promote (0, x); } \ 00615 TMPL inline C cos (const C& x) { \ 00616 ASSERT (x == (promote (0, x)), "zero expected"); \ 00617 return promote (1, x); } \ 00618 TMPL inline C sin (const C& x) { \ 00619 ASSERT (x == (promote (0, x)), "zero expected"); \ 00620 return promote (0, x); } \ 00621 TMPL inline C tan (const C& x) { \ 00622 ASSERT (x == (promote (0, x)), "zero expected"); \ 00623 return promote (0, x); } \ 00624 TMPL inline C acos (const C& x) { \ 00625 ASSERT (x == (promote (1, x)), "one expected"); \ 00626 return promote (0, x); } \ 00627 TMPL inline C asin (const C& x) { \ 00628 ASSERT (x == (promote (0, x)), "zero expected"); \ 00629 return promote (0, x); } \ 00630 TMPL inline C atan (const C& x) { \ 00631 ASSERT (x == (promote (0, x)), "zero expected"); \ 00632 return promote (0, x); } 00633 00634 #define HYPOT_SUGAR(TMPL,C) \ 00635 TMPL inline C hypot (const C& x, const C& y) { \ 00636 return sqrt (square (x) + square (y)); } 00637 00638 #define POW_SUGAR(TMPL,C) \ 00639 TMPL inline C pow (const C& x, const C& y) { \ 00640 return exp (y * log (x)); } 00641 00642 #define ATAN2_SUGAR(TMPL,C) \ 00643 TMPL inline C atan2 (const C& y, const C& x) { \ 00644 if (x > promote (0, x)) \ 00645 return atan (y/x); \ 00646 else if (y == promote (0, x)) \ 00647 return x == promote (0, x)? \ 00648 promote (0, x): promote (-4, x) * atan (promote (1, x)); \ 00649 else if (x == promote (0, x)) \ 00650 return promote (2 * sign (y), x) * atan (promote (1, x)); \ 00651 else \ 00652 return promote (sign (y), x) * \ 00653 (promote (4, x) * atan (promote (1, x)) - atan (abs (y/x))); } 00654 00655 #define INV_TRIGO_SUGAR(TMPL,C) \ 00656 TMPL inline C sec (const C& x) { \ 00657 return promote (1, x) / cos (x); } \ 00658 TMPL inline C csc (const C& x) { \ 00659 return promote (1, x) / sin (x); } \ 00660 TMPL inline C cot (const C& x) { \ 00661 return cos (x) / sin (x); } 00662 00663 #define HYPER_SUGAR(TMPL,C) \ 00664 TMPL inline C cosh (const C& x) { \ 00665 return (exp (x) + exp (-x)) / promote (2, x); } \ 00666 TMPL inline C sinh (const C& x) { \ 00667 return (exp (x) - exp (-x)) / promote (2, x); } \ 00668 TMPL inline C tanh (const C& x) { \ 00669 return (exp (x) - exp (-x)) / (exp (x) + exp (-x)); } 00670 00671 #define INV_HYPER_SUGAR(TMPL,C) \ 00672 TMPL inline C sech (const C& x) { \ 00673 return promote (2, x) / (exp (x) + exp (-x)); } \ 00674 TMPL inline C csch (const C& x) { \ 00675 return promote (2, x) / (exp (x) - exp (-x)); } \ 00676 TMPL inline C coth (const C& x) { \ 00677 return (exp (x) + exp (-x)) / (exp (x) - exp (-x)); } 00678 00679 #define ARG_HYPER_SUGAR(TMPL,C) \ 00680 TMPL inline C acosh (const C& x) { \ 00681 return log (x + sqrt (square (x) - promote (1, x))); } \ 00682 TMPL inline C asinh (const C& x) { \ 00683 return log (x + sqrt (square (x) + promote (1, x))); } \ 00684 TMPL inline C atanh (const C& x) { \ 00685 return log ((promote (1, x) + x) / (promote (1, x) - x)) / promote (2, x); } 00686 00687 /****************************************************************************** 00688 * Approximate and reliable arithmetic 00689 ******************************************************************************/ 00690 00691 template<typename C> inline bool is_finite (const C& x) { 00692 (void) x; return true; } 00693 template<typename C> inline bool is_infinite (const C& x) { 00694 (void) x; return false; } 00695 template<typename C> inline bool is_fuzz (const C& x) { 00696 (void) x; return false; } 00697 template<typename C> inline bool is_nan (const C& x) { 00698 (void) x; return false; } 00699 template<typename C> inline bool is_reliable (const C& x) { 00700 (void) x; return true; } 00701 template<typename C> inline double magnitude (const C& x) { 00702 return (double) exponent (x); } 00703 template<typename C> inline C sharpen (const C& x) { 00704 return x; } 00705 template<typename C, typename D> inline C blur (const C& x, const D& y) { 00706 (void) y; return x; } 00707 00708 /****************************************************************************** 00709 * Complex numbers 00710 ******************************************************************************/ 00711 00712 template<typename C> inline C Re (const C& x) { return x; } 00713 template<typename C> inline C Im (const C& x) { return 0; } 00714 template<typename C> inline C conj (const C& x) { return x; } 00715 00716 /****************************************************************************** 00717 * Calculus 00718 ******************************************************************************/ 00719 00720 template<typename T, typename V> T 00721 derive (const T& f, const V& v, nat n) { 00722 if (n == 0) return f; 00723 else return derive (derive (f, v, n-1), v); 00724 } 00725 00726 /****************************************************************************** 00727 * Miscellaneous 00728 ******************************************************************************/ 00729 00730 template<typename C> inline C 00731 common_part (const C& x, const C& y) { 00732 if (x == y) return x; 00733 else return promote (0, x); 00734 } 00735 00736 /****************************************************************************** 00737 * Utilities 00738 ******************************************************************************/ 00739 00740 template<typename C> inline bool 00741 always_false (const C& x) { 00742 (void) x; return false; 00743 } 00744 00745 template<typename C> inline bool 00746 always_true (const C& x) { 00747 (void) x; return true; 00748 } 00749 00750 template<typename C> inline void 00751 swap (C& x, C& y) { 00752 C temp= x; 00753 x= y; 00754 y= temp; 00755 } 00756 00757 template<typename C> inline const C& 00758 read_only (const C& c) { 00759 return c; 00760 } 00761 00762 /****************************************************************************** 00763 * Forward declarations 00764 ******************************************************************************/ 00765 00766 inline void set_maximal (int& x); 00767 inline void set_minimal (int& x); 00768 inline void set_maximal (nat& x); 00769 inline void set_minimal (nat& x); 00770 inline void set_maximal (long int& x); 00771 inline void set_minimal (long int& x); 00772 inline void set_maximal (long unsigned int& x); 00773 inline void set_minimal (long unsigned int& x); 00774 inline void set_nan (double& x); 00775 inline void set_maximal (double& x); 00776 inline void set_minimal (double& x); 00777 inline void set_infinity (double& x); 00778 inline void set_fuzz (double& x); 00779 inline void set_smallest (double& x); 00780 inline void set_largest (double& x); 00781 inline void set_accuracy (double& x); 00782 inline void set_log2 (double& x); 00783 inline void set_pi (double& x); 00784 inline void set_euler (double& x); 00785 inline double times_infinity (const double& x); 00786 00787 inline double square (const double& x); 00788 inline double invert (const double& x); 00789 inline double sqrt (const double& x); 00790 inline double exp (const double& x); 00791 inline double exp2 (const double& x); 00792 inline double log (const double& x); 00793 inline double log2 (const double& x); 00794 inline double cos (const double& x); 00795 inline double sin (const double& x); 00796 inline double tan (const double& x); 00797 inline double cosh (const double& x); 00798 inline double sinh (const double& x); 00799 inline double tanh (const double& x); 00800 inline double acos (const double& x); 00801 inline double asin (const double& x); 00802 inline double atan (const double& x); 00803 inline double hypot (const double& x, const double& y); 00804 inline double atan2 (const double& y, const double& x); 00805 inline double pow (const double& x, const double& y); 00806 inline double pow (const double& x, const int& y); 00807 inline double pow (const int& x, const double& y); 00808 template<typename S> inline double incexp2 (const double& x, const S& y); 00809 inline double incexp2 (const double& x); 00810 template<typename S> inline void incexp2_assign (double& x, const S& y); 00811 template<typename S> inline void incexp2 (double&, const double&, const S&); 00812 template<typename S> inline double decexp2 (const double& x, const S& y); 00813 inline double decexp2 (const double& x); 00814 template<typename S> inline void decexp2_assign (double& x, const S& y); 00815 template<typename S> inline void decexp2 (double&, const double&, const S&); 00816 inline double floor (const double& x); 00817 inline double trunc (const double& x); 00818 inline double ceil (const double& x); 00819 inline double round (const double& x); 00820 00821 } // namespace mmx 00822 #endif // __MMX_DEFAULTS_HPP