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