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