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