numerix_doc 0.4
/Users/mourrain/Devel/mmx/numerix/include/numerix/ball_infinities.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines