1 1.1 mrg // TR1 complex -*- C++ -*- 2 1.1 mrg 3 1.12 mrg // Copyright (C) 2006-2022 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /** @file tr1/complex 26 1.1 mrg * This is a TR1 C++ Library header. 27 1.1 mrg */ 28 1.1 mrg 29 1.1 mrg #ifndef _GLIBCXX_TR1_COMPLEX 30 1.1 mrg #define _GLIBCXX_TR1_COMPLEX 1 31 1.1 mrg 32 1.1 mrg #pragma GCC system_header 33 1.1 mrg 34 1.3 mrg #include <complex> 35 1.3 mrg 36 1.3 mrg namespace std _GLIBCXX_VISIBILITY(default) 37 1.3 mrg { 38 1.9 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 39 1.9 mrg 40 1.3 mrg namespace tr1 41 1.3 mrg { 42 1.3 mrg /** 43 1.3 mrg * @addtogroup complex_numbers 44 1.3 mrg * @{ 45 1.3 mrg */ 46 1.3 mrg 47 1.3 mrg #if __cplusplus >= 201103L 48 1.3 mrg using std::acos; 49 1.3 mrg using std::asin; 50 1.3 mrg using std::atan; 51 1.6 mrg using std::acosh; 52 1.6 mrg using std::asinh; 53 1.6 mrg using std::atanh; 54 1.3 mrg #else 55 1.3 mrg template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); 56 1.3 mrg template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); 57 1.3 mrg template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); 58 1.3 mrg template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); 59 1.3 mrg template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); 60 1.3 mrg template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); 61 1.6 mrg #endif 62 1.3 mrg 63 1.6 mrg // The std::fabs return type in C++11 mode is different (just _Tp). 64 1.3 mrg template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); 65 1.3 mrg 66 1.3 mrg #if __cplusplus < 201103L 67 1.3 mrg template<typename _Tp> 68 1.3 mrg inline std::complex<_Tp> 69 1.3 mrg __complex_acos(const std::complex<_Tp>& __z) 70 1.3 mrg { 71 1.3 mrg const std::complex<_Tp> __t = std::tr1::asin(__z); 72 1.3 mrg const _Tp __pi_2 = 1.5707963267948966192313216916397514L; 73 1.3 mrg return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); 74 1.3 mrg } 75 1.3 mrg 76 1.3 mrg #if _GLIBCXX_USE_C99_COMPLEX_TR1 77 1.3 mrg inline __complex__ float 78 1.3 mrg __complex_acos(__complex__ float __z) 79 1.3 mrg { return __builtin_cacosf(__z); } 80 1.3 mrg 81 1.3 mrg inline __complex__ double 82 1.3 mrg __complex_acos(__complex__ double __z) 83 1.3 mrg { return __builtin_cacos(__z); } 84 1.3 mrg 85 1.3 mrg inline __complex__ long double 86 1.3 mrg __complex_acos(const __complex__ long double& __z) 87 1.3 mrg { return __builtin_cacosl(__z); } 88 1.3 mrg 89 1.3 mrg template<typename _Tp> 90 1.3 mrg inline std::complex<_Tp> 91 1.3 mrg acos(const std::complex<_Tp>& __z) 92 1.3 mrg { return __complex_acos(__z.__rep()); } 93 1.3 mrg #else 94 1.3 mrg /// acos(__z) [8.1.2]. 95 1.3 mrg // Effects: Behaves the same as C99 function cacos, defined 96 1.3 mrg // in subclause 7.3.5.1. 97 1.3 mrg template<typename _Tp> 98 1.3 mrg inline std::complex<_Tp> 99 1.3 mrg acos(const std::complex<_Tp>& __z) 100 1.3 mrg { return __complex_acos(__z); } 101 1.3 mrg #endif 102 1.3 mrg 103 1.3 mrg template<typename _Tp> 104 1.3 mrg inline std::complex<_Tp> 105 1.3 mrg __complex_asin(const std::complex<_Tp>& __z) 106 1.3 mrg { 107 1.3 mrg std::complex<_Tp> __t(-__z.imag(), __z.real()); 108 1.3 mrg __t = std::tr1::asinh(__t); 109 1.3 mrg return std::complex<_Tp>(__t.imag(), -__t.real()); 110 1.3 mrg } 111 1.3 mrg 112 1.3 mrg #if _GLIBCXX_USE_C99_COMPLEX_TR1 113 1.3 mrg inline __complex__ float 114 1.3 mrg __complex_asin(__complex__ float __z) 115 1.3 mrg { return __builtin_casinf(__z); } 116 1.3 mrg 117 1.3 mrg inline __complex__ double 118 1.3 mrg __complex_asin(__complex__ double __z) 119 1.3 mrg { return __builtin_casin(__z); } 120 1.3 mrg 121 1.3 mrg inline __complex__ long double 122 1.3 mrg __complex_asin(const __complex__ long double& __z) 123 1.3 mrg { return __builtin_casinl(__z); } 124 1.3 mrg 125 1.3 mrg template<typename _Tp> 126 1.3 mrg inline std::complex<_Tp> 127 1.3 mrg asin(const std::complex<_Tp>& __z) 128 1.3 mrg { return __complex_asin(__z.__rep()); } 129 1.3 mrg #else 130 1.3 mrg /// asin(__z) [8.1.3]. 131 1.3 mrg // Effects: Behaves the same as C99 function casin, defined 132 1.3 mrg // in subclause 7.3.5.2. 133 1.3 mrg template<typename _Tp> 134 1.3 mrg inline std::complex<_Tp> 135 1.3 mrg asin(const std::complex<_Tp>& __z) 136 1.3 mrg { return __complex_asin(__z); } 137 1.1 mrg #endif 138 1.3 mrg 139 1.3 mrg template<typename _Tp> 140 1.3 mrg std::complex<_Tp> 141 1.3 mrg __complex_atan(const std::complex<_Tp>& __z) 142 1.3 mrg { 143 1.3 mrg const _Tp __r2 = __z.real() * __z.real(); 144 1.3 mrg const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); 145 1.3 mrg 146 1.3 mrg _Tp __num = __z.imag() + _Tp(1.0); 147 1.3 mrg _Tp __den = __z.imag() - _Tp(1.0); 148 1.3 mrg 149 1.3 mrg __num = __r2 + __num * __num; 150 1.3 mrg __den = __r2 + __den * __den; 151 1.3 mrg 152 1.3 mrg return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), 153 1.3 mrg _Tp(0.25) * log(__num / __den)); 154 1.3 mrg } 155 1.3 mrg 156 1.3 mrg #if _GLIBCXX_USE_C99_COMPLEX_TR1 157 1.3 mrg inline __complex__ float 158 1.3 mrg __complex_atan(__complex__ float __z) 159 1.3 mrg { return __builtin_catanf(__z); } 160 1.3 mrg 161 1.3 mrg inline __complex__ double 162 1.3 mrg __complex_atan(__complex__ double __z) 163 1.3 mrg { return __builtin_catan(__z); } 164 1.3 mrg 165 1.3 mrg inline __complex__ long double 166 1.3 mrg __complex_atan(const __complex__ long double& __z) 167 1.3 mrg { return __builtin_catanl(__z); } 168 1.3 mrg 169 1.3 mrg template<typename _Tp> 170 1.3 mrg inline std::complex<_Tp> 171 1.3 mrg atan(const std::complex<_Tp>& __z) 172 1.3 mrg { return __complex_atan(__z.__rep()); } 173 1.3 mrg #else 174 1.3 mrg /// atan(__z) [8.1.4]. 175 1.3 mrg // Effects: Behaves the same as C99 function catan, defined 176 1.3 mrg // in subclause 7.3.5.3. 177 1.3 mrg template<typename _Tp> 178 1.3 mrg inline std::complex<_Tp> 179 1.3 mrg atan(const std::complex<_Tp>& __z) 180 1.3 mrg { return __complex_atan(__z); } 181 1.3 mrg #endif 182 1.3 mrg 183 1.3 mrg template<typename _Tp> 184 1.3 mrg std::complex<_Tp> 185 1.3 mrg __complex_acosh(const std::complex<_Tp>& __z) 186 1.3 mrg { 187 1.3 mrg // Kahan's formula. 188 1.3 mrg return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0))) 189 1.3 mrg + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0)))); 190 1.3 mrg } 191 1.3 mrg 192 1.3 mrg #if _GLIBCXX_USE_C99_COMPLEX_TR1 193 1.3 mrg inline __complex__ float 194 1.3 mrg __complex_acosh(__complex__ float __z) 195 1.3 mrg { return __builtin_cacoshf(__z); } 196 1.3 mrg 197 1.3 mrg inline __complex__ double 198 1.3 mrg __complex_acosh(__complex__ double __z) 199 1.3 mrg { return __builtin_cacosh(__z); } 200 1.3 mrg 201 1.3 mrg inline __complex__ long double 202 1.3 mrg __complex_acosh(const __complex__ long double& __z) 203 1.3 mrg { return __builtin_cacoshl(__z); } 204 1.3 mrg 205 1.3 mrg template<typename _Tp> 206 1.3 mrg inline std::complex<_Tp> 207 1.3 mrg acosh(const std::complex<_Tp>& __z) 208 1.3 mrg { return __complex_acosh(__z.__rep()); } 209 1.3 mrg #else 210 1.3 mrg /// acosh(__z) [8.1.5]. 211 1.3 mrg // Effects: Behaves the same as C99 function cacosh, defined 212 1.3 mrg // in subclause 7.3.6.1. 213 1.3 mrg template<typename _Tp> 214 1.3 mrg inline std::complex<_Tp> 215 1.3 mrg acosh(const std::complex<_Tp>& __z) 216 1.3 mrg { return __complex_acosh(__z); } 217 1.3 mrg #endif 218 1.3 mrg 219 1.3 mrg template<typename _Tp> 220 1.3 mrg std::complex<_Tp> 221 1.3 mrg __complex_asinh(const std::complex<_Tp>& __z) 222 1.3 mrg { 223 1.3 mrg std::complex<_Tp> __t((__z.real() - __z.imag()) 224 1.3 mrg * (__z.real() + __z.imag()) + _Tp(1.0), 225 1.3 mrg _Tp(2.0) * __z.real() * __z.imag()); 226 1.3 mrg __t = std::sqrt(__t); 227 1.3 mrg 228 1.3 mrg return std::log(__t + __z); 229 1.3 mrg } 230 1.3 mrg 231 1.3 mrg #if _GLIBCXX_USE_C99_COMPLEX_TR1 232 1.3 mrg inline __complex__ float 233 1.3 mrg __complex_asinh(__complex__ float __z) 234 1.3 mrg { return __builtin_casinhf(__z); } 235 1.3 mrg 236 1.3 mrg inline __complex__ double 237 1.3 mrg __complex_asinh(__complex__ double __z) 238 1.3 mrg { return __builtin_casinh(__z); } 239 1.3 mrg 240 1.3 mrg inline __complex__ long double 241 1.3 mrg __complex_asinh(const __complex__ long double& __z) 242 1.3 mrg { return __builtin_casinhl(__z); } 243 1.3 mrg 244 1.3 mrg template<typename _Tp> 245 1.3 mrg inline std::complex<_Tp> 246 1.3 mrg asinh(const std::complex<_Tp>& __z) 247 1.3 mrg { return __complex_asinh(__z.__rep()); } 248 1.3 mrg #else 249 1.3 mrg /// asinh(__z) [8.1.6]. 250 1.3 mrg // Effects: Behaves the same as C99 function casin, defined 251 1.3 mrg // in subclause 7.3.6.2. 252 1.3 mrg template<typename _Tp> 253 1.3 mrg inline std::complex<_Tp> 254 1.3 mrg asinh(const std::complex<_Tp>& __z) 255 1.3 mrg { return __complex_asinh(__z); } 256 1.3 mrg #endif 257 1.3 mrg 258 1.3 mrg template<typename _Tp> 259 1.3 mrg std::complex<_Tp> 260 1.3 mrg __complex_atanh(const std::complex<_Tp>& __z) 261 1.3 mrg { 262 1.3 mrg const _Tp __i2 = __z.imag() * __z.imag(); 263 1.3 mrg const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); 264 1.3 mrg 265 1.3 mrg _Tp __num = _Tp(1.0) + __z.real(); 266 1.3 mrg _Tp __den = _Tp(1.0) - __z.real(); 267 1.3 mrg 268 1.3 mrg __num = __i2 + __num * __num; 269 1.3 mrg __den = __i2 + __den * __den; 270 1.3 mrg 271 1.3 mrg return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), 272 1.3 mrg _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); 273 1.3 mrg } 274 1.3 mrg 275 1.3 mrg #if _GLIBCXX_USE_C99_COMPLEX_TR1 276 1.3 mrg inline __complex__ float 277 1.3 mrg __complex_atanh(__complex__ float __z) 278 1.3 mrg { return __builtin_catanhf(__z); } 279 1.3 mrg 280 1.3 mrg inline __complex__ double 281 1.3 mrg __complex_atanh(__complex__ double __z) 282 1.3 mrg { return __builtin_catanh(__z); } 283 1.3 mrg 284 1.3 mrg inline __complex__ long double 285 1.3 mrg __complex_atanh(const __complex__ long double& __z) 286 1.3 mrg { return __builtin_catanhl(__z); } 287 1.3 mrg 288 1.3 mrg template<typename _Tp> 289 1.3 mrg inline std::complex<_Tp> 290 1.3 mrg atanh(const std::complex<_Tp>& __z) 291 1.3 mrg { return __complex_atanh(__z.__rep()); } 292 1.3 mrg #else 293 1.3 mrg /// atanh(__z) [8.1.7]. 294 1.3 mrg // Effects: Behaves the same as C99 function catanh, defined 295 1.3 mrg // in subclause 7.3.6.3. 296 1.3 mrg template<typename _Tp> 297 1.3 mrg inline std::complex<_Tp> 298 1.3 mrg atanh(const std::complex<_Tp>& __z) 299 1.3 mrg { return __complex_atanh(__z); } 300 1.3 mrg #endif 301 1.3 mrg 302 1.6 mrg #endif // C++11 303 1.6 mrg 304 1.3 mrg template<typename _Tp> 305 1.3 mrg inline std::complex<_Tp> 306 1.3 mrg /// fabs(__z) [8.1.8]. 307 1.3 mrg // Effects: Behaves the same as C99 function cabs, defined 308 1.3 mrg // in subclause 7.3.8.1. 309 1.3 mrg fabs(const std::complex<_Tp>& __z) 310 1.3 mrg { return std::abs(__z); } 311 1.3 mrg 312 1.3 mrg /// Additional overloads [8.1.9]. 313 1.3 mrg #if __cplusplus < 201103L 314 1.1 mrg 315 1.3 mrg template<typename _Tp> 316 1.3 mrg inline typename __gnu_cxx::__promote<_Tp>::__type 317 1.3 mrg arg(_Tp __x) 318 1.3 mrg { 319 1.3 mrg typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 320 1.3 mrg #if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) 321 1.3 mrg return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L) 322 1.3 mrg : __type(); 323 1.1 mrg #else 324 1.3 mrg return std::arg(std::complex<__type>(__x)); 325 1.1 mrg #endif 326 1.3 mrg } 327 1.3 mrg 328 1.3 mrg template<typename _Tp> 329 1.3 mrg inline typename __gnu_cxx::__promote<_Tp>::__type 330 1.3 mrg imag(_Tp) 331 1.3 mrg { return _Tp(); } 332 1.3 mrg 333 1.3 mrg template<typename _Tp> 334 1.3 mrg inline typename __gnu_cxx::__promote<_Tp>::__type 335 1.3 mrg norm(_Tp __x) 336 1.3 mrg { 337 1.3 mrg typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 338 1.3 mrg return __type(__x) * __type(__x); 339 1.3 mrg } 340 1.3 mrg 341 1.3 mrg template<typename _Tp> 342 1.3 mrg inline typename __gnu_cxx::__promote<_Tp>::__type 343 1.3 mrg real(_Tp __x) 344 1.3 mrg { return __x; } 345 1.3 mrg 346 1.3 mrg #endif 347 1.3 mrg 348 1.3 mrg template<typename _Tp, typename _Up> 349 1.3 mrg inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 350 1.3 mrg pow(const std::complex<_Tp>& __x, const _Up& __y) 351 1.3 mrg { 352 1.3 mrg typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 353 1.3 mrg return std::pow(std::complex<__type>(__x), __type(__y)); 354 1.3 mrg } 355 1.3 mrg 356 1.3 mrg template<typename _Tp, typename _Up> 357 1.3 mrg inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 358 1.3 mrg pow(const _Tp& __x, const std::complex<_Up>& __y) 359 1.3 mrg { 360 1.3 mrg typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 361 1.3 mrg return std::pow(__type(__x), std::complex<__type>(__y)); 362 1.3 mrg } 363 1.3 mrg 364 1.3 mrg template<typename _Tp, typename _Up> 365 1.3 mrg inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 366 1.3 mrg pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) 367 1.3 mrg { 368 1.3 mrg typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 369 1.3 mrg return std::pow(std::complex<__type>(__x), 370 1.3 mrg std::complex<__type>(__y)); 371 1.3 mrg } 372 1.1 mrg 373 1.1 mrg using std::arg; 374 1.1 mrg 375 1.1 mrg template<typename _Tp> 376 1.1 mrg inline std::complex<_Tp> 377 1.1 mrg conj(const std::complex<_Tp>& __z) 378 1.8 mrg { return std::conj(__z); } 379 1.1 mrg 380 1.1 mrg template<typename _Tp> 381 1.1 mrg inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type> 382 1.1 mrg conj(_Tp __x) 383 1.1 mrg { return __x; } 384 1.1 mrg 385 1.1 mrg using std::imag; 386 1.1 mrg using std::norm; 387 1.1 mrg using std::polar; 388 1.1 mrg 389 1.1 mrg template<typename _Tp, typename _Up> 390 1.1 mrg inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 391 1.1 mrg polar(const _Tp& __rho, const _Up& __theta) 392 1.1 mrg { 393 1.1 mrg typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 394 1.1 mrg return std::polar(__type(__rho), __type(__theta)); 395 1.1 mrg } 396 1.1 mrg 397 1.1 mrg using std::real; 398 1.1 mrg 399 1.1 mrg template<typename _Tp> 400 1.1 mrg inline std::complex<_Tp> 401 1.1 mrg pow(const std::complex<_Tp>& __x, const _Tp& __y) 402 1.1 mrg { return std::pow(__x, __y); } 403 1.1 mrg 404 1.1 mrg template<typename _Tp> 405 1.1 mrg inline std::complex<_Tp> 406 1.1 mrg pow(const _Tp& __x, const std::complex<_Tp>& __y) 407 1.1 mrg { return std::pow(__x, __y); } 408 1.1 mrg 409 1.1 mrg template<typename _Tp> 410 1.1 mrg inline std::complex<_Tp> 411 1.1 mrg pow(const std::complex<_Tp>& __x, const std::complex<_Tp>& __y) 412 1.1 mrg { return std::pow(__x, __y); } 413 1.3 mrg 414 1.11 mrg /// @} group complex_numbers 415 1.9 mrg } 416 1.3 mrg 417 1.3 mrg _GLIBCXX_END_NAMESPACE_VERSION 418 1.1 mrg } 419 1.1 mrg 420 1.1 mrg #endif // _GLIBCXX_TR1_COMPLEX 421