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