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