numerix_doc 0.4
|
00001 00002 /****************************************************************************** 00003 * MODULE : ball_infinities.hpp 00004 * DESCRIPTION: Refined error estimates when computing with infinities 00005 * COPYRIGHT : (C) 2006 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_BALL_INFINITIES_HPP 00014 #define __MMX_BALL_INFINITIES_HPP 00015 #include <numerix/ball_rounded.hpp> 00016 namespace mmx { 00017 #define TMPL template<typename C,typename R,typename V> 00018 #define Ball ball<C,R,V> 00019 00020 /****************************************************************************** 00021 * The ball_infinities<V> variant 00022 ******************************************************************************/ 00023 00024 template<typename V> 00025 struct ball_infinities: public V {}; 00026 00027 template<typename F, typename V, typename W> 00028 struct implementation<F,V,ball_infinities<W> >: 00029 public implementation<F,V,W> {}; 00030 00031 template<typename V> 00032 struct ball_variant_helper<floating<V> > { 00033 typedef ball_infinities<ball_rounded> BV; 00034 }; 00035 00036 /****************************************************************************** 00037 * Additive operations 00038 ******************************************************************************/ 00039 00040 template<typename IV, typename BV> 00041 struct implementation<ball_additive,IV,ball_infinities<BV> > { 00042 typedef implementation<ball_additive,BV> Fallback; 00043 typedef implementation<ball_rounding,BV> Rnd; 00044 00045 TMPL static void 00046 neg (Ball& d, const Ball& z) { 00047 if (is_finite (z) || is_infinite (z)) Fallback::neg (d, z); 00048 else d= z; 00049 } 00050 00051 TMPL static void 00052 add (Ball& d, const Ball& z1, const Ball& z2) { 00053 if (is_finite (z1) && is_finite (z2)) Fallback::add (d, z1, z2); 00054 else if (is_nan (z1) || is_nan (z2)) d= Nan (Ball); 00055 else if (is_fuzz (z1) || is_fuzz (z2)) d= Fuzz (Ball); 00056 else if (is_infinite (z1) && is_infinite (z2)) { 00057 if (Projective (C) || center (z1) != center (z2)) d= Fuzz (Ball); 00058 else d= z1; 00059 } 00060 else d= (is_infinite (z1)? z1: z2); 00061 } 00062 00063 TMPL static void 00064 add (Ball& d, const C& z1, const Ball& z2) { 00065 if (is_finite (z1) && is_finite (z2)) Fallback::add (d, z1, z2); 00066 else add (d, Ball (z1), z2); 00067 } 00068 00069 TMPL static void 00070 add (Ball& d, const Ball& z1, const C& z2) { 00071 if (is_finite (z1) && is_finite (z2)) Fallback::add (d, z1, z2); 00072 else add (d, z1, Ball (z2)); 00073 } 00074 00075 TMPL static void 00076 sub (Ball& d, const Ball& z1, const Ball& z2) { 00077 if (is_finite (z1) && is_finite (z2)) Fallback::sub (d, z1, z2); 00078 else if (is_nan (z1) || is_nan (z2)) d= Nan (Ball); 00079 else if (is_fuzz (z1) || is_fuzz (z2)) d= Fuzz (Ball); 00080 else if (is_infinite (z1) && is_infinite (z2)) { 00081 if (Projective (C) || center (z1) == center (z2)) d= Fuzz (Ball); 00082 else d= z1; 00083 } 00084 else d= (is_infinite (z1)? z1: -z2); 00085 } 00086 00087 TMPL static void 00088 sub (Ball& d, const C& z1, const Ball& z2) { 00089 if (is_finite (z1) && is_finite (z2)) Fallback::sub (d, z1, z2); 00090 else sub (d, Ball (z1), z2); 00091 } 00092 00093 TMPL static void 00094 sub (Ball& d, const Ball& z1, const C& z2) { 00095 if (is_finite (z1) && is_finite (z2)) Fallback::sub (d, z1, z2); 00096 else sub (d, z1, Ball (z2)); 00097 } 00098 00099 }; // implementation<ball_additive,IV,ball_infinities<BV> > 00100 00101 /****************************************************************************** 00102 * Multiplicative operations 00103 ******************************************************************************/ 00104 00105 template<typename IV, typename BV> 00106 struct implementation<ball_multiplicative,IV,ball_infinities<BV> > { 00107 typedef implementation<ball_multiplicative,BV> Fallback; 00108 typedef implementation<ball_rounding,BV> Rnd; 00109 00110 TMPL static void 00111 mul (Ball& d, const Ball& z1, const Ball& z2) { 00112 if (is_finite (z1) && is_finite (z2)) Fallback::mul (d, z1, z2); 00113 else if (is_nan (z1) || is_nan (z2)) d= Nan (Ball); 00114 else if (is_fuzz (z1) || is_fuzz (z2)) d= Fuzz (Ball); 00115 else if (is_infinite (z1)) { 00116 if (is_zero (z2)) d= Fuzz (Ball); 00117 else if (Projective (C)) d= Infinity (Ball); 00118 else { 00119 center (d)= center (z1) * center (z2); 00120 radius (d)= 0; 00121 } 00122 } 00123 else { 00124 if (is_zero (z1)) d= Fuzz (Ball); 00125 else if (Projective (C)) d= Infinity (Ball); 00126 else { 00127 center (d)= center (z1) * center (z2); 00128 radius (d)= 0; 00129 } 00130 } 00131 } 00132 00133 TMPL static void 00134 mul (Ball& d, const C& z1, const Ball& z2) { 00135 if (is_finite (z1) && is_finite (z2)) Fallback::mul (d, z1, z2); 00136 else mul (d, Ball (z1), z2); 00137 } 00138 00139 TMPL static void 00140 mul (Ball& d, const Ball& z1, const C& z2) { 00141 if (is_finite (z1) && is_finite (z2)) Fallback::mul (d, z1, z2); 00142 else mul (d, z1, Ball (z2)); 00143 } 00144 00145 TMPL static void 00146 square (Ball& d, const Ball& z) { 00147 if (is_finite (z)) Fallback::square (d, z); 00148 else if (is_infinite (z)) d= Infinity (Ball); 00149 else d= z; 00150 } 00151 00152 TMPL static void 00153 invert (Ball& d, const Ball& z) { 00154 if (is_zero (z)) d= Nan (Ball); 00155 else if (is_finite (z)) Fallback::invert (d, z); 00156 else if (is_nan (z)) d= Nan (Ball); 00157 else d= 0; 00158 } 00159 00160 TMPL static void 00161 invert (Ball& d, const C& z) { 00162 if (is_zero (z)) d= Nan (Ball); 00163 else if (is_finite (z)) Fallback::invert (d, z); 00164 else if (is_nan (z)) d= Nan (Ball); 00165 else d= 0; 00166 } 00167 00168 TMPL static void 00169 div (Ball& d, const Ball& z1, const Ball& z2) { 00170 if (is_zero (z2)) d= Nan (Ball); 00171 else if (is_finite (z1) && is_finite (z2)) Fallback::div (d, z1, z2); 00172 else if (is_nan (z1) || is_nan (z2)) d= Nan (Ball); 00173 else if (is_fuzz (z1)) d= Fuzz (Ball); 00174 else if (is_infinite (z1)) { 00175 if (is_infinite (z2)) d= Fuzz (Ball); 00176 else if (Projective (C)) d= Infinity (Ball); 00177 else { 00178 center (d)= center (z1) / center (z2); 00179 radius (d)= 0; 00180 } 00181 } 00182 else d= 0; 00183 } 00184 00185 TMPL static void 00186 div (Ball& d, const C& z1, const Ball& z2) { 00187 if (is_finite (z1) && is_finite (z2)) Fallback::div (d, z1, z2); 00188 else div (d, Ball (z1), z2); 00189 } 00190 00191 TMPL static void 00192 div (Ball& d, const Ball& z1, const C& z2) { 00193 if (is_finite (z1) && is_finite (z2)) Fallback::div (d, z1, z2); 00194 else div (d, z1, Ball (z2)); 00195 } 00196 00197 }; // implementation<ball_multiplicative,IV,ball_infinities<BV> > 00198 00199 /****************************************************************************** 00200 * Square root related functions 00201 ******************************************************************************/ 00202 00203 template<typename IV, typename BV> 00204 struct implementation<ball_root,IV,ball_infinities<BV> > { 00205 typedef implementation<ball_root,BV> Fallback; 00206 typedef implementation<ball_rounding,BV> Rnd; 00207 00208 TMPL static void 00209 sqrt (Ball& d, const Ball& z) { 00210 if (is_negative_or_zero (z)) d= Nan (Ball); 00211 else if (is_finite (z)) Fallback::sqrt (d, z); 00212 else if (is_infinite (z)) d= Maximal (Ball); 00213 else d= Nan (Ball); 00214 } 00215 00216 TMPL static void 00217 hypot (Ball& d, const Ball& x, const Ball& y) { 00218 if (is_finite (x) && is_finite (y)) Fallback::hypot (d, x, y); 00219 else if (is_nan (x) || is_nan (y)) d= Nan (Ball); 00220 else if (is_fuzz (x) || is_fuzz (y)) d= Fuzz (Ball); 00221 else d= Maximal (Ball); 00222 } 00223 00224 }; // implementation<ball_root,IV,ball_infinities<BV> > 00225 00226 /****************************************************************************** 00227 * Absolute value 00228 ******************************************************************************/ 00229 00230 #define ATMPL template<typename C,typename R,typename V,typename C2,typename V2> 00231 #define ABall ball<C2,R,V2> 00232 00233 template<typename IV, typename BV> 00234 struct implementation<ball_abs,IV,ball_infinities<BV> > { 00235 typedef implementation<ball_abs,BV> Fallback; 00236 typedef implementation<ball_rounding,BV> Rnd; 00237 00238 ATMPL static inline void 00239 abs (ABall& d, const Ball& z) { 00240 if (is_finite (z)) Fallback::abs (d, z); 00241 else if (is_infinite (z)) d= Infinity (ABall); 00242 else if (is_fuzz (z)) d= Fuzz (ABall); 00243 else d= Nan (ABall); 00244 } 00245 00246 TMPL static inline void 00247 abs (Ball& d, const Ball& z) { 00248 Fallback::abs (d, z); 00249 } 00250 00251 }; // implementation<ball_abs,IV,ball_infinities<BV> > 00252 00253 #undef ATMPL 00254 #undef ABall 00255 00256 /****************************************************************************** 00257 * Shift operations 00258 ******************************************************************************/ 00259 00260 template<typename IV, typename BV> 00261 struct implementation<ball_shift,IV,ball_infinities<BV> > { 00262 typedef implementation<ball_shift,BV> Fallback; 00263 typedef implementation<ball_rounding,BV> Rnd; 00264 00265 TMPL static inline void 00266 shiftl (Ball& d, const xint& shift) { 00267 if (is_finite (d)) Fallback::shiftl (d, shift); 00268 } 00269 00270 TMPL static inline void 00271 shiftl (Ball& d, const Ball& z, const xint& shift) { 00272 if (is_finite (z)) Fallback::shiftl (d, z, shift); 00273 else d= z; 00274 } 00275 00276 TMPL static inline void 00277 shiftr (Ball& d, const xint& shift) { 00278 if (is_finite (d)) Fallback::shiftr (d, shift); 00279 } 00280 00281 TMPL static inline void 00282 shiftr (Ball& d, const Ball& z, const xint& shift) { 00283 if (is_finite (z)) Fallback::shiftr (d, z, shift); 00284 else d= z; 00285 } 00286 00287 }; // implementation<ball_shift,IV,ball_infinities<BV> > 00288 00289 #undef TMPL 00290 #undef Ball 00291 } // namespace mmx 00292 #endif // __MMX_BALL_INFINITIES_HPP