1// TR1 complex -*- C++ -*- 2 3// Copyright (C) 2007, 2008, 2009 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_impl/complex 26 * This is an internal header file, included by other library headers. 27 * You should not attempt to use it directly. 28 */ 29 30namespace std 31{ 32_GLIBCXX_BEGIN_NAMESPACE_TR1 33 34 /** 35 * @addtogroup complex_numbers 36 * @{ 37 */ 38 39 // Forward declarations. 40 template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); 41 template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); 42 template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); 43 44 template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); 45 template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); 46 template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); 47#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 48 // DR 595. 49 template<typename _Tp> _Tp fabs(const std::complex<_Tp>&); 50#else 51 template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); 52#endif 53 54 template<typename _Tp> 55 inline std::complex<_Tp> 56 __complex_acos(const std::complex<_Tp>& __z) 57 { 58 const std::complex<_Tp> __t = std::_GLIBCXX_TR1 asin(__z); 59 const _Tp __pi_2 = 1.5707963267948966192313216916397514L; 60 return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); 61 } 62 63#if _GLIBCXX_USE_C99_COMPLEX_TR1 64 inline __complex__ float 65 __complex_acos(__complex__ float __z) 66 { return __builtin_cacosf(__z); } 67 68 inline __complex__ double 69 __complex_acos(__complex__ double __z) 70 { return __builtin_cacos(__z); } 71 72 inline __complex__ long double 73 __complex_acos(const __complex__ long double& __z) 74 { return __builtin_cacosl(__z); } 75 76 template<typename _Tp> 77 inline std::complex<_Tp> 78 acos(const std::complex<_Tp>& __z) 79 { return __complex_acos(__z.__rep()); } 80#else 81 /// acos(__z) [8.1.2]. 82 // Effects: Behaves the same as C99 function cacos, defined 83 // in subclause 7.3.5.1. 84 template<typename _Tp> 85 inline std::complex<_Tp> 86 acos(const std::complex<_Tp>& __z) 87 { return __complex_acos(__z); } 88#endif 89 90 template<typename _Tp> 91 inline std::complex<_Tp> 92 __complex_asin(const std::complex<_Tp>& __z) 93 { 94 std::complex<_Tp> __t(-__z.imag(), __z.real()); 95 __t = std::_GLIBCXX_TR1 asinh(__t); 96 return std::complex<_Tp>(__t.imag(), -__t.real()); 97 } 98 99#if _GLIBCXX_USE_C99_COMPLEX_TR1 100 inline __complex__ float 101 __complex_asin(__complex__ float __z) 102 { return __builtin_casinf(__z); } 103 104 inline __complex__ double 105 __complex_asin(__complex__ double __z) 106 { return __builtin_casin(__z); } 107 108 inline __complex__ long double 109 __complex_asin(const __complex__ long double& __z) 110 { return __builtin_casinl(__z); } 111 112 template<typename _Tp> 113 inline std::complex<_Tp> 114 asin(const std::complex<_Tp>& __z) 115 { return __complex_asin(__z.__rep()); } 116#else 117 /// asin(__z) [8.1.3]. 118 // Effects: Behaves the same as C99 function casin, defined 119 // in subclause 7.3.5.2. 120 template<typename _Tp> 121 inline std::complex<_Tp> 122 asin(const std::complex<_Tp>& __z) 123 { return __complex_asin(__z); } 124#endif 125 126 template<typename _Tp> 127 std::complex<_Tp> 128 __complex_atan(const std::complex<_Tp>& __z) 129 { 130 const _Tp __r2 = __z.real() * __z.real(); 131 const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); 132 133 _Tp __num = __z.imag() + _Tp(1.0); 134 _Tp __den = __z.imag() - _Tp(1.0); 135 136 __num = __r2 + __num * __num; 137 __den = __r2 + __den * __den; 138 139 return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), 140 _Tp(0.25) * log(__num / __den)); 141 } 142 143#if _GLIBCXX_USE_C99_COMPLEX_TR1 144 inline __complex__ float 145 __complex_atan(__complex__ float __z) 146 { return __builtin_catanf(__z); } 147 148 inline __complex__ double 149 __complex_atan(__complex__ double __z) 150 { return __builtin_catan(__z); } 151 152 inline __complex__ long double 153 __complex_atan(const __complex__ long double& __z) 154 { return __builtin_catanl(__z); } 155 156 template<typename _Tp> 157 inline std::complex<_Tp> 158 atan(const std::complex<_Tp>& __z) 159 { return __complex_atan(__z.__rep()); } 160#else 161 /// atan(__z) [8.1.4]. 162 // Effects: Behaves the same as C99 function catan, defined 163 // in subclause 7.3.5.3. 164 template<typename _Tp> 165 inline std::complex<_Tp> 166 atan(const std::complex<_Tp>& __z) 167 { return __complex_atan(__z); } 168#endif 169 170 template<typename _Tp> 171 std::complex<_Tp> 172 __complex_acosh(const std::complex<_Tp>& __z) 173 { 174 std::complex<_Tp> __t((__z.real() - __z.imag()) 175 * (__z.real() + __z.imag()) - _Tp(1.0), 176 _Tp(2.0) * __z.real() * __z.imag()); 177 __t = std::sqrt(__t); 178 179 return std::log(__t + __z); 180 } 181 182#if _GLIBCXX_USE_C99_COMPLEX_TR1 183 inline __complex__ float 184 __complex_acosh(__complex__ float __z) 185 { return __builtin_cacoshf(__z); } 186 187 inline __complex__ double 188 __complex_acosh(__complex__ double __z) 189 { return __builtin_cacosh(__z); } 190 191 inline __complex__ long double 192 __complex_acosh(const __complex__ long double& __z) 193 { return __builtin_cacoshl(__z); } 194 195 template<typename _Tp> 196 inline std::complex<_Tp> 197 acosh(const std::complex<_Tp>& __z) 198 { return __complex_acosh(__z.__rep()); } 199#else 200 /// acosh(__z) [8.1.5]. 201 // Effects: Behaves the same as C99 function cacosh, defined 202 // in subclause 7.3.6.1. 203 template<typename _Tp> 204 inline std::complex<_Tp> 205 acosh(const std::complex<_Tp>& __z) 206 { return __complex_acosh(__z); } 207#endif 208 209 template<typename _Tp> 210 std::complex<_Tp> 211 __complex_asinh(const std::complex<_Tp>& __z) 212 { 213 std::complex<_Tp> __t((__z.real() - __z.imag()) 214 * (__z.real() + __z.imag()) + _Tp(1.0), 215 _Tp(2.0) * __z.real() * __z.imag()); 216 __t = std::sqrt(__t); 217 218 return std::log(__t + __z); 219 } 220 221#if _GLIBCXX_USE_C99_COMPLEX_TR1 222 inline __complex__ float 223 __complex_asinh(__complex__ float __z) 224 { return __builtin_casinhf(__z); } 225 226 inline __complex__ double 227 __complex_asinh(__complex__ double __z) 228 { return __builtin_casinh(__z); } 229 230 inline __complex__ long double 231 __complex_asinh(const __complex__ long double& __z) 232 { return __builtin_casinhl(__z); } 233 234 template<typename _Tp> 235 inline std::complex<_Tp> 236 asinh(const std::complex<_Tp>& __z) 237 { return __complex_asinh(__z.__rep()); } 238#else 239 /// asinh(__z) [8.1.6]. 240 // Effects: Behaves the same as C99 function casin, defined 241 // in subclause 7.3.6.2. 242 template<typename _Tp> 243 inline std::complex<_Tp> 244 asinh(const std::complex<_Tp>& __z) 245 { return __complex_asinh(__z); } 246#endif 247 248 template<typename _Tp> 249 std::complex<_Tp> 250 __complex_atanh(const std::complex<_Tp>& __z) 251 { 252 const _Tp __i2 = __z.imag() * __z.imag(); 253 const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); 254 255 _Tp __num = _Tp(1.0) + __z.real(); 256 _Tp __den = _Tp(1.0) - __z.real(); 257 258 __num = __i2 + __num * __num; 259 __den = __i2 + __den * __den; 260 261 return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), 262 _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); 263 } 264 265#if _GLIBCXX_USE_C99_COMPLEX_TR1 266 inline __complex__ float 267 __complex_atanh(__complex__ float __z) 268 { return __builtin_catanhf(__z); } 269 270 inline __complex__ double 271 __complex_atanh(__complex__ double __z) 272 { return __builtin_catanh(__z); } 273 274 inline __complex__ long double 275 __complex_atanh(const __complex__ long double& __z) 276 { return __builtin_catanhl(__z); } 277 278 template<typename _Tp> 279 inline std::complex<_Tp> 280 atanh(const std::complex<_Tp>& __z) 281 { return __complex_atanh(__z.__rep()); } 282#else 283 /// atanh(__z) [8.1.7]. 284 // Effects: Behaves the same as C99 function catanh, defined 285 // in subclause 7.3.6.3. 286 template<typename _Tp> 287 inline std::complex<_Tp> 288 atanh(const std::complex<_Tp>& __z) 289 { return __complex_atanh(__z); } 290#endif 291 292 template<typename _Tp> 293#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 294 inline _Tp 295#else 296 inline std::complex<_Tp> 297#endif 298 /// fabs(__z) [8.1.8]. 299 // Effects: Behaves the same as C99 function cabs, defined 300 // in subclause 7.3.8.1. 301 fabs(const std::complex<_Tp>& __z) 302 { return std::abs(__z); } 303 304 /// Additional overloads [8.1.9]. 305#if (defined(_GLIBCXX_INCLUDE_AS_CXX0X) \ 306 || (defined(_GLIBCXX_INCLUDE_AS_TR1) \ 307 && !defined(__GXX_EXPERIMENTAL_CXX0X__))) 308 309 template<typename _Tp> 310 inline typename __gnu_cxx::__promote<_Tp>::__type 311 arg(_Tp __x) 312 { 313 typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 314 return std::arg(std::complex<__type>(__x)); 315 } 316 317 template<typename _Tp> 318 inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type> 319 conj(_Tp __x) 320 { return __x; } 321 322 template<typename _Tp> 323 inline typename __gnu_cxx::__promote<_Tp>::__type 324 imag(_Tp) 325 { return _Tp(); } 326 327 template<typename _Tp> 328 inline typename __gnu_cxx::__promote<_Tp>::__type 329 norm(_Tp __x) 330 { 331 typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 332 return __type(__x) * __type(__x); 333 } 334 335 template<typename _Tp> 336 inline typename __gnu_cxx::__promote<_Tp>::__type 337 real(_Tp __x) 338 { return __x; } 339 340#endif 341 342 template<typename _Tp, typename _Up> 343 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 344 pow(const std::complex<_Tp>& __x, const _Up& __y) 345 { 346 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 347 return std::pow(std::complex<__type>(__x), __type(__y)); 348 } 349 350 template<typename _Tp, typename _Up> 351 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 352 pow(const _Tp& __x, const std::complex<_Up>& __y) 353 { 354 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 355 return std::pow(__type(__x), std::complex<__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 std::complex<_Tp>& __x, const std::complex<_Up>& __y) 361 { 362 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 363 return std::pow(std::complex<__type>(__x), 364 std::complex<__type>(__y)); 365 } 366 367 // @} group complex_numbers 368 369_GLIBCXX_END_NAMESPACE_TR1 370} 371