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