libstdc++
|
00001 // TR1 complex -*- C++ -*- 00002 00003 // Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /** @file tr1/complex 00027 * This is a TR1 C++ Library header. 00028 */ 00029 00030 #ifndef _GLIBCXX_TR1_COMPLEX 00031 #define _GLIBCXX_TR1_COMPLEX 1 00032 00033 #pragma GCC system_header 00034 00035 #include <complex> 00036 00037 namespace std _GLIBCXX_VISIBILITY(default) 00038 { 00039 namespace tr1 00040 { 00041 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00042 00043 /** 00044 * @addtogroup complex_numbers 00045 * @{ 00046 */ 00047 00048 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00049 using std::acos; 00050 using std::asin; 00051 using std::atan; 00052 #else 00053 template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); 00054 template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); 00055 template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); 00056 #endif 00057 00058 template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); 00059 template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); 00060 template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); 00061 00062 // The std::fabs return type in C++0x mode is different (just _Tp). 00063 template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); 00064 00065 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00066 template<typename _Tp> 00067 inline std::complex<_Tp> 00068 __complex_acos(const std::complex<_Tp>& __z) 00069 { 00070 const std::complex<_Tp> __t = std::tr1::asin(__z); 00071 const _Tp __pi_2 = 1.5707963267948966192313216916397514L; 00072 return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); 00073 } 00074 00075 #if _GLIBCXX_USE_C99_COMPLEX_TR1 00076 inline __complex__ float 00077 __complex_acos(__complex__ float __z) 00078 { return __builtin_cacosf(__z); } 00079 00080 inline __complex__ double 00081 __complex_acos(__complex__ double __z) 00082 { return __builtin_cacos(__z); } 00083 00084 inline __complex__ long double 00085 __complex_acos(const __complex__ long double& __z) 00086 { return __builtin_cacosl(__z); } 00087 00088 template<typename _Tp> 00089 inline std::complex<_Tp> 00090 acos(const std::complex<_Tp>& __z) 00091 { return __complex_acos(__z.__rep()); } 00092 #else 00093 /// acos(__z) [8.1.2]. 00094 // Effects: Behaves the same as C99 function cacos, defined 00095 // in subclause 7.3.5.1. 00096 template<typename _Tp> 00097 inline std::complex<_Tp> 00098 acos(const std::complex<_Tp>& __z) 00099 { return __complex_acos(__z); } 00100 #endif 00101 00102 template<typename _Tp> 00103 inline std::complex<_Tp> 00104 __complex_asin(const std::complex<_Tp>& __z) 00105 { 00106 std::complex<_Tp> __t(-__z.imag(), __z.real()); 00107 __t = std::tr1::asinh(__t); 00108 return std::complex<_Tp>(__t.imag(), -__t.real()); 00109 } 00110 00111 #if _GLIBCXX_USE_C99_COMPLEX_TR1 00112 inline __complex__ float 00113 __complex_asin(__complex__ float __z) 00114 { return __builtin_casinf(__z); } 00115 00116 inline __complex__ double 00117 __complex_asin(__complex__ double __z) 00118 { return __builtin_casin(__z); } 00119 00120 inline __complex__ long double 00121 __complex_asin(const __complex__ long double& __z) 00122 { return __builtin_casinl(__z); } 00123 00124 template<typename _Tp> 00125 inline std::complex<_Tp> 00126 asin(const std::complex<_Tp>& __z) 00127 { return __complex_asin(__z.__rep()); } 00128 #else 00129 /// asin(__z) [8.1.3]. 00130 // Effects: Behaves the same as C99 function casin, defined 00131 // in subclause 7.3.5.2. 00132 template<typename _Tp> 00133 inline std::complex<_Tp> 00134 asin(const std::complex<_Tp>& __z) 00135 { return __complex_asin(__z); } 00136 #endif 00137 00138 template<typename _Tp> 00139 std::complex<_Tp> 00140 __complex_atan(const std::complex<_Tp>& __z) 00141 { 00142 const _Tp __r2 = __z.real() * __z.real(); 00143 const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); 00144 00145 _Tp __num = __z.imag() + _Tp(1.0); 00146 _Tp __den = __z.imag() - _Tp(1.0); 00147 00148 __num = __r2 + __num * __num; 00149 __den = __r2 + __den * __den; 00150 00151 return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), 00152 _Tp(0.25) * log(__num / __den)); 00153 } 00154 00155 #if _GLIBCXX_USE_C99_COMPLEX_TR1 00156 inline __complex__ float 00157 __complex_atan(__complex__ float __z) 00158 { return __builtin_catanf(__z); } 00159 00160 inline __complex__ double 00161 __complex_atan(__complex__ double __z) 00162 { return __builtin_catan(__z); } 00163 00164 inline __complex__ long double 00165 __complex_atan(const __complex__ long double& __z) 00166 { return __builtin_catanl(__z); } 00167 00168 template<typename _Tp> 00169 inline std::complex<_Tp> 00170 atan(const std::complex<_Tp>& __z) 00171 { return __complex_atan(__z.__rep()); } 00172 #else 00173 /// atan(__z) [8.1.4]. 00174 // Effects: Behaves the same as C99 function catan, defined 00175 // in subclause 7.3.5.3. 00176 template<typename _Tp> 00177 inline std::complex<_Tp> 00178 atan(const std::complex<_Tp>& __z) 00179 { return __complex_atan(__z); } 00180 #endif 00181 00182 #endif // __GXX_EXPERIMENTAL_CXX0X__ 00183 00184 template<typename _Tp> 00185 std::complex<_Tp> 00186 __complex_acosh(const std::complex<_Tp>& __z) 00187 { 00188 std::complex<_Tp> __t((__z.real() - __z.imag()) 00189 * (__z.real() + __z.imag()) - _Tp(1.0), 00190 _Tp(2.0) * __z.real() * __z.imag()); 00191 __t = std::sqrt(__t); 00192 00193 return std::log(__t + __z); 00194 } 00195 00196 #if _GLIBCXX_USE_C99_COMPLEX_TR1 00197 inline __complex__ float 00198 __complex_acosh(__complex__ float __z) 00199 { return __builtin_cacoshf(__z); } 00200 00201 inline __complex__ double 00202 __complex_acosh(__complex__ double __z) 00203 { return __builtin_cacosh(__z); } 00204 00205 inline __complex__ long double 00206 __complex_acosh(const __complex__ long double& __z) 00207 { return __builtin_cacoshl(__z); } 00208 00209 template<typename _Tp> 00210 inline std::complex<_Tp> 00211 acosh(const std::complex<_Tp>& __z) 00212 { return __complex_acosh(__z.__rep()); } 00213 #else 00214 /// acosh(__z) [8.1.5]. 00215 // Effects: Behaves the same as C99 function cacosh, defined 00216 // in subclause 7.3.6.1. 00217 template<typename _Tp> 00218 inline std::complex<_Tp> 00219 acosh(const std::complex<_Tp>& __z) 00220 { return __complex_acosh(__z); } 00221 #endif 00222 00223 template<typename _Tp> 00224 std::complex<_Tp> 00225 __complex_asinh(const std::complex<_Tp>& __z) 00226 { 00227 std::complex<_Tp> __t((__z.real() - __z.imag()) 00228 * (__z.real() + __z.imag()) + _Tp(1.0), 00229 _Tp(2.0) * __z.real() * __z.imag()); 00230 __t = std::sqrt(__t); 00231 00232 return std::log(__t + __z); 00233 } 00234 00235 #if _GLIBCXX_USE_C99_COMPLEX_TR1 00236 inline __complex__ float 00237 __complex_asinh(__complex__ float __z) 00238 { return __builtin_casinhf(__z); } 00239 00240 inline __complex__ double 00241 __complex_asinh(__complex__ double __z) 00242 { return __builtin_casinh(__z); } 00243 00244 inline __complex__ long double 00245 __complex_asinh(const __complex__ long double& __z) 00246 { return __builtin_casinhl(__z); } 00247 00248 template<typename _Tp> 00249 inline std::complex<_Tp> 00250 asinh(const std::complex<_Tp>& __z) 00251 { return __complex_asinh(__z.__rep()); } 00252 #else 00253 /// asinh(__z) [8.1.6]. 00254 // Effects: Behaves the same as C99 function casin, defined 00255 // in subclause 7.3.6.2. 00256 template<typename _Tp> 00257 inline std::complex<_Tp> 00258 asinh(const std::complex<_Tp>& __z) 00259 { return __complex_asinh(__z); } 00260 #endif 00261 00262 template<typename _Tp> 00263 std::complex<_Tp> 00264 __complex_atanh(const std::complex<_Tp>& __z) 00265 { 00266 const _Tp __i2 = __z.imag() * __z.imag(); 00267 const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); 00268 00269 _Tp __num = _Tp(1.0) + __z.real(); 00270 _Tp __den = _Tp(1.0) - __z.real(); 00271 00272 __num = __i2 + __num * __num; 00273 __den = __i2 + __den * __den; 00274 00275 return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), 00276 _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); 00277 } 00278 00279 #if _GLIBCXX_USE_C99_COMPLEX_TR1 00280 inline __complex__ float 00281 __complex_atanh(__complex__ float __z) 00282 { return __builtin_catanhf(__z); } 00283 00284 inline __complex__ double 00285 __complex_atanh(__complex__ double __z) 00286 { return __builtin_catanh(__z); } 00287 00288 inline __complex__ long double 00289 __complex_atanh(const __complex__ long double& __z) 00290 { return __builtin_catanhl(__z); } 00291 00292 template<typename _Tp> 00293 inline std::complex<_Tp> 00294 atanh(const std::complex<_Tp>& __z) 00295 { return __complex_atanh(__z.__rep()); } 00296 #else 00297 /// atanh(__z) [8.1.7]. 00298 // Effects: Behaves the same as C99 function catanh, defined 00299 // in subclause 7.3.6.3. 00300 template<typename _Tp> 00301 inline std::complex<_Tp> 00302 atanh(const std::complex<_Tp>& __z) 00303 { return __complex_atanh(__z); } 00304 #endif 00305 00306 template<typename _Tp> 00307 inline std::complex<_Tp> 00308 /// fabs(__z) [8.1.8]. 00309 // Effects: Behaves the same as C99 function cabs, defined 00310 // in subclause 7.3.8.1. 00311 fabs(const std::complex<_Tp>& __z) 00312 { return std::abs(__z); } 00313 00314 /// Additional overloads [8.1.9]. 00315 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00316 00317 template<typename _Tp> 00318 inline typename __gnu_cxx::__promote<_Tp>::__type 00319 arg(_Tp __x) 00320 { 00321 typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 00322 #if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) 00323 return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L) 00324 : __type(); 00325 #else 00326 return std::arg(std::complex<__type>(__x)); 00327 #endif 00328 } 00329 00330 template<typename _Tp> 00331 inline typename __gnu_cxx::__promote<_Tp>::__type 00332 imag(_Tp) 00333 { return _Tp(); } 00334 00335 template<typename _Tp> 00336 inline typename __gnu_cxx::__promote<_Tp>::__type 00337 norm(_Tp __x) 00338 { 00339 typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 00340 return __type(__x) * __type(__x); 00341 } 00342 00343 template<typename _Tp> 00344 inline typename __gnu_cxx::__promote<_Tp>::__type 00345 real(_Tp __x) 00346 { return __x; } 00347 00348 #endif 00349 00350 template<typename _Tp, typename _Up> 00351 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 00352 pow(const std::complex<_Tp>& __x, const _Up& __y) 00353 { 00354 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 00355 return std::pow(std::complex<__type>(__x), __type(__y)); 00356 } 00357 00358 template<typename _Tp, typename _Up> 00359 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 00360 pow(const _Tp& __x, const std::complex<_Up>& __y) 00361 { 00362 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 00363 return std::pow(__type(__x), std::complex<__type>(__y)); 00364 } 00365 00366 template<typename _Tp, typename _Up> 00367 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 00368 pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) 00369 { 00370 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 00371 return std::pow(std::complex<__type>(__x), 00372 std::complex<__type>(__y)); 00373 } 00374 00375 using std::arg; 00376 00377 template<typename _Tp> 00378 inline std::complex<_Tp> 00379 conj(const std::complex<_Tp>& __z) 00380 { return std::conj(__z); } 00381 00382 template<typename _Tp> 00383 inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type> 00384 conj(_Tp __x) 00385 { return __x; } 00386 00387 using std::imag; 00388 using std::norm; 00389 using std::polar; 00390 00391 template<typename _Tp, typename _Up> 00392 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 00393 polar(const _Tp& __rho, const _Up& __theta) 00394 { 00395 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 00396 return std::polar(__type(__rho), __type(__theta)); 00397 } 00398 00399 using std::real; 00400 00401 template<typename _Tp> 00402 inline std::complex<_Tp> 00403 pow(const std::complex<_Tp>& __x, const _Tp& __y) 00404 { return std::pow(__x, __y); } 00405 00406 template<typename _Tp> 00407 inline std::complex<_Tp> 00408 pow(const _Tp& __x, const std::complex<_Tp>& __y) 00409 { return std::pow(__x, __y); } 00410 00411 template<typename _Tp> 00412 inline std::complex<_Tp> 00413 pow(const std::complex<_Tp>& __x, const std::complex<_Tp>& __y) 00414 { return std::pow(__x, __y); } 00415 00416 // @} group complex_numbers 00417 00418 _GLIBCXX_END_NAMESPACE_VERSION 00419 } 00420 } 00421 00422 #endif // _GLIBCXX_TR1_COMPLEX