00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #ifndef __MMX_TWIN_HPP
00014 #define __MMX_TWIN_HPP
00015 #include <basix/operators.hpp>
00016 namespace mmx {
00017 struct std_twin {};
00018 #define TMPL_DEF template<typename C, typename D=generic, typename V=std_twin>
00019 #define TMPL template<typename C, typename D, typename V>
00020 #define Twin twin<C,D,V>
00021 TMPL class twin;
00022 TMPL inline C car (const Twin& x);
00023 TMPL inline D cdr (const Twin& x);
00024 TMPL inline C& car (Twin& x);
00025 TMPL inline D& cdr (Twin& x);
00026 
00027 
00028 
00029 
00030 
00031 TMPL_DEF
00032 class twin {
00033 MMX_ALLOCATORS;
00034 private:
00035   C x1;
00036   D x2;
00037 public:
00038   inline twin (): x1 (0), x2 (0) {}
00039   template<typename T> inline twin (const T& x):
00040     
00041     x1 (as<C> (x)), x2 (as<D> (x)) {}
00042   template<typename T, typename U> inline twin (const T& y1, const U& y2):
00043     
00044     x1 (as<C> (y1)), x2 (as<D> (y2)) {}
00045   inline twin (const int& x):
00046     x1 (x), x2 (x) {}
00047   template<typename T> inline twin (const T& y1, const int& y2):
00048     x1 (as<C> (y1)), x2 (y2) {}
00049   template<typename W> inline twin (const twin<C,V,W>& x):
00050     x1 (car (x)), x2 (cdr (x)) {}
00051   friend C car LESSGTR (const Twin& x);
00052   friend D cdr LESSGTR (const Twin& x);
00053   friend C& car LESSGTR (Twin& x);
00054   friend D& cdr LESSGTR (Twin& x);
00055 };
00056 DEFINE_BINARY_FORMAT_2 (twin)
00057 
00058 template<typename C1, typename D1, typename V1,
00059          typename C2, typename D2, typename V2>
00060 struct as_helper<twin<C1,D1,V1>,twin<C2,D2,V2> > {
00061   static inline twin<C1,D1,V1> cv (const twin<C2,D2,V2>& x) {
00062     return twin<C1,D1,V1> (as<C1> (car (x)), as<D1> (cdr (x))); }
00063 };
00064 
00065 TMPL generic
00066 construct (const Twin& x) {
00067   return construct (as<generic> (x));
00068 }
00069 
00070 TMPL struct rounding_helper<Twin >: public rounding_helper<C> {};
00071 TMPL struct projective_helper<Twin >: public projective_helper<C> {};
00072 
00073 
00074 
00075 
00076 
00077 TMPL inline C car (const Twin& x) { return x.x1; }
00078 TMPL inline D cdr (const Twin& x) { return x.x2; }
00079 TMPL inline C& car (Twin& x) { return x.x1; }
00080 TMPL inline D& cdr (Twin& x) { return x.x2; }
00081 TMPL inline format<C> CF1 (const Twin& z) { return get_format (car (z)); }
00082 TMPL inline format<D> CF2 (const Twin& z) { return get_format (cdr (z)); }
00083 
00084 TMPL inline Twin copy (const Twin& x) {
00085   return Twin (copy (car (x)), copy (cdr (x))); }
00086 TMPL inline Twin duplicate (const Twin& x) {
00087   return Twin (duplicate (car (x)), duplicate (cdr (x))); }
00088 TMPL inline bool is_exact_zero (const Twin& x) {
00089   return is_exact_zero (car (x)); }
00090 
00091 template<typename Op, typename C, typename D, typename V> nat
00092 unary_hash (const Twin& x) {
00093   return Op::op (car (x));
00094 }
00095 
00096 TMPL inline syntactic
00097 flatten (const Twin& x) {
00098   return flatten (cdr (x));
00099 }
00100 
00101 template<typename CS, typename CD, typename DS, typename DD,
00102          typename FunC, typename FunD> twin<CD,DD>
00103 map (const FunC& funC, const FunD& funD,
00104      const twin<CS,DS>& z,
00105      const format<CD>& fmC, const format<DD>& fmD) {
00106   return twin<CD,DD> (funC (car (z)), funD (cdr (z)));
00107 }
00108 
00109 TMPL
00110 struct binary_helper<Twin >: public void_binary_helper<Twin > {
00111   static inline string short_type_name () {
00112     return "Tw" * Short_type_name (C) * Short_type_name (D); }
00113   static inline generic full_type_name () {
00114     return gen ("Twin", Full_type_name (C), Full_type_name (D)); }
00115   static inline generic disassemble (const Twin& z) {
00116     return gen_vec (as<generic> (car (z)), as<generic> (cdr (z))); }
00117   static inline Twin assemble (const generic& v) {
00118     return Twin (as<C> (vector_access (v, 0)),
00119                  as<D> (vector_access (v, 1))); }
00120   static inline void write (const port& out, const Twin& z) {
00121     binary_write<C> (out, car (z));
00122     binary_write<D> (out, cdr (z)); }
00123   static inline Twin read (const port& in) {
00124     C c= binary_read<C> (in);
00125     D d= binary_read<D> (in);
00126     return Twin (c, d); }
00127 };
00128 
00129 
00130 
00131 
00132 
00133 TMPL bool operator == (const Twin& x, const Twin& y) {
00134   return car (x) == car (y); }
00135 TMPL bool operator != (const Twin& x, const Twin& y) {
00136   return car (x) != car (y); }
00137 TMPL bool operator < (const Twin& x, const Twin& y) {
00138   return car (x) < car (y); }
00139 TMPL bool operator <= (const Twin& x, const Twin& y) {
00140   return car (x) <= car (y); }
00141 TMPL bool operator > (const Twin& x, const Twin& y) {
00142   return car (x) > car (y); }
00143 TMPL bool operator >= (const Twin& x, const Twin& y) {
00144   return car (x) >= car (y); }
00145 
00146 EQUAL_INT_SUGAR(TMPL,Twin);
00147 COMPARE_INT_SUGAR(TMPL,Twin);
00148 
00149 TMPL nat hash (const Twin& x) { return hash (car (x)); }
00150 TMPL nat exact_hash (const Twin& x) { return exact_hash (cdr (x)); }
00151 TMPL nat hard_hash (const Twin& x) { return hard_hash (cdr (x)); }
00152 
00153 TMPL bool exact_eq (const Twin& x, const Twin& y) {
00154   return exact_eq (cdr (x), cdr (y)); }
00155 TMPL bool exact_neq (const Twin& x, const Twin& y) {
00156   return exact_neq (cdr (x), cdr (y)); }
00157 TMPL bool hard_eq (const Twin& x, const Twin& y) {
00158   return hard_eq (cdr (x), cdr (y)); }
00159 TMPL bool hard_neq (const Twin& x, const Twin& y) {
00160   return hard_neq (cdr (x), cdr (y)); }
00161 
00162 
00163 
00164 
00165 
00166 TMPL inline void set_default (Twin& z) {
00167   set_default (car (z)); set_default (cdr (z)); }
00168 TMPL inline void set_nan (Twin& z) {
00169   set_nan (car (z)); set_nan (cdr (z)); }
00170 TMPL inline void set_infinity (Twin& z) {
00171   set_infinity (car (z)); set_infinity (cdr (z)); }
00172 TMPL inline void set_fuzz (Twin& z) {
00173   set_fuzz (car (z)); set_fuzz (cdr (z)); }
00174 TMPL inline void set_smallest (Twin& z) {
00175   set_smallest (car (z)); set_smallest (cdr (z)); }
00176 TMPL inline void set_largest (Twin& z) {
00177   set_largest (car (z)); set_largest (cdr (z)); }
00178 TMPL inline void set_accuracy (Twin& z) {
00179   set_accuracy (car (z)); set_accuracy (cdr (z)); }
00180 TMPL inline void set_log2 (Twin& z) {
00181   set_log2 (car (z)); set_log2 (cdr (z)); }
00182 TMPL inline void set_pi (Twin& z) {
00183   set_pi (car (z)); set_pi (cdr (z)); }
00184 TMPL inline void set_euler (Twin& z) {
00185   set_euler (car (z)); set_euler (cdr (z)); }
00186 TMPL inline void set_imaginary (Twin& z) {
00187   set_zero (car (z)); set_imaginary (cdr (z)); }
00188 TMPL inline Twin times_infinity (const Twin& x) {
00189   return x * infinity_cst<Twin > (); }
00190 
00191 
00192 
00193 
00194 
00195 TMPL inline Twin
00196 operator + (const Twin& x1, const Twin& x2) {
00197   return Twin (car (x1) + car (x2), cdr (x1) + cdr (x2));
00198 }
00199 
00200 TMPL inline Twin
00201 operator - (const Twin& x) {
00202   return Twin (-car (x), -cdr (x));
00203 }
00204 
00205 TMPL inline Twin
00206 operator - (const Twin& x1, const Twin& x2) {
00207   return Twin (car (x1) - car (x2), cdr (x1) - cdr (x2));
00208 }
00209 
00210 TMPL inline Twin
00211 operator * (const Twin& x1, const Twin& x2) {
00212   return Twin (car (x1) * car (x2), cdr (x1) * cdr (x2));
00213 }
00214 
00215 TMPL inline Twin
00216 operator / (const Twin& x1, const Twin& x2) {
00217   return Twin (car (x1) / car (x2), cdr (x1) / cdr (x2));
00218 }
00219 
00220 ARITH_INT_SUGAR(TMPL,Twin)
00221 
00222 
00223 
00224 
00225 
00226 TMPL Twin sqrt (const Twin& x) {
00227   return Twin (sqrt (car (x)), sqrt (cdr (x))); }
00228 TMPL Twin exp (const Twin& x) {
00229   return Twin (exp (car (x)), exp (cdr (x))); }
00230 TMPL Twin log (const Twin& x) {
00231   return Twin (log (car (x)), log (cdr (x))); }
00232 TMPL inline Twin pow (const Twin& x1, const Twin& x2) {
00233   return Twin (pow (car (x1), car (x2)), pow (cdr (x1), cdr (x2))); }
00234 TMPL inline Twin pow (const Twin& x1, const int& x2) {
00235   return pow (x1, Twin (x2)); }
00236 TMPL Twin cos (const Twin& x) {
00237   return Twin (cos (car (x)), cos (cdr (x))); }
00238 TMPL Twin sin (const Twin& x) {
00239   return Twin (sin (car (x)), sin (cdr (x))); }
00240 TMPL Twin tan (const Twin& x) {
00241   return Twin (tan (car (x)), tan (cdr (x))); }
00242 TMPL Twin acos (const Twin& x) {
00243   return Twin (acos (car (x)), acos (cdr (x))); }
00244 TMPL Twin asin (const Twin& x) {
00245   return Twin (asin (car (x)), asin (cdr (x))); }
00246 TMPL Twin atan (const Twin& x) {
00247   return Twin (atan (car (x)), atan (cdr (x))); }
00248 TMPL Twin cosh (const Twin& x) {
00249   return Twin (cosh (car (x)), cosh (cdr (x))); }
00250 TMPL Twin sinh (const Twin& x) {
00251   return Twin (sinh (car (x)), sinh (cdr (x))); }
00252 TMPL Twin tanh (const Twin& x) {
00253   return Twin (tanh (car (x)), tanh (cdr (x))); }
00254 TMPL Twin acosh (const Twin& x) {
00255   return Twin (acosh (car (x)), acosh (cdr (x))); }
00256 TMPL Twin asinh (const Twin& x) {
00257   return Twin (asinh (car (x)), asinh (cdr (x))); }
00258 TMPL Twin atanh (const Twin& x) {
00259   return Twin (atanh (car (x)), atanh (cdr (x))); }
00260 TMPL Twin atan2 (const Twin& x, const Twin& y) {
00261   return Twin (atan2 (car (x), car (y)), atan2 (cdr (x), cdr (y))); }
00262 TMPL Twin hypot (const Twin& x, const Twin& y) {
00263   return Twin (hypot (car (x), car (y)), hypot (cdr (x), cdr (y))); }
00264 
00265 
00266 
00267 
00268 
00269 TMPL inline bool is_finite (const Twin& x) {
00270   return is_finite (car (x)); }
00271 TMPL inline bool is_infinite (const Twin& x) {
00272   return is_infinite (car (x)); }
00273 TMPL inline bool is_fuzz (const Twin& x) {
00274   return is_fuzz (car (x)); }
00275 TMPL inline bool is_nan (const Twin& x) {
00276   return is_nan (car (x)); }
00277 TMPL inline bool is_reliable (const Twin& x) {
00278   return is_reliable (car (x)); }
00279 
00280 TMPL inline Twin change_precision (const Twin& x, xnat p) {
00281   return Twin (change_precision (car (x), p), cdr (x)); }
00282 TMPL inline xnat precision (const Twin& x) {
00283   return precision (car (x)); }
00284 
00285 TMPL inline xint exponent (const Twin& x) {
00286   return exponent (car (x)); }
00287 TMPL inline double magnitude (const Twin& x) {
00288   return magnitude (car (x)); }
00289 TMPL inline Twin operator << (const Twin& x, const xint& shift) {
00290   return Twin (incexp2 (car (x), shift), incexp2 (cdr (x), shift)); }
00291 TMPL inline Twin operator >> (const Twin& x, const xint& shift) {
00292   return Twin (decexp2 (car (x), shift), decexp2 (cdr (x), shift)); }
00293 
00294 TMPL inline Twin sharpen (const Twin& z) {
00295   return Twin (sharpen (car (z)), sharpen (cdr (z))); }
00296 template<typename C, typename D, typename V,
00297          typename C2, typename D2, typename V2> inline Twin
00298 blur (const Twin& z, const twin<C2,D2,V2>& r) {
00299   return Twin (blur (car (z), car (r)), blur (cdr (z), cdr (r))); }
00300 
00301 #undef TMPL_DEF
00302 #undef TMPL
00303 #undef Twin
00304 } 
00305 #endif // __MMX_TWIN_HPP