00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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 };
00100
00101
00102
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 };
00198
00199
00200
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 };
00225
00226
00227
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 };
00252
00253 #undef ATMPL
00254 #undef ABall
00255
00256
00257
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 };
00288
00289 #undef TMPL
00290 #undef Ball
00291 }
00292 #endif // __MMX_BALL_INFINITIES_HPP