numerix_doc 0.4
|
00001 00002 /****************************************************************************** 00003 * MODULE : twin.hpp 00004 * DESCRIPTION: Twin numbers 00005 * COPYRIGHT : (C) 2007 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_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 * The twin type 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 //x1 (x), x2 (x) {} 00041 x1 (as<C> (x)), x2 (as<D> (x)) {} 00042 template<typename T, typename U> inline twin (const T& y1, const U& y2): 00043 // x1 (y1), x2 (y2) {} 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 * Basic routines 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> twin<CD,DD> 00102 map (const function_1<CD,Argument(CS) >& funC, 00103 const function_1<DD,Argument(DS) >& funD, 00104 const twin<CS,DS>& z, 00105 const format<CD>& fmC, 00106 const format<DD>& fmD) { 00107 return twin<CD,DD> (funC (car (z)), funD (cdr (z))); 00108 } 00109 00110 TMPL 00111 struct binary_helper<Twin >: public void_binary_helper<Twin > { 00112 static inline string short_type_name () { 00113 return "Tw" * Short_type_name (C) * Short_type_name (D); } 00114 static inline generic full_type_name () { 00115 return gen ("Twin", Full_type_name (C), Full_type_name (D)); } 00116 static inline generic disassemble (const Twin& z) { 00117 return gen_vec (as<generic> (car (z)), as<generic> (cdr (z))); } 00118 static inline Twin assemble (const generic& v) { 00119 return Twin (as<C> (vector_access (v, 0)), 00120 as<D> (vector_access (v, 1))); } 00121 static inline void write (const port& out, const Twin& z) { 00122 binary_write<C> (out, car (z)); 00123 binary_write<D> (out, cdr (z)); } 00124 static inline Twin read (const port& in) { 00125 C c= binary_read<C> (in); 00126 D d= binary_read<D> (in); 00127 return Twin (c, d); } 00128 }; 00129 00130 /****************************************************************************** 00131 * Equality and ordering relations 00132 ******************************************************************************/ 00133 00134 TMPL bool operator == (const Twin& x, const Twin& y) { 00135 return car (x) == car (y); } 00136 TMPL bool operator != (const Twin& x, const Twin& y) { 00137 return car (x) != car (y); } 00138 TMPL bool operator < (const Twin& x, const Twin& y) { 00139 return car (x) < car (y); } 00140 TMPL bool operator <= (const Twin& x, const Twin& y) { 00141 return car (x) <= car (y); } 00142 TMPL bool operator > (const Twin& x, const Twin& y) { 00143 return car (x) > car (y); } 00144 TMPL bool operator >= (const Twin& x, const Twin& y) { 00145 return car (x) >= car (y); } 00146 00147 EQUAL_INT_SUGAR(TMPL,Twin); 00148 COMPARE_INT_SUGAR(TMPL,Twin); 00149 00150 TMPL nat hash (const Twin& x) { return hash (car (x)); } 00151 TMPL nat exact_hash (const Twin& x) { return exact_hash (cdr (x)); } 00152 TMPL nat hard_hash (const Twin& x) { return hard_hash (cdr (x)); } 00153 00154 TMPL bool exact_eq (const Twin& x, const Twin& y) { 00155 return exact_eq (cdr (x), cdr (y)); } 00156 TMPL bool exact_neq (const Twin& x, const Twin& y) { 00157 return exact_neq (cdr (x), cdr (y)); } 00158 TMPL bool hard_eq (const Twin& x, const Twin& y) { 00159 return hard_eq (cdr (x), cdr (y)); } 00160 TMPL bool hard_neq (const Twin& x, const Twin& y) { 00161 return hard_neq (cdr (x), cdr (y)); } 00162 00163 /****************************************************************************** 00164 * Constants 00165 ******************************************************************************/ 00166 00167 TMPL inline void set_nan (Twin& z) { 00168 set_nan (car (z)); set_nan (cdr (z)); } 00169 TMPL inline void set_infinity (Twin& z) { 00170 set_infinity (car (z)); set_infinity (cdr (z)); } 00171 TMPL inline void set_fuzz (Twin& z) { 00172 set_fuzz (car (z)); set_fuzz (cdr (z)); } 00173 TMPL inline void set_smallest (Twin& z) { 00174 set_smallest (car (z)); set_smallest (cdr (z)); } 00175 TMPL inline void set_largest (Twin& z) { 00176 set_largest (car (z)); set_largest (cdr (z)); } 00177 TMPL inline void set_accuracy (Twin& z) { 00178 set_accuracy (car (z)); set_accuracy (cdr (z)); } 00179 TMPL inline void set_log2 (Twin& z) { 00180 set_log2 (car (z)); set_log2 (cdr (z)); } 00181 TMPL inline void set_pi (Twin& z) { 00182 set_pi (car (z)); set_pi (cdr (z)); } 00183 TMPL inline void set_euler (Twin& z) { 00184 set_euler (car (z)); set_euler (cdr (z)); } 00185 TMPL inline void set_imaginary (Twin& z) { 00186 set_zero (car (z)); set_imaginary (cdr (z)); } 00187 TMPL inline Twin times_infinity (const Twin& x) { 00188 return x * infinity_cst<Twin > (); } 00189 00190 /****************************************************************************** 00191 * Basic arithmetic 00192 ******************************************************************************/ 00193 00194 TMPL inline Twin 00195 operator + (const Twin& x1, const Twin& x2) { 00196 return Twin (car (x1) + car (x2), cdr (x1) + cdr (x2)); 00197 } 00198 00199 TMPL inline Twin 00200 operator - (const Twin& x) { 00201 return Twin (-car (x), -cdr (x)); 00202 } 00203 00204 TMPL inline Twin 00205 operator - (const Twin& x1, const Twin& x2) { 00206 return Twin (car (x1) - car (x2), cdr (x1) - cdr (x2)); 00207 } 00208 00209 TMPL inline Twin 00210 operator * (const Twin& x1, const Twin& x2) { 00211 return Twin (car (x1) * car (x2), cdr (x1) * cdr (x2)); 00212 } 00213 00214 TMPL inline Twin 00215 operator / (const Twin& x1, const Twin& x2) { 00216 return Twin (car (x1) / car (x2), cdr (x1) / cdr (x2)); 00217 } 00218 00219 ARITH_INT_SUGAR(TMPL,Twin) 00220 00221 /****************************************************************************** 00222 * Elementary functions 00223 ******************************************************************************/ 00224 00225 TMPL Twin sqrt (const Twin& x) { 00226 return Twin (sqrt (car (x)), sqrt (cdr (x))); } 00227 TMPL Twin exp (const Twin& x) { 00228 return Twin (exp (car (x)), exp (cdr (x))); } 00229 TMPL Twin log (const Twin& x) { 00230 return Twin (log (car (x)), log (cdr (x))); } 00231 TMPL inline Twin pow (const Twin& x1, const Twin& x2) { 00232 return Twin (pow (car (x1), car (x2)), pow (cdr (x1), cdr (x2))); } 00233 TMPL inline Twin pow (const Twin& x1, const int& x2) { 00234 return pow (x1, Twin (x2)); } 00235 TMPL Twin cos (const Twin& x) { 00236 return Twin (cos (car (x)), cos (cdr (x))); } 00237 TMPL Twin sin (const Twin& x) { 00238 return Twin (sin (car (x)), sin (cdr (x))); } 00239 TMPL Twin tan (const Twin& x) { 00240 return Twin (tan (car (x)), tan (cdr (x))); } 00241 TMPL Twin acos (const Twin& x) { 00242 return Twin (acos (car (x)), acos (cdr (x))); } 00243 TMPL Twin asin (const Twin& x) { 00244 return Twin (asin (car (x)), asin (cdr (x))); } 00245 TMPL Twin atan (const Twin& x) { 00246 return Twin (atan (car (x)), atan (cdr (x))); } 00247 TMPL Twin cosh (const Twin& x) { 00248 return Twin (cosh (car (x)), cosh (cdr (x))); } 00249 TMPL Twin sinh (const Twin& x) { 00250 return Twin (sinh (car (x)), sinh (cdr (x))); } 00251 TMPL Twin tanh (const Twin& x) { 00252 return Twin (tanh (car (x)), tanh (cdr (x))); } 00253 TMPL Twin acosh (const Twin& x) { 00254 return Twin (acosh (car (x)), acosh (cdr (x))); } 00255 TMPL Twin asinh (const Twin& x) { 00256 return Twin (asinh (car (x)), asinh (cdr (x))); } 00257 TMPL Twin atanh (const Twin& x) { 00258 return Twin (atanh (car (x)), atanh (cdr (x))); } 00259 TMPL Twin atan2 (const Twin& x, const Twin& y) { 00260 return Twin (atan2 (car (x), car (y)), atan2 (cdr (x), cdr (y))); } 00261 TMPL Twin hypot (const Twin& x, const Twin& y) { 00262 return Twin (hypot (car (x), car (y)), hypot (cdr (x), cdr (y))); } 00263 00264 /****************************************************************************** 00265 * Floating point related functions 00266 ******************************************************************************/ 00267 00268 TMPL inline bool is_finite (const Twin& x) { 00269 return is_finite (car (x)); } 00270 TMPL inline bool is_infinite (const Twin& x) { 00271 return is_infinite (car (x)); } 00272 TMPL inline bool is_fuzz (const Twin& x) { 00273 return is_fuzz (car (x)); } 00274 TMPL inline bool is_nan (const Twin& x) { 00275 return is_nan (car (x)); } 00276 TMPL inline bool is_reliable (const Twin& x) { 00277 return is_reliable (car (x)); } 00278 00279 TMPL inline Twin change_precision (const Twin& x, xnat p) { 00280 return Twin (change_precision (car (x), p), cdr (x)); } 00281 TMPL inline xnat precision (const Twin& x) { 00282 return precision (car (x)); } 00283 00284 TMPL inline xint exponent (const Twin& x) { 00285 return exponent (car (x)); } 00286 TMPL inline double magnitude (const Twin& x) { 00287 return magnitude (car (x)); } 00288 TMPL inline Twin operator << (const Twin& x, const xint& shift) { 00289 return Twin (incexp2 (car (x), shift), incexp2 (cdr (x), shift)); } 00290 TMPL inline Twin operator >> (const Twin& x, const xint& shift) { 00291 return Twin (decexp2 (car (x), shift), decexp2 (cdr (x), shift)); } 00292 00293 TMPL inline Twin sharpen (const Twin& z) { 00294 return Twin (sharpen (car (z)), sharpen (cdr (z))); } 00295 template<typename C, typename D, typename V, 00296 typename C2, typename D2, typename V2> inline Twin 00297 blur (const Twin& z, const twin<C2,D2,V2>& r) { 00298 return Twin (blur (car (z), car (r)), blur (cdr (z), cdr (r))); } 00299 00300 #undef TMPL_DEF 00301 #undef TMPL 00302 #undef Twin 00303 } // namespace mmx 00304 #endif // __MMX_TWIN_HPP