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