00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_BALL_COMPLEX_ROUNDED_HPP
00014 #define __MMX_BALL_COMPLEX_ROUNDED_HPP
00015 #include <numerix/ball.hpp>
00016 #include <numerix/complex.hpp>
00017 namespace mmx {
00018 #define TMPL template<typename C,typename R,typename V>
00019 #define CTMPL template<typename C,typename R,typename V,typename CC,typename CV>
00020 #define Ball ball<C,R,V>
00021 #define CBall ball<CC,R,CV>
00022
00023
00024
00025
00026
00027 template<typename V>
00028 struct ball_complex: public V {};
00029
00030 template<typename F, typename V, typename W>
00031 struct implementation<F,V,ball_complex<W> >:
00032 public implementation<F,V,W> {};
00033
00034 template<typename C>
00035 struct ball_variant_helper<complex<C> > {
00036 typedef Ball_variant(C) BV;
00037 };
00038
00039
00040
00041
00042
00043 struct ball_complex_construct {};
00044
00045 template<typename IV, typename BV>
00046 struct implementation<ball_complex_construct,IV,ball_complex<BV> > {
00047 typedef implementation<ball_rounding,BV> Rnd;
00048
00049 CTMPL static void
00050 gauss (CBall& d, const Ball& re, const Ball& im) {
00051 typedef Round_up(R) Up;
00052 gaussian_as (center (d), center (re), center (im));
00053 radius (d)= Up::hypot (radius (re), radius (im));
00054 Rnd::add_elementary_error (d);
00055 }
00056
00057 CTMPL static void
00058 polar (CBall& d, const Ball& r, const Ball& t) {
00059 gauss (d, r * cos (t), r * sin (t));
00060 }
00061
00062 };
00063
00064
00065
00066
00067
00068 template<typename IV, typename BV>
00069 struct implementation<ball_root,IV,ball_complex<BV> >:
00070 public implementation<ball_root,BV>
00071 {
00072 typedef implementation<ball_rounding,BV> Rnd;
00073
00074 TMPL static void
00075 sqrt (Ball& d, const Ball& z) {
00076 typedef Round_up(R) Up;
00077 typedef Round_down(R) Down;
00078 if (is_zero (z)) d= Fuzz (Ball);
00079 else if (is_infinite (z)) d= Infinity (Ball);
00080 else {
00081 center (d)= sqrt_op::op (center (z));
00082 radius (d)= Up::div (decexp2 (radius (z)), Down::sqrt (abs_down (z)));
00083 Rnd::add_multiplicative_error (d);
00084 }
00085 }
00086
00087 };
00088
00089
00090
00091
00092
00093 template<typename IV, typename BV>
00094 struct implementation<ball_elementary,IV,ball_complex<BV> >:
00095 public implementation<ball_elementary,BV>
00096 {
00097 typedef implementation<ball_rounding,BV> Rnd;
00098
00099 TMPL static void
00100 exp (Ball& d, const Ball& z) {
00101 typedef Round_up(R) Up;
00102 center (d)= exp_op::op (center (z));
00103 radius (d)= Up::mul (Up::exp (bnd_up (Re (z))), radius (z));
00104 Rnd::add_elementary_error (d);
00105 }
00106
00107 TMPL static void
00108 log (Ball& d, const Ball& z) {
00109 typedef Round_up(R) Up;
00110 if (is_zero (z)) d= Nan (Ball);
00111 else {
00112 center (d)= log_op::op (center (z));
00113 radius (d)= Up::div (radius (z), abs_down (z));
00114 Rnd::add_elementary_error (d);
00115 }
00116 }
00117
00118 TMPL static void
00119 cos (Ball& d, const Ball& z) {
00120 typedef Round_up(R) Up;
00121 center (d)= cos_op::op (center (z));
00122 radius (d)= Up::mul (Up::sinh (bnd_up (Im (z))), radius (z));
00123 Rnd::add_elementary_error (d);
00124 }
00125
00126 TMPL static void
00127 sin (Ball& d, const Ball& z) {
00128 typedef Round_up(R) Up;
00129 center (d)= sin_op::op (center (z));
00130 radius (d)= Up::mul (Up::cosh (bnd_up (Im (z))), radius (z));
00131 Rnd::add_elementary_error (d);
00132 }
00133
00134 TMPL static void
00135 tan (Ball& d, const Ball& z) {
00136 d= sin_op::op (z) / cos_op::op (z);
00137 }
00138
00139 TMPL static inline void
00140 cosh (Ball& d, const Ball& z) {
00141 typedef Round_up(R) Up;
00142 center (d)= cosh_op::op (center (z));
00143 radius (d)= Up::mul (Up::sinh (bnd_up (abs (Re (z)))), radius (z));
00144 Rnd::add_elementary_error (d);
00145 }
00146
00147 TMPL static inline void
00148 sinh (Ball& d, const Ball& z) {
00149 typedef Round_up(R) Up;
00150 center (d)= sinh_op::op (center (z));
00151 radius (d)= Up::mul (Up::cosh (bnd_up (abs (Re (z)))), radius (z));
00152 Rnd::add_elementary_error (d);
00153 }
00154
00155 TMPL static void
00156 tanh (Ball& d, const Ball& z) {
00157 d= sinh_op::op (z) / cosh_op::op (z);
00158 }
00159
00160 TMPL static void
00161 acos (Ball& d, const Ball& z) {
00162 d= over_i (acosh_op::op (z));
00163 }
00164
00165 TMPL static void
00166 asin (Ball& d, const Ball& z) {
00167 d= over_i (asinh_op::op (times_i (z)));
00168 }
00169
00170 TMPL static void
00171 atan (Ball& d, const Ball& z) {
00172 d= over_i (atanh_op::op (times_i (z)));
00173 }
00174
00175 };
00176
00177 #undef TMPL
00178 #undef CTMPL
00179 #undef Ball
00180 #undef CBall
00181 }
00182 #endif // __MMX_BALL_COMPLEX_ROUNDED_HPP