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