numerix_doc 0.4
|
00001 00002 /****************************************************************************** 00003 * MODULE : complex.hpp 00004 * DESCRIPTION: Complexified numbers 00005 * COPYRIGHT : (C) 2005 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_COMPLEX_HPP 00014 #define __MMX_COMPLEX_HPP 00015 #include <basix/double.hpp> 00016 #include <basix/function.hpp> 00017 #include <numerix/floating.hpp> 00018 #include <numerix/rounded.hpp> 00019 namespace mmx { 00020 #define TMPL_DEF template<typename C> 00021 #define TMPL template<typename C> 00022 #define Complex complex<C> 00023 TMPL class complex; 00024 TMPL inline C Re (const Complex& z); 00025 TMPL inline C Im (const Complex& z); 00026 TMPL inline C& Re (Complex& z); 00027 TMPL inline C& Im (Complex& z); 00028 00029 /****************************************************************************** 00030 * The complex type 00031 ******************************************************************************/ 00032 00033 TMPL_DEF 00034 class complex { 00035 MMX_ALLOCATORS; 00036 private: 00037 C re; 00038 C im; 00039 public: 00040 inline complex () {} 00041 inline complex (const format<C>& fm): 00042 re (get_sample (fm)), im (get_sample (fm)) {} 00043 template<typename T> inline complex (const T& x): 00044 re (as<C> (x)), im (0) {} 00045 template<typename T> inline complex (const complex<T>& z): 00046 re (Re (z)), im (Im (z)) {} 00047 template<typename XT,typename YT> inline 00048 complex (const XT& x, const YT& y): 00049 re (x), im (y) {} 00050 friend C Re LESSGTR (const Complex& z); 00051 friend C Im LESSGTR (const Complex& z); 00052 friend C& Re LESSGTR (Complex& z); 00053 friend C& Im LESSGTR (Complex& z); 00054 00055 inline Complex& operator += (const Complex& z); 00056 inline Complex& operator -= (const Complex& z); 00057 inline Complex& operator *= (const C& x); 00058 inline Complex& operator /= (const C& x); 00059 inline Complex& operator *= (const Complex& z); 00060 inline Complex& operator /= (const Complex& z); 00061 inline Complex& operator <<= (const xint& shift); 00062 inline Complex& operator >>= (const xint& shift); 00063 }; 00064 DEFINE_UNARY_FORMAT_1 (complex) 00065 00066 STYPE_TO_TYPE(TMPL,scalar_type,Complex,C); 00067 UNARY_RETURN_TYPE(TMPL,Re_op,Complex,C); 00068 UNARY_RETURN_TYPE(TMPL,abs_op,Complex,C); 00069 UNARY_RETURN_TYPE(TMPL,center_op,Complex,complex<Center_type(C) >); 00070 UNARY_RETURN_TYPE(TMPL,radius_op,Complex,Radius_type(C)); 00071 STYPE_TO_TYPE(TMPL,default_radius_type,Complex,Default_radius_type(C)); 00072 TMPL struct rounding_helper<Complex >: public rounding_helper<C> {}; 00073 TMPL struct projective_helper<Complex > { static const bool val= true; }; 00074 00075 TMPL 00076 struct fast_helper<Complex > { 00077 typedef complex<Fast_type(C) > fast_type; 00078 static inline fast_type dd (const Complex& z) { 00079 return complex<Fast_type (C) > (fast (Re (z)), fast (Im (z))); } 00080 static inline Complex uu (const fast_type& z) { 00081 return complex<C> (slow<C> (Re (z)), slow<C> (Im (z))); } 00082 }; 00083 00084 template<typename T,typename F> 00085 struct as_helper<complex<T>,complex<F> > { 00086 static inline complex<T> cv (const complex<F>& z) { 00087 return complex<T> (as<T> (Re (z)), as<T> (Im (z))); } 00088 }; 00089 00090 template<typename T, typename F> inline void 00091 set_as (complex<T>& r, const complex<F>& z) { 00092 set_as (Re(r), Re(z)); 00093 set_as (Im(r), Im(z)); 00094 } 00095 00096 template<typename T, typename F> inline void 00097 set_as (complex<T>& r, const F& x) { 00098 set_as (Re(r), x); 00099 set_as (Im(r), 0); 00100 } 00101 00102 /****************************************************************************** 00103 * Basic routines 00104 ******************************************************************************/ 00105 00106 TMPL inline C Re (const Complex& z) { return z.re; } 00107 TMPL inline C Im (const Complex& z) { return z.im; } 00108 TMPL inline C& Re (Complex& z) { return z.re; } 00109 TMPL inline C& Im (Complex& z) { return z.im; } 00110 TMPL inline format<C> CF (const Complex& z) { return get_format (Re(z)); } 00111 00112 TMPL inline Complex copy (const Complex& z) { 00113 return Complex (copy (Re (z)), copy (Im (z))); } 00114 TMPL inline Complex duplicate (const Complex& z) { 00115 return Complex (duplicate (Re (z)), duplicate (Im (z))); } 00116 TMPL inline bool is_exact_zero (const Complex& z) { 00117 return is_exact_zero (Re (z)) && is_exact_zero (Im (z)); } 00118 00119 template<typename Op, typename C> inline nat 00120 unary_hash (const Complex& z) { 00121 nat h= Op::op (Re (z)); 00122 return (h<<1) ^ (h<<5) ^ (h>>29) ^ Op::op (Im (z)); 00123 } 00124 00125 template<typename Op, typename C> bool 00126 binary_test (const Complex& z1, const Complex& z2) { 00127 return Op::op (Re (z1), Re (z2)) && Op::op (Im (z1), Im (z2)); 00128 } 00129 00130 template<typename S1, typename D> complex<D> 00131 map (const function_1<D,Argument(S1) >& fun, const complex<S1>& z) { 00132 return complex<D> (fun (Re (z)), fun (Im (z))); 00133 } 00134 00135 template<typename S1, typename D> complex<D> 00136 map (D (*fun) (const S1&), const complex<S1>& z) { 00137 return complex<D> (fun (Re (z)), fun (Im (z))); 00138 } 00139 00140 TRUE_IDENTITY_OP_SUGAR(TMPL,Complex) 00141 EXACT_IDENTITY_OP_SUGAR(TMPL,Complex) 00142 HARD_IDENTITY_OP_SUGAR(TMPL,Complex) 00143 EQUAL_INT_SUGAR(TMPL,Complex); 00144 00145 TMPL syntactic 00146 flatten (const Complex& z) { 00147 if (is_nan (z)) return Nan (syntactic); 00148 if (is_fuzz (z)) return Fuzz (syntactic); 00149 if (is_infinite (z)) return Infinity (syntactic); 00150 if (is_exact_zero (z)) return 0; 00151 if (Re (z) != 0 && Im (z) == 0) 00152 return flatten (Re (z)); 00153 if (Re (z) == 0 && Im (z) != 0) 00154 return flatten (Im (z)) * Imaginary (syntactic); 00155 return flatten (Re (z)) + flatten (Im (z)) * Imaginary (syntactic); 00156 } 00157 00158 TMPL syntactic 00159 flatten (const Complex& z, xnat dd) { 00160 if (is_nan (z)) return Nan (syntactic); 00161 if (is_fuzz (z)) return Fuzz (syntactic); 00162 if (is_infinite (z)) return Infinity (syntactic); 00163 if (is_exact_zero (z)) return 0; 00164 if (Re (z) != 0 && Im (z) == 0) 00165 return flatten (Re (z), dd); 00166 if (Re (z) == 0 && Im (z) != 0) 00167 return flatten (Im (z), dd) * Imaginary (syntactic); 00168 return flatten (Re (z), dd) + flatten (Im (z), dd) * Imaginary (syntactic); 00169 } 00170 00171 TMPL 00172 struct binary_helper<Complex >: public void_binary_helper<Complex > { 00173 static inline string short_type_name () { 00174 return "Cc" * Short_type_name (C); } 00175 static inline generic full_type_name () { 00176 return gen ("Complex", Full_type_name (C)); } 00177 static inline generic disassemble (const Complex& z) { 00178 return gen_vec (as<generic> (Re (z)), as<generic> (Im (z))); } 00179 static inline Complex assemble (const generic& v) { 00180 return Complex (as<C> (vector_access (v, 0)), 00181 as<C> (vector_access (v, 1))); } 00182 static inline void write (const port& out, const Complex& z) { 00183 binary_write<C> (out, Re (z)); 00184 binary_write<C> (out, Im (z)); } 00185 static inline Complex read (const port& in) { 00186 C r= binary_read<C> (in); 00187 C i= binary_read<C> (in); 00188 return Complex (r, i); } 00189 }; 00190 00191 /****************************************************************************** 00192 * Polar coordinates and complex conjugation 00193 ******************************************************************************/ 00194 00195 TMPL inline Complex 00196 gaussian (const C& re, const C& im= 0) { 00197 return Complex (re, im); 00198 } 00199 00200 template<typename C, typename R> inline void 00201 gaussian_as (C& z, const R& x, const R& y) { 00202 z= gaussian (x, y); 00203 } 00204 00205 TMPL inline Complex 00206 polar (const C& r, const C& t) { 00207 return Complex (r * cos (t), r * sin (t)); 00208 } 00209 00210 TMPL inline C 00211 abs (const Complex& z) { 00212 return hypot (Re (z), Im (z)); 00213 } 00214 00215 TMPL inline C 00216 arg (const Complex& z) { 00217 return atan2 (Im (z), Re (z)); 00218 } 00219 00220 TMPL inline C 00221 norm (const Complex& z) { 00222 return square (Re (z)) + square (Im (z)); 00223 } 00224 00225 TMPL inline Complex 00226 conj (const Complex& z) { 00227 return Complex (Re (z), -Im (z)); 00228 } 00229 00230 TMPL inline Complex 00231 times_i (const Complex& z) { 00232 return Complex (-Im (z), Re (z)); 00233 } 00234 00235 TMPL inline Complex 00236 over_i (const Complex& z) { 00237 return Complex (Im (z), -Re (z)); 00238 } 00239 00240 /****************************************************************************** 00241 * Constants 00242 ******************************************************************************/ 00243 00244 TMPL inline void set_nan (Complex& z) { 00245 set_nan (Re (z)); set_nan (Im (z)); } 00246 TMPL inline void set_infinity (Complex& z) { 00247 set_infinity (Re (z)); set_infinity (Im (z)); } 00248 TMPL inline void set_fuzz (Complex& z) { 00249 set_fuzz (Re (z)); set_fuzz (Im (z)); } 00250 TMPL inline void set_smallest (Complex& z) { 00251 set_smallest (Re (z)); set_zero (Im (z)); } 00252 TMPL inline void set_largest (Complex& z) { 00253 set_largest (Re (z)); set_zero (Im (z)); } 00254 TMPL inline void set_accuracy (Complex& z) { 00255 set_accuracy (Re (z)); set_zero (Im (z)); } 00256 TMPL inline void set_log2 (Complex& z) { 00257 set_log2 (Re (z)); set_zero (Im (z)); } 00258 TMPL inline void set_pi (Complex& z) { 00259 set_pi (Re (z)); set_zero (Im (z)); } 00260 TMPL inline void set_euler (Complex& z) { 00261 set_euler (Re (z)); set_zero (Im (z)); } 00262 TMPL inline void set_imaginary (Complex& z) { 00263 set_zero (Re (z)); set_one (Im (z)); } 00264 TMPL inline Complex times_infinity (const Complex& z) { 00265 return z * infinity_cst<Complex > (); } 00266 00267 /****************************************************************************** 00268 * Basic arithmetic 00269 ******************************************************************************/ 00270 00271 TMPL inline Complex 00272 operator + (const Complex& z1, const Complex& z2) { 00273 return Complex (Re (z1) + Re (z2), Im (z1) + Im (z2)); 00274 } 00275 00276 TMPL inline Complex 00277 operator + (const Complex& z1, const C& z2) { 00278 return Complex (Re (z1) + z2, Im (z1)); 00279 } 00280 00281 TMPL inline Complex 00282 operator + (const C& z1, const Complex& z2) { 00283 return Complex (z1 + Re (z2), Im (z2)); 00284 } 00285 00286 TMPL inline Complex 00287 operator - (const Complex& z) { 00288 return Complex (-Re (z), -Im (z)); 00289 } 00290 00291 TMPL inline Complex 00292 operator - (const Complex& z1, const Complex& z2) { 00293 return Complex (Re (z1) - Re (z2), Im (z1) - Im (z2)); 00294 } 00295 00296 TMPL inline Complex 00297 operator - (const Complex& z1, const C& z2) { 00298 return Complex (Re (z1) - z2, Im (z1)); 00299 } 00300 00301 TMPL inline Complex 00302 operator - (const C& z1, const Complex& z2) { 00303 return Complex (z1 - Re (z2), -Im (z2)); 00304 } 00305 00306 TMPL inline Complex 00307 operator * (const C& x, const Complex& z) { 00308 return Complex (x * Re (z), x * Im (z)); 00309 } 00310 00311 TMPL inline Complex 00312 operator * (const Complex& z, const C& x) { 00313 return Complex (Re (z) * x, Im (z) * x); 00314 } 00315 00316 TMPL inline Complex 00317 operator * (const Complex& z1, const Complex& z2) { 00318 return Complex (Re (z1) * Re (z2) - Im (z1) * Im (z2), 00319 Re (z1) * Im (z2) + Im (z1) * Re (z2)); 00320 } 00321 00322 TMPL inline Complex 00323 square (const Complex& z) { 00324 C h= Re (z) * Im (z); 00325 return Complex (square (Re (z)) - square (Im (z)), h + h); 00326 } 00327 00328 TMPL inline Complex 00329 invert (const Complex& z) { 00330 C a= norm (z); 00331 return Complex (Re (z) / a, -Im (z) / a); 00332 } 00333 00334 TMPL inline Complex 00335 operator / (const Complex& z, const C& x) { 00336 return Complex (Re (z) / x, Im (z) / x); 00337 } 00338 00339 TMPL inline Complex 00340 operator / (const C& x, const Complex& z) { 00341 C a= x / norm (z); 00342 return Complex (a * Re (z), -a * Im (z)); 00343 } 00344 00345 TMPL inline Complex 00346 operator / (const Complex& z1, const Complex& z2) { 00347 C a= norm (z2); 00348 return Complex ((Re (z1) * Re (z2) + Im (z1) * Im (z2)) / a, 00349 (Im (z1) * Re (z2) - Re (z1) * Im (z2)) / a); 00350 } 00351 00352 ARITH_SCALAR_INT_SUGAR(TMPL,Complex); 00353 GCD_SUGAR(TMPL,Complex); 00354 00355 /****************************************************************************** 00356 * In place arithmetic operations 00357 ******************************************************************************/ 00358 00359 TMPL inline Complex& 00360 Complex::operator += (const Complex& z) { 00361 re += z.re; 00362 im += z.im; 00363 return *this; 00364 } 00365 00366 TMPL inline Complex& 00367 Complex::operator -= (const Complex& z) { 00368 re -= z.re; 00369 im -= z.im; 00370 return *this; 00371 } 00372 00373 TMPL inline Complex& 00374 Complex::operator *= (const C& x) { 00375 re *= x; 00376 im *= x; 00377 return *this; 00378 } 00379 00380 TMPL inline Complex& 00381 Complex::operator /= (const C& x) { 00382 re /= x; 00383 im /= x; 00384 return *this; 00385 } 00386 00387 TMPL inline Complex& 00388 Complex::operator *= (const Complex& z) { 00389 C RE= re, zRE= z.re; 00390 re= re * z.re - im * z.im; 00391 im= RE * z.im + im * zRE; 00392 return *this; 00393 } 00394 00395 TMPL inline Complex& 00396 Complex::operator /= (const Complex& z) { 00397 C RE= re; 00398 C a = norm (z); 00399 re= (re * z.re + im * z.im) / a; 00400 im= (im * z.re - RE * z.im) / a; 00401 return *this; 00402 } 00403 00404 TMPL inline void 00405 neg (Complex& r) { 00406 neg (Re (r)); 00407 neg (Im (r)); 00408 } 00409 00410 TMPL inline void 00411 neg (Complex& r, const Complex& z1) { 00412 neg (Re (r), Re (z1)); 00413 neg (Im (r), Im (z1)); 00414 } 00415 00416 TMPL inline void 00417 add (Complex& r, const Complex& z1, const Complex& z2) { 00418 add (Re (r), Re (z1), Re (z2)); 00419 add (Im (r), Im (z1), Im (z2)); 00420 } 00421 00422 TMPL inline void 00423 sub (Complex& r, const Complex& z1, const Complex& z2) { 00424 sub (Re (r), Re (z1), Re (z2)); 00425 sub (Im (r), Im (z1), Im (z2)); 00426 } 00427 00428 TMPL inline void 00429 mul (Complex& r, const C& c, const Complex& z) { 00430 mul (Re (r), c, Re (z)); 00431 mul (Im (r), c, Im (z)); 00432 } 00433 00434 TMPL inline void 00435 mul (Complex& r, const Complex& z, const C& c) { 00436 mul (Re (r), Re (z), c); 00437 mul (Im (r), Im (z), c); 00438 } 00439 00440 TMPL inline void 00441 div (Complex& r, const Complex& z, const C& c) { 00442 div (Re (r), Re (z), c); 00443 div (Im (r), Im (z), c); 00444 } 00445 00446 /****************************************************************************** 00447 * Exponentiation and logarithms 00448 ******************************************************************************/ 00449 00450 TMPL Complex 00451 sqrt (const Complex& z) { 00452 C a= hypot (Re (z), Im (z)); 00453 if (Re (z) > 0) { 00454 C r= sqrt ((a + Re (z)) / promote (2, a)); 00455 return Complex (r, (Im (z) / r) / promote (2, a)); 00456 } 00457 else if (a == 0) return promote (0, z); 00458 else { 00459 C i = sqrt ((a - Re (z)) / promote (2, a)); 00460 if (Im (z) < 0) i= -i; 00461 return Complex ((Im (z) / i) / promote (2, a), i); 00462 } 00463 } 00464 00465 TMPL inline Complex 00466 exp (const Complex& z) { 00467 return polar (exp (Re (z)), Im (z)); 00468 } 00469 00470 TMPL inline Complex 00471 log (const Complex& z) { 00472 return Complex (log (abs (z)), arg (z)); 00473 } 00474 00475 TMPL inline Complex 00476 pow (const Complex& z, const Complex& y) { 00477 C r= log (abs (z)); 00478 C t= arg (z); 00479 return polar (exp (r * Re (y) - Im (y) * t), 00480 Im (y) * r + Re (y) * t); 00481 } 00482 00483 TMPL inline Complex 00484 pow (const Complex& z, const C& y) { 00485 return exp (y * log (z)); 00486 } 00487 00488 TMPL inline Complex 00489 pow (const C& z, const Complex& y) { 00490 return exp (y * log (z)); 00491 } 00492 00493 TMPL inline Complex 00494 pow (const Complex& z, const int& y) { 00495 return exp (y * log (z)); 00496 } 00497 00498 TMPL inline Complex 00499 pow (const int& z, const Complex& y) { 00500 return exp (y * log (z)); 00501 } 00502 00503 TMPL inline Complex 00504 cos (const Complex& z) { 00505 return Complex (cos (Re (z)) * cosh (Im (z)), 00506 -sin (Re (z)) * sinh (Im (z))); 00507 } 00508 00509 TMPL inline Complex 00510 sin (const Complex& z) { 00511 return Complex (sin (Re (z)) * cosh (Im (z)), 00512 cos (Re (z)) * sinh (Im (z))); 00513 } 00514 00515 TMPL inline Complex 00516 tan (const Complex& z) { 00517 return sin (z) / cos (z); 00518 } 00519 00520 TMPL inline Complex 00521 acos (const C& z) { 00522 return over_i (acosh (z)); 00523 } 00524 00525 TMPL inline Complex 00526 asin (const C& z) { 00527 return over_i (asinh (times_i (z))); 00528 } 00529 00530 TMPL inline Complex 00531 atan (const C& z) { 00532 return over_i (atanh (times_i (z))); 00533 } 00534 00535 TMPL inline Complex 00536 acos (const Complex& z) { 00537 return over_i (acosh (z)); 00538 } 00539 00540 TMPL inline Complex 00541 asin (const Complex& z) { 00542 return over_i (asinh (times_i (z))); 00543 } 00544 00545 TMPL inline Complex 00546 atan (const Complex& z) { 00547 return over_i (atanh (times_i (z))); 00548 } 00549 00550 TMPL inline Complex 00551 cosh (const Complex& z) { 00552 return Complex (cosh (Re (z)) * cos (Im (z)), 00553 sinh (Re (z)) * sin (Im (z))); 00554 } 00555 00556 TMPL inline Complex 00557 sinh (const Complex& z) { 00558 return Complex (sinh (Re (z)) * cos (Im (z)), 00559 cosh (Re (z)) * sin (Im (z))); 00560 } 00561 00562 TMPL inline Complex 00563 tanh (const Complex& z) { 00564 return sinh (z) / cosh (z); 00565 } 00566 00567 INV_TRIGO_SUGAR(TMPL,Complex) 00568 INV_HYPER_SUGAR(TMPL,Complex) 00569 ARG_HYPER_SUGAR(TMPL,Complex) 00570 00571 /****************************************************************************** 00572 * Floating point related functions 00573 ******************************************************************************/ 00574 00575 TMPL inline bool is_finite (const Complex& z) { 00576 return is_finite (Re (z)) && is_finite (Im (z)); } 00577 TMPL inline bool is_nan (const Complex& z) { 00578 return is_nan (Re (z)) || is_nan (Im (z)); } 00579 TMPL inline bool is_infinite (const Complex& z) { 00580 return !is_nan (z) && (is_infinite (Re (z)) || is_infinite (Im (z))); } 00581 TMPL inline bool is_fuzz (const Complex& z) { 00582 return !is_nan (z) && (is_fuzz (Re (z)) || is_fuzz (Im (z))); } 00583 TMPL inline bool is_reliable (const Complex& z) { 00584 return is_reliable (Re (z)); } 00585 00586 TMPL inline Complex change_precision (const Complex& z, xnat prec) { 00587 return Complex (change_precision (Re (z), prec), 00588 change_precision (Im (z), prec)); } 00589 TMPL inline xnat precision (const Complex& z) { 00590 return min (precision (Re (z)), precision (Im (z))); } 00591 00592 TMPL inline Abs_type(C) rounding_error (const complex<C>& z) { 00593 typedef Round_up(Abs_type(C) ) Up; 00594 return Up::add (rounding_error (Re (z)), rounding_error (Im (z))); } 00595 TMPL inline Abs_type(C) additive_error (const complex<C>& z) { 00596 typedef Round_up(Abs_type(C) ) Up; 00597 return Up::add (additive_error (Re (z)), additive_error (Im (z))); } 00598 TMPL inline Abs_type(C) multiplicative_error (const complex<C>& z) { 00599 typedef Round_up(Abs_type(C) ) Up; 00600 return incexp2 (Up::add (multiplicative_error (Re (z)), 00601 multiplicative_error (Im (z))), 3); } 00602 TMPL inline Abs_type(C) elementary_error (const complex<C>& z) { 00603 typedef Round_up(Abs_type(C) ) Up; 00604 return incexp2 (Up::add (elementary_error (Re (z)), 00605 elementary_error (Im (z))), 3); } 00606 00607 /* 00608 template<typename V> inline floating<V> 00609 additive_error (const complex<floating<V> >& z) { 00610 floating<V> r (*Re(z)), s (*Im(z)); 00611 mpfr_abs (*r, *Re(z), GMP_RNDN); 00612 mpfr_abs (*s, *Im(z), GMP_RNDN); 00613 mpfr_add (*r, *s, GMP_RNDU); 00614 mpfr_mul_2si (*r, *r, 1-mpfr_get_prec (*Re(z)), GMP_RNDN); 00615 mpfr_nextabove (*r); 00616 return r; } 00617 */ 00618 00619 TMPL inline xint exponent (const Complex& z) { 00620 return max (exponent (Re (z)), exponent (Im (z))); } 00621 TMPL inline double magnitude (const Complex& z) { 00622 return magnitude (square (Re(z)) + square (Im(z))) / 2.0; } 00623 TMPL inline Complex operator << (const Complex& z, const xint& shift) { 00624 return Complex (incexp2 (Re (z), shift), incexp2 (Im (z), shift)); } 00625 TMPL inline Complex operator >> (const Complex& z, const xint& shift) { 00626 return Complex (decexp2 (Re (z), shift), decexp2 (Im (z), shift)); } 00627 00628 TMPL inline Complex& 00629 Complex::operator <<= (const xint& shift) { 00630 incexp2_assign (re, shift); 00631 incexp2_assign (im, shift); 00632 return *this; 00633 } 00634 00635 TMPL inline Complex& 00636 Complex::operator >>= (const xint& shift) { 00637 decexp2_assign (re, shift); 00638 decexp2_assign (im, shift); 00639 return *this; 00640 } 00641 00642 TMPL inline Complex sharpen (const Complex& z) { 00643 return Complex (sharpen (Re (z)), sharpen (Im (z))); } 00644 template<typename C, typename R> inline Complex 00645 blur (const Complex& z, const R& r) { 00646 return Complex (blur (Re (z), r), blur (Im (z), r)); } 00647 00648 #undef TMPL_DEF 00649 #undef TMPL 00650 #undef Complex 00651 } // namespace mmx 00652 #endif // __MMX_COMPLEX_HPP