basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/defaults.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines