complex

Go to the documentation of this file.
00001 // The template and inlines for the -*- C++ -*- complex number classes. 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 // 00032 // ISO C++ 14882: 26.2 Complex Numbers 00033 // Note: this is not a conforming implementation. 00034 // Initially implemented by Ulrich Drepper <drepper@cygnus.com> 00035 // Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 00036 // 00037 00038 /** @file complex 00039 * This is a Standard C++ Library header. You should @c #include this header 00040 * in your programs, rather than any of the "st[dl]_*.h" implementation files. 00041 */ 00042 00043 #ifndef _GLIBCXX_COMPLEX 00044 #define _GLIBCXX_COMPLEX 1 00045 00046 #pragma GCC system_header 00047 00048 #include <bits/c++config.h> 00049 #include <bits/cpp_type_traits.h> 00050 #include <cmath> 00051 #include <sstream> 00052 00053 namespace std 00054 { 00055 // Forward declarations 00056 template<typename _Tp> class complex; 00057 template<> class complex<float>; 00058 template<> class complex<double>; 00059 template<> class complex<long double>; 00060 00061 /// Return magnitude of @a z. 00062 template<typename _Tp> _Tp abs(const complex<_Tp>&); 00063 /// Return phase angle of @a z. 00064 template<typename _Tp> _Tp arg(const complex<_Tp>&); 00065 /// Return @a z magnitude squared. 00066 template<typename _Tp> _Tp norm(const complex<_Tp>&); 00067 00068 /// Return complex conjugate of @a z. 00069 template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); 00070 /// Return complex with magnitude @a rho and angle @a theta. 00071 template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); 00072 00073 // Transcendentals: 00074 /// Return complex cosine of @a z. 00075 template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); 00076 /// Return complex hyperbolic cosine of @a z. 00077 template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); 00078 /// Return complex base e exponential of @a z. 00079 template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); 00080 /// Return complex natural logarithm of @a z. 00081 template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); 00082 /// Return complex base 10 logarithm of @a z. 00083 template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); 00084 /// Return complex cosine of @a z. 00085 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); 00086 /// Return @a x to the @a y'th power. 00087 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); 00088 /// Return @a x to the @a y'th power. 00089 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 00090 const complex<_Tp>&); 00091 /// Return @a x to the @a y'th power. 00092 template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); 00093 /// Return complex sine of @a z. 00094 template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); 00095 /// Return complex hyperbolic sine of @a z. 00096 template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); 00097 /// Return complex square root of @a z. 00098 template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); 00099 /// Return complex tangent of @a z. 00100 template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); 00101 /// Return complex hyperbolic tangent of @a z. 00102 template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); 00103 //@} 00104 00105 00106 // 26.2.2 Primary template class complex 00107 /** 00108 * Template to represent complex numbers. 00109 * 00110 * Specializations for float, double, and long double are part of the 00111 * library. Results with any other type are not guaranteed. 00112 * 00113 * @param Tp Type of real and imaginary values. 00114 */ 00115 template<typename _Tp> 00116 class complex 00117 { 00118 public: 00119 /// Value typedef. 00120 typedef _Tp value_type; 00121 00122 /// Default constructor. First parameter is x, second parameter is y. 00123 /// Unspecified parameters default to 0. 00124 complex(const _Tp& = _Tp(), const _Tp & = _Tp()); 00125 00126 // Lets the compiler synthesize the copy constructor 00127 // complex (const complex<_Tp>&); 00128 /// Copy constructor. 00129 template<typename _Up> 00130 complex(const complex<_Up>&); 00131 00132 /// Return real part of complex number. 00133 _Tp& real(); 00134 /// Return real part of complex number. 00135 const _Tp& real() const; 00136 /// Return imaginary part of complex number. 00137 _Tp& imag(); 00138 /// Return imaginary part of complex number. 00139 const _Tp& imag() const; 00140 00141 /// Assign this complex number to scalar @a t. 00142 complex<_Tp>& operator=(const _Tp&); 00143 /// Add @a t to this complex number. 00144 complex<_Tp>& operator+=(const _Tp&); 00145 /// Subtract @a t from this complex number. 00146 complex<_Tp>& operator-=(const _Tp&); 00147 /// Multiply this complex number by @a t. 00148 complex<_Tp>& operator*=(const _Tp&); 00149 /// Divide this complex number by @a t. 00150 complex<_Tp>& operator/=(const _Tp&); 00151 00152 // Lets the compiler synthesize the 00153 // copy and assignment operator 00154 // complex<_Tp>& operator= (const complex<_Tp>&); 00155 /// Assign this complex number to complex @a z. 00156 template<typename _Up> 00157 complex<_Tp>& operator=(const complex<_Up>&); 00158 /// Add @a z to this complex number. 00159 template<typename _Up> 00160 complex<_Tp>& operator+=(const complex<_Up>&); 00161 /// Subtract @a z from this complex number. 00162 template<typename _Up> 00163 complex<_Tp>& operator-=(const complex<_Up>&); 00164 /// Multiply this complex number by @a z. 00165 template<typename _Up> 00166 complex<_Tp>& operator*=(const complex<_Up>&); 00167 /// Divide this complex number by @a z. 00168 template<typename _Up> 00169 complex<_Tp>& operator/=(const complex<_Up>&); 00170 00171 private: 00172 _Tp _M_real; 00173 _Tp _M_imag; 00174 }; 00175 00176 template<typename _Tp> 00177 inline _Tp& 00178 complex<_Tp>::real() { return _M_real; } 00179 00180 template<typename _Tp> 00181 inline const _Tp& 00182 complex<_Tp>::real() const { return _M_real; } 00183 00184 template<typename _Tp> 00185 inline _Tp& 00186 complex<_Tp>::imag() { return _M_imag; } 00187 00188 template<typename _Tp> 00189 inline const _Tp& 00190 complex<_Tp>::imag() const { return _M_imag; } 00191 00192 template<typename _Tp> 00193 inline 00194 complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) 00195 : _M_real(__r), _M_imag(__i) { } 00196 00197 template<typename _Tp> 00198 template<typename _Up> 00199 inline 00200 complex<_Tp>::complex(const complex<_Up>& __z) 00201 : _M_real(__z.real()), _M_imag(__z.imag()) { } 00202 00203 template<typename _Tp> 00204 complex<_Tp>& 00205 complex<_Tp>::operator=(const _Tp& __t) 00206 { 00207 _M_real = __t; 00208 _M_imag = _Tp(); 00209 return *this; 00210 } 00211 00212 // 26.2.5/1 00213 template<typename _Tp> 00214 inline complex<_Tp>& 00215 complex<_Tp>::operator+=(const _Tp& __t) 00216 { 00217 _M_real += __t; 00218 return *this; 00219 } 00220 00221 // 26.2.5/3 00222 template<typename _Tp> 00223 inline complex<_Tp>& 00224 complex<_Tp>::operator-=(const _Tp& __t) 00225 { 00226 _M_real -= __t; 00227 return *this; 00228 } 00229 00230 // 26.2.5/5 00231 template<typename _Tp> 00232 complex<_Tp>& 00233 complex<_Tp>::operator*=(const _Tp& __t) 00234 { 00235 _M_real *= __t; 00236 _M_imag *= __t; 00237 return *this; 00238 } 00239 00240 // 26.2.5/7 00241 template<typename _Tp> 00242 complex<_Tp>& 00243 complex<_Tp>::operator/=(const _Tp& __t) 00244 { 00245 _M_real /= __t; 00246 _M_imag /= __t; 00247 return *this; 00248 } 00249 00250 template<typename _Tp> 00251 template<typename _Up> 00252 complex<_Tp>& 00253 complex<_Tp>::operator=(const complex<_Up>& __z) 00254 { 00255 _M_real = __z.real(); 00256 _M_imag = __z.imag(); 00257 return *this; 00258 } 00259 00260 // 26.2.5/9 00261 template<typename _Tp> 00262 template<typename _Up> 00263 complex<_Tp>& 00264 complex<_Tp>::operator+=(const complex<_Up>& __z) 00265 { 00266 _M_real += __z.real(); 00267 _M_imag += __z.imag(); 00268 return *this; 00269 } 00270 00271 // 26.2.5/11 00272 template<typename _Tp> 00273 template<typename _Up> 00274 complex<_Tp>& 00275 complex<_Tp>::operator-=(const complex<_Up>& __z) 00276 { 00277 _M_real -= __z.real(); 00278 _M_imag -= __z.imag(); 00279 return *this; 00280 } 00281 00282 // 26.2.5/13 00283 // XXX: This is a grammar school implementation. 00284 template<typename _Tp> 00285 template<typename _Up> 00286 complex<_Tp>& 00287 complex<_Tp>::operator*=(const complex<_Up>& __z) 00288 { 00289 const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); 00290 _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); 00291 _M_real = __r; 00292 return *this; 00293 } 00294 00295 // 26.2.5/15 00296 // XXX: This is a grammar school implementation. 00297 template<typename _Tp> 00298 template<typename _Up> 00299 complex<_Tp>& 00300 complex<_Tp>::operator/=(const complex<_Up>& __z) 00301 { 00302 const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); 00303 const _Tp __n = std::norm(__z); 00304 _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; 00305 _M_real = __r / __n; 00306 return *this; 00307 } 00308 00309 // Operators: 00310 //@{ 00311 /// Return new complex value @a x plus @a y. 00312 template<typename _Tp> 00313 inline complex<_Tp> 00314 operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 00315 { 00316 complex<_Tp> __r = __x; 00317 __r += __y; 00318 return __r; 00319 } 00320 00321 template<typename _Tp> 00322 inline complex<_Tp> 00323 operator+(const complex<_Tp>& __x, const _Tp& __y) 00324 { 00325 complex<_Tp> __r = __x; 00326 __r.real() += __y; 00327 return __r; 00328 } 00329 00330 template<typename _Tp> 00331 inline complex<_Tp> 00332 operator+(const _Tp& __x, const complex<_Tp>& __y) 00333 { 00334 complex<_Tp> __r = __y; 00335 __r.real() += __x; 00336 return __r; 00337 } 00338 //@} 00339 00340 //@{ 00341 /// Return new complex value @a x minus @a y. 00342 template<typename _Tp> 00343 inline complex<_Tp> 00344 operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 00345 { 00346 complex<_Tp> __r = __x; 00347 __r -= __y; 00348 return __r; 00349 } 00350 00351 template<typename _Tp> 00352 inline complex<_Tp> 00353 operator-(const complex<_Tp>& __x, const _Tp& __y) 00354 { 00355 complex<_Tp> __r = __x; 00356 __r.real() -= __y; 00357 return __r; 00358 } 00359 00360 template<typename _Tp> 00361 inline complex<_Tp> 00362 operator-(const _Tp& __x, const complex<_Tp>& __y) 00363 { 00364 complex<_Tp> __r(__x, -__y.imag()); 00365 __r.real() -= __y.real(); 00366 return __r; 00367 } 00368 //@} 00369 00370 //@{ 00371 /// Return new complex value @a x times @a y. 00372 template<typename _Tp> 00373 inline complex<_Tp> 00374 operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) 00375 { 00376 complex<_Tp> __r = __x; 00377 __r *= __y; 00378 return __r; 00379 } 00380 00381 template<typename _Tp> 00382 inline complex<_Tp> 00383 operator*(const complex<_Tp>& __x, const _Tp& __y) 00384 { 00385 complex<_Tp> __r = __x; 00386 __r *= __y; 00387 return __r; 00388 } 00389 00390 template<typename _Tp> 00391 inline complex<_Tp> 00392 operator*(const _Tp& __x, const complex<_Tp>& __y) 00393 { 00394 complex<_Tp> __r = __y; 00395 __r *= __x; 00396 return __r; 00397 } 00398 //@} 00399 00400 //@{ 00401 /// Return new complex value @a x divided by @a y. 00402 template<typename _Tp> 00403 inline complex<_Tp> 00404 operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) 00405 { 00406 complex<_Tp> __r = __x; 00407 __r /= __y; 00408 return __r; 00409 } 00410 00411 template<typename _Tp> 00412 inline complex<_Tp> 00413 operator/(const complex<_Tp>& __x, const _Tp& __y) 00414 { 00415 complex<_Tp> __r = __x; 00416 __r /= __y; 00417 return __r; 00418 } 00419 00420 template<typename _Tp> 00421 inline complex<_Tp> 00422 operator/(const _Tp& __x, const complex<_Tp>& __y) 00423 { 00424 complex<_Tp> __r = __x; 00425 __r /= __y; 00426 return __r; 00427 } 00428 //@} 00429 00430 /// Return @a x. 00431 template<typename _Tp> 00432 inline complex<_Tp> 00433 operator+(const complex<_Tp>& __x) 00434 { return __x; } 00435 00436 /// Return complex negation of @a x. 00437 template<typename _Tp> 00438 inline complex<_Tp> 00439 operator-(const complex<_Tp>& __x) 00440 { return complex<_Tp>(-__x.real(), -__x.imag()); } 00441 00442 //@{ 00443 /// Return true if @a x is equal to @a y. 00444 template<typename _Tp> 00445 inline bool 00446 operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 00447 { return __x.real() == __y.real() && __x.imag() == __y.imag(); } 00448 00449 template<typename _Tp> 00450 inline bool 00451 operator==(const complex<_Tp>& __x, const _Tp& __y) 00452 { return __x.real() == __y && __x.imag() == _Tp(); } 00453 00454 template<typename _Tp> 00455 inline bool 00456 operator==(const _Tp& __x, const complex<_Tp>& __y) 00457 { return __x == __y.real() && _Tp() == __y.imag(); } 00458 //@} 00459 00460 //@{ 00461 /// Return false if @a x is equal to @a y. 00462 template<typename _Tp> 00463 inline bool 00464 operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 00465 { return __x.real() != __y.real() || __x.imag() != __y.imag(); } 00466 00467 template<typename _Tp> 00468 inline bool 00469 operator!=(const complex<_Tp>& __x, const _Tp& __y) 00470 { return __x.real() != __y || __x.imag() != _Tp(); } 00471 00472 template<typename _Tp> 00473 inline bool 00474 operator!=(const _Tp& __x, const complex<_Tp>& __y) 00475 { return __x != __y.real() || _Tp() != __y.imag(); } 00476 //@} 00477 00478 /// Extraction operator for complex values. 00479 template<typename _Tp, typename _CharT, class _Traits> 00480 basic_istream<_CharT, _Traits>& 00481 operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 00482 { 00483 _Tp __re_x, __im_x; 00484 _CharT __ch; 00485 __is >> __ch; 00486 if (__ch == '(') 00487 { 00488 __is >> __re_x >> __ch; 00489 if (__ch == ',') 00490 { 00491 __is >> __im_x >> __ch; 00492 if (__ch == ')') 00493 __x = complex<_Tp>(__re_x, __im_x); 00494 else 00495 __is.setstate(ios_base::failbit); 00496 } 00497 else if (__ch == ')') 00498 __x = __re_x; 00499 else 00500 __is.setstate(ios_base::failbit); 00501 } 00502 else 00503 { 00504 __is.putback(__ch); 00505 __is >> __re_x; 00506 __x = __re_x; 00507 } 00508 return __is; 00509 } 00510 00511 /// Insertion operator for complex values. 00512 template<typename _Tp, typename _CharT, class _Traits> 00513 basic_ostream<_CharT, _Traits>& 00514 operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 00515 { 00516 basic_ostringstream<_CharT, _Traits> __s; 00517 __s.flags(__os.flags()); 00518 __s.imbue(__os.getloc()); 00519 __s.precision(__os.precision()); 00520 __s << '(' << __x.real() << ',' << __x.imag() << ')'; 00521 return __os << __s.str(); 00522 } 00523 00524 // Values 00525 template<typename _Tp> 00526 inline _Tp& 00527 real(complex<_Tp>& __z) 00528 { return __z.real(); } 00529 00530 template<typename _Tp> 00531 inline const _Tp& 00532 real(const complex<_Tp>& __z) 00533 { return __z.real(); } 00534 00535 template<typename _Tp> 00536 inline _Tp& 00537 imag(complex<_Tp>& __z) 00538 { return __z.imag(); } 00539 00540 template<typename _Tp> 00541 inline const _Tp& 00542 imag(const complex<_Tp>& __z) 00543 { return __z.imag(); } 00544 00545 template<typename _Tp> 00546 inline _Tp 00547 abs(const complex<_Tp>& __z) 00548 { 00549 _Tp __x = __z.real(); 00550 _Tp __y = __z.imag(); 00551 const _Tp __s = std::max(abs(__x), abs(__y)); 00552 if (__s == _Tp()) // well ... 00553 return __s; 00554 __x /= __s; 00555 __y /= __s; 00556 return __s * sqrt(__x * __x + __y * __y); 00557 } 00558 00559 template<typename _Tp> 00560 inline _Tp 00561 arg(const complex<_Tp>& __z) 00562 { return atan2(__z.imag(), __z.real()); } 00563 00564 // 26.2.7/5: norm(__z) returns the squared magintude of __z. 00565 // As defined, norm() is -not- a norm is the common mathematical 00566 // sens used in numerics. The helper class _Norm_helper<> tries to 00567 // distinguish between builtin floating point and the rest, so as 00568 // to deliver an answer as close as possible to the real value. 00569 template<bool> 00570 struct _Norm_helper 00571 { 00572 template<typename _Tp> 00573 static inline _Tp _S_do_it(const complex<_Tp>& __z) 00574 { 00575 const _Tp __x = __z.real(); 00576 const _Tp __y = __z.imag(); 00577 return __x * __x + __y * __y; 00578 } 00579 }; 00580 00581 template<> 00582 struct _Norm_helper<true> 00583 { 00584 template<typename _Tp> 00585 static inline _Tp _S_do_it(const complex<_Tp>& __z) 00586 { 00587 _Tp __res = std::abs(__z); 00588 return __res * __res; 00589 } 00590 }; 00591 00592 template<typename _Tp> 00593 inline _Tp 00594 norm(const complex<_Tp>& __z) 00595 { 00596 return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); 00597 } 00598 00599 template<typename _Tp> 00600 inline complex<_Tp> 00601 polar(const _Tp& __rho, const _Tp& __theta) 00602 { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } 00603 00604 template<typename _Tp> 00605 inline complex<_Tp> 00606 conj(const complex<_Tp>& __z) 00607 { return complex<_Tp>(__z.real(), -__z.imag()); } 00608 00609 // Transcendentals 00610 template<typename _Tp> 00611 inline complex<_Tp> 00612 cos(const complex<_Tp>& __z) 00613 { 00614 const _Tp __x = __z.real(); 00615 const _Tp __y = __z.imag(); 00616 return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); 00617 } 00618 00619 template<typename _Tp> 00620 inline complex<_Tp> 00621 cosh(const complex<_Tp>& __z) 00622 { 00623 const _Tp __x = __z.real(); 00624 const _Tp __y = __z.imag(); 00625 return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); 00626 } 00627 00628 template<typename _Tp> 00629 inline complex<_Tp> 00630 exp(const complex<_Tp>& __z) 00631 { return std::polar(exp(__z.real()), __z.imag()); } 00632 00633 template<typename _Tp> 00634 inline complex<_Tp> 00635 log(const complex<_Tp>& __z) 00636 { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } 00637 00638 template<typename _Tp> 00639 inline complex<_Tp> 00640 log10(const complex<_Tp>& __z) 00641 { return std::log(__z) / log(_Tp(10.0)); } 00642 00643 template<typename _Tp> 00644 inline complex<_Tp> 00645 sin(const complex<_Tp>& __z) 00646 { 00647 const _Tp __x = __z.real(); 00648 const _Tp __y = __z.imag(); 00649 return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 00650 } 00651 00652 template<typename _Tp> 00653 inline complex<_Tp> 00654 sinh(const complex<_Tp>& __z) 00655 { 00656 const _Tp __x = __z.real(); 00657 const _Tp __y = __z.imag(); 00658 return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); 00659 } 00660 00661 template<typename _Tp> 00662 complex<_Tp> 00663 sqrt(const complex<_Tp>& __z) 00664 { 00665 _Tp __x = __z.real(); 00666 _Tp __y = __z.imag(); 00667 00668 if (__x == _Tp()) 00669 { 00670 _Tp __t = sqrt(abs(__y) / 2); 00671 return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); 00672 } 00673 else 00674 { 00675 _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); 00676 _Tp __u = __t / 2; 00677 return __x > _Tp() 00678 ? complex<_Tp>(__u, __y / __t) 00679 : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); 00680 } 00681 } 00682 00683 template<typename _Tp> 00684 inline complex<_Tp> 00685 tan(const complex<_Tp>& __z) 00686 { 00687 return std::sin(__z) / std::cos(__z); 00688 } 00689 00690 template<typename _Tp> 00691 inline complex<_Tp> 00692 tanh(const complex<_Tp>& __z) 00693 { 00694 return std::sinh(__z) / std::cosh(__z); 00695 } 00696 00697 template<typename _Tp> 00698 inline complex<_Tp> 00699 pow(const complex<_Tp>& __z, int __n) 00700 { 00701 return std::__pow_helper(__z, __n); 00702 } 00703 00704 template<typename _Tp> 00705 complex<_Tp> 00706 pow(const complex<_Tp>& __x, const _Tp& __y) 00707 { 00708 if (__x.imag() == _Tp() && __x.real() > _Tp()) 00709 return pow(__x.real(), __y); 00710 00711 complex<_Tp> __t = std::log(__x); 00712 return std::polar(exp(__y * __t.real()), __y * __t.imag()); 00713 } 00714 00715 template<typename _Tp> 00716 inline complex<_Tp> 00717 pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 00718 { 00719 return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); 00720 } 00721 00722 template<typename _Tp> 00723 inline complex<_Tp> 00724 pow(const _Tp& __x, const complex<_Tp>& __y) 00725 { 00726 return __x > _Tp() ? std::polar(pow(__x, __y.real()), 00727 __y.imag() * log(__x)) 00728 : std::pow(complex<_Tp>(__x, _Tp()), __y); 00729 } 00730 00731 // 26.2.3 complex specializations 00732 // complex<float> specialization 00733 template<> class complex<float> 00734 { 00735 public: 00736 typedef float value_type; 00737 00738 complex(float = 0.0f, float = 0.0f); 00739 #ifdef _GLIBCXX_BUGGY_COMPLEX 00740 complex(const complex& __z) : _M_value(__z._M_value) { } 00741 #endif 00742 explicit complex(const complex<double>&); 00743 explicit complex(const complex<long double>&); 00744 00745 float& real(); 00746 const float& real() const; 00747 float& imag(); 00748 const float& imag() const; 00749 00750 complex<float>& operator=(float); 00751 complex<float>& operator+=(float); 00752 complex<float>& operator-=(float); 00753 complex<float>& operator*=(float); 00754 complex<float>& operator/=(float); 00755 00756 // Let's the compiler synthetize the copy and assignment 00757 // operator. It always does a pretty good job. 00758 // complex& operator= (const complex&); 00759 template<typename _Tp> 00760 complex<float>&operator=(const complex<_Tp>&); 00761 template<typename _Tp> 00762 complex<float>& operator+=(const complex<_Tp>&); 00763 template<class _Tp> 00764 complex<float>& operator-=(const complex<_Tp>&); 00765 template<class _Tp> 00766 complex<float>& operator*=(const complex<_Tp>&); 00767 template<class _Tp> 00768 complex<float>&operator/=(const complex<_Tp>&); 00769 00770 private: 00771 typedef __complex__ float _ComplexT; 00772 _ComplexT _M_value; 00773 00774 complex(_ComplexT __z) : _M_value(__z) { } 00775 00776 friend class complex<double>; 00777 friend class complex<long double>; 00778 }; 00779 00780 inline float& 00781 complex<float>::real() 00782 { return __real__ _M_value; } 00783 00784 inline const float& 00785 complex<float>::real() const 00786 { return __real__ _M_value; } 00787 00788 inline float& 00789 complex<float>::imag() 00790 { return __imag__ _M_value; } 00791 00792 inline const float& 00793 complex<float>::imag() const 00794 { return __imag__ _M_value; } 00795 00796 inline 00797 complex<float>::complex(float r, float i) 00798 { 00799 __real__ _M_value = r; 00800 __imag__ _M_value = i; 00801 } 00802 00803 inline complex<float>& 00804 complex<float>::operator=(float __f) 00805 { 00806 __real__ _M_value = __f; 00807 __imag__ _M_value = 0.0f; 00808 return *this; 00809 } 00810 00811 inline complex<float>& 00812 complex<float>::operator+=(float __f) 00813 { 00814 __real__ _M_value += __f; 00815 return *this; 00816 } 00817 00818 inline complex<float>& 00819 complex<float>::operator-=(float __f) 00820 { 00821 __real__ _M_value -= __f; 00822 return *this; 00823 } 00824 00825 inline complex<float>& 00826 complex<float>::operator*=(float __f) 00827 { 00828 _M_value *= __f; 00829 return *this; 00830 } 00831 00832 inline complex<float>& 00833 complex<float>::operator/=(float __f) 00834 { 00835 _M_value /= __f; 00836 return *this; 00837 } 00838 00839 template<typename _Tp> 00840 inline complex<float>& 00841 complex<float>::operator=(const complex<_Tp>& __z) 00842 { 00843 __real__ _M_value = __z.real(); 00844 __imag__ _M_value = __z.imag(); 00845 return *this; 00846 } 00847 00848 template<typename _Tp> 00849 inline complex<float>& 00850 complex<float>::operator+=(const complex<_Tp>& __z) 00851 { 00852 __real__ _M_value += __z.real(); 00853 __imag__ _M_value += __z.imag(); 00854 return *this; 00855 } 00856 00857 template<typename _Tp> 00858 inline complex<float>& 00859 complex<float>::operator-=(const complex<_Tp>& __z) 00860 { 00861 __real__ _M_value -= __z.real(); 00862 __imag__ _M_value -= __z.imag(); 00863 return *this; 00864 } 00865 00866 template<typename _Tp> 00867 inline complex<float>& 00868 complex<float>::operator*=(const complex<_Tp>& __z) 00869 { 00870 _ComplexT __t; 00871 __real__ __t = __z.real(); 00872 __imag__ __t = __z.imag(); 00873 _M_value *= __t; 00874 return *this; 00875 } 00876 00877 template<typename _Tp> 00878 inline complex<float>& 00879 complex<float>::operator/=(const complex<_Tp>& __z) 00880 { 00881 _ComplexT __t; 00882 __real__ __t = __z.real(); 00883 __imag__ __t = __z.imag(); 00884 _M_value /= __t; 00885 return *this; 00886 } 00887 00888 // 26.2.3 complex specializations 00889 // complex<double> specialization 00890 template<> class complex<double> 00891 { 00892 public: 00893 typedef double value_type; 00894 00895 complex(double =0.0, double =0.0); 00896 #ifdef _GLIBCXX_BUGGY_COMPLEX 00897 complex(const complex& __z) : _M_value(__z._M_value) { } 00898 #endif 00899 complex(const complex<float>&); 00900 explicit complex(const complex<long double>&); 00901 00902 double& real(); 00903 const double& real() const; 00904 double& imag(); 00905 const double& imag() const; 00906 00907 complex<double>& operator=(double); 00908 complex<double>& operator+=(double); 00909 complex<double>& operator-=(double); 00910 complex<double>& operator*=(double); 00911 complex<double>& operator/=(double); 00912 00913 // The compiler will synthetize this, efficiently. 00914 // complex& operator= (const complex&); 00915 template<typename _Tp> 00916 complex<double>& operator=(const complex<_Tp>&); 00917 template<typename _Tp> 00918 complex<double>& operator+=(const complex<_Tp>&); 00919 template<typename _Tp> 00920 complex<double>& operator-=(const complex<_Tp>&); 00921 template<typename _Tp> 00922 complex<double>& operator*=(const complex<_Tp>&); 00923 template<typename _Tp> 00924 complex<double>& operator/=(const complex<_Tp>&); 00925 00926 private: 00927 typedef __complex__ double _ComplexT; 00928 _ComplexT _M_value; 00929 00930 complex(_ComplexT __z) : _M_value(__z) { } 00931 00932 friend class complex<float>; 00933 friend class complex<long double>; 00934 }; 00935 00936 inline double& 00937 complex<double>::real() 00938 { return __real__ _M_value; } 00939 00940 inline const double& 00941 complex<double>::real() const 00942 { return __real__ _M_value; } 00943 00944 inline double& 00945 complex<double>::imag() 00946 { return __imag__ _M_value; } 00947 00948 inline const double& 00949 complex<double>::imag() const 00950 { return __imag__ _M_value; } 00951 00952 inline 00953 complex<double>::complex(double __r, double __i) 00954 { 00955 __real__ _M_value = __r; 00956 __imag__ _M_value = __i; 00957 } 00958 00959 inline complex<double>& 00960 complex<double>::operator=(double __d) 00961 { 00962 __real__ _M_value = __d; 00963 __imag__ _M_value = 0.0; 00964 return *this; 00965 } 00966 00967 inline complex<double>& 00968 complex<double>::operator+=(double __d) 00969 { 00970 __real__ _M_value += __d; 00971 return *this; 00972 } 00973 00974 inline complex<double>& 00975 complex<double>::operator-=(double __d) 00976 { 00977 __real__ _M_value -= __d; 00978 return *this; 00979 } 00980 00981 inline complex<double>& 00982 complex<double>::operator*=(double __d) 00983 { 00984 _M_value *= __d; 00985 return *this; 00986 } 00987 00988 inline complex<double>& 00989 complex<double>::operator/=(double __d) 00990 { 00991 _M_value /= __d; 00992 return *this; 00993 } 00994 00995 template<typename _Tp> 00996 inline complex<double>& 00997 complex<double>::operator=(const complex<_Tp>& __z) 00998 { 00999 __real__ _M_value = __z.real(); 01000 __imag__ _M_value = __z.imag(); 01001 return *this; 01002 } 01003 01004 template<typename _Tp> 01005 inline complex<double>& 01006 complex<double>::operator+=(const complex<_Tp>& __z) 01007 { 01008 __real__ _M_value += __z.real(); 01009 __imag__ _M_value += __z.imag(); 01010 return *this; 01011 } 01012 01013 template<typename _Tp> 01014 inline complex<double>& 01015 complex<double>::operator-=(const complex<_Tp>& __z) 01016 { 01017 __real__ _M_value -= __z.real(); 01018 __imag__ _M_value -= __z.imag(); 01019 return *this; 01020 } 01021 01022 template<typename _Tp> 01023 inline complex<double>& 01024 complex<double>::operator*=(const complex<_Tp>& __z) 01025 { 01026 _ComplexT __t; 01027 __real__ __t = __z.real(); 01028 __imag__ __t = __z.imag(); 01029 _M_value *= __t; 01030 return *this; 01031 } 01032 01033 template<typename _Tp> 01034 inline complex<double>& 01035 complex<double>::operator/=(const complex<_Tp>& __z) 01036 { 01037 _ComplexT __t; 01038 __real__ __t = __z.real(); 01039 __imag__ __t = __z.imag(); 01040 _M_value /= __t; 01041 return *this; 01042 } 01043 01044 // 26.2.3 complex specializations 01045 // complex<long double> specialization 01046 template<> class complex<long double> 01047 { 01048 public: 01049 typedef long double value_type; 01050 01051 complex(long double = 0.0L, long double = 0.0L); 01052 #ifdef _GLIBCXX_BUGGY_COMPLEX 01053 complex(const complex& __z) : _M_value(__z._M_value) { } 01054 #endif 01055 complex(const complex<float>&); 01056 complex(const complex<double>&); 01057 01058 long double& real(); 01059 const long double& real() const; 01060 long double& imag(); 01061 const long double& imag() const; 01062 01063 complex<long double>& operator= (long double); 01064 complex<long double>& operator+= (long double); 01065 complex<long double>& operator-= (long double); 01066 complex<long double>& operator*= (long double); 01067 complex<long double>& operator/= (long double); 01068 01069 // The compiler knows how to do this efficiently 01070 // complex& operator= (const complex&); 01071 template<typename _Tp> 01072 complex<long double>& operator=(const complex<_Tp>&); 01073 template<typename _Tp> 01074 complex<long double>& operator+=(const complex<_Tp>&); 01075 template<typename _Tp> 01076 complex<long double>& operator-=(const complex<_Tp>&); 01077 template<typename _Tp> 01078 complex<long double>& operator*=(const complex<_Tp>&); 01079 template<typename _Tp> 01080 complex<long double>& operator/=(const complex<_Tp>&); 01081 01082 private: 01083 typedef __complex__ long double _ComplexT; 01084 _ComplexT _M_value; 01085 01086 complex(_ComplexT __z) : _M_value(__z) { } 01087 01088 friend class complex<float>; 01089 friend class complex<double>; 01090 }; 01091 01092 inline 01093 complex<long double>::complex(long double __r, long double __i) 01094 { 01095 __real__ _M_value = __r; 01096 __imag__ _M_value = __i; 01097 } 01098 01099 inline long double& 01100 complex<long double>::real() 01101 { return __real__ _M_value; } 01102 01103 inline const long double& 01104 complex<long double>::real() const 01105 { return __real__ _M_value; } 01106 01107 inline long double& 01108 complex<long double>::imag() 01109 { return __imag__ _M_value; } 01110 01111 inline const long double& 01112 complex<long double>::imag() const 01113 { return __imag__ _M_value; } 01114 01115 inline complex<long double>& 01116 complex<long double>::operator=(long double __r) 01117 { 01118 __real__ _M_value = __r; 01119 __imag__ _M_value = 0.0L; 01120 return *this; 01121 } 01122 01123 inline complex<long double>& 01124 complex<long double>::operator+=(long double __r) 01125 { 01126 __real__ _M_value += __r; 01127 return *this; 01128 } 01129 01130 inline complex<long double>& 01131 complex<long double>::operator-=(long double __r) 01132 { 01133 __real__ _M_value -= __r; 01134 return *this; 01135 } 01136 01137 inline complex<long double>& 01138 complex<long double>::operator*=(long double __r) 01139 { 01140 _M_value *= __r; 01141 return *this; 01142 } 01143 01144 inline complex<long double>& 01145 complex<long double>::operator/=(long double __r) 01146 { 01147 _M_value /= __r; 01148 return *this; 01149 } 01150 01151 template<typename _Tp> 01152 inline complex<long double>& 01153 complex<long double>::operator=(const complex<_Tp>& __z) 01154 { 01155 __real__ _M_value = __z.real(); 01156 __imag__ _M_value = __z.imag(); 01157 return *this; 01158 } 01159 01160 template<typename _Tp> 01161 inline complex<long double>& 01162 complex<long double>::operator+=(const complex<_Tp>& __z) 01163 { 01164 __real__ _M_value += __z.real(); 01165 __imag__ _M_value += __z.imag(); 01166 return *this; 01167 } 01168 01169 template<typename _Tp> 01170 inline complex<long double>& 01171 complex<long double>::operator-=(const complex<_Tp>& __z) 01172 { 01173 __real__ _M_value -= __z.real(); 01174 __imag__ _M_value -= __z.imag(); 01175 return *this; 01176 } 01177 01178 template<typename _Tp> 01179 inline complex<long double>& 01180 complex<long double>::operator*=(const complex<_Tp>& __z) 01181 { 01182 _ComplexT __t; 01183 __real__ __t = __z.real(); 01184 __imag__ __t = __z.imag(); 01185 _M_value *= __t; 01186 return *this; 01187 } 01188 01189 template<typename _Tp> 01190 inline complex<long double>& 01191 complex<long double>::operator/=(const complex<_Tp>& __z) 01192 { 01193 _ComplexT __t; 01194 __real__ __t = __z.real(); 01195 __imag__ __t = __z.imag(); 01196 _M_value /= __t; 01197 return *this; 01198 } 01199 01200 // These bits have to be at the end of this file, so that the 01201 // specializations have all been defined. 01202 // ??? No, they have to be there because of compiler limitation at 01203 // inlining. It suffices that class specializations be defined. 01204 inline 01205 complex<float>::complex(const complex<double>& __z) 01206 : _M_value(_ComplexT(__z._M_value)) { } 01207 01208 inline 01209 complex<float>::complex(const complex<long double>& __z) 01210 : _M_value(_ComplexT(__z._M_value)) { } 01211 01212 inline 01213 complex<double>::complex(const complex<float>& __z) 01214 : _M_value(_ComplexT(__z._M_value)) { } 01215 01216 inline 01217 complex<double>::complex(const complex<long double>& __z) 01218 { 01219 __real__ _M_value = __z.real(); 01220 __imag__ _M_value = __z.imag(); 01221 } 01222 01223 inline 01224 complex<long double>::complex(const complex<float>& __z) 01225 : _M_value(_ComplexT(__z._M_value)) { } 01226 01227 inline 01228 complex<long double>::complex(const complex<double>& __z) 01229 : _M_value(_ComplexT(__z._M_value)) { } 01230 } // namespace std 01231 01232 #endif /* _GLIBCXX_COMPLEX */

Generated on Wed Sep 8 10:19:28 2004 for libstdc++-v3 Source by doxygen 1.3.8