1// TR1 complex -*- C++ -*- 2 3// Copyright (C) 2006 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 2, 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// You should have received a copy of the GNU General Public License along 17// with this library; see the file COPYING. If not, write to the Free 18// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19// USA. 20 21// As a special exception, you may use this file as part of a free software 22// library without restriction. Specifically, if other files instantiate 23// templates or use macros or inline functions from this file, or you compile 24// this file and link it with other files to produce an executable, this 25// file does not by itself cause the resulting executable to be covered by 26// the GNU General Public License. This exception does not however 27// invalidate any other reasons why the executable file might be covered by 28// the GNU General Public License. 29 30/** @file tr1/complex 31 * This is a TR1 C++ Library header. 32 */ 33 34#ifndef _TR1_COMPLEX 35#define _TR1_COMPLEX 1 36 37#include "../complex" 38#include <tr1/common.h> 39 40// namespace std::tr1 41namespace std 42{ 43_GLIBCXX_BEGIN_NAMESPACE(tr1) 44 45 // Forward declarations. 46 template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); 47 template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); 48 template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); 49 50 template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); 51 template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); 52 template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); 53 template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); 54 55 /// @brief acos(__z) [8.1.2]. 56 // Effects: Behaves the same as C99 function cacos, defined 57 // in subclause 7.3.5.1. 58 template<typename _Tp> 59 inline std::complex<_Tp> 60 __complex_acos(const std::complex<_Tp>& __z) 61 { 62 const std::complex<_Tp> __t = std::tr1::asin(__z); 63 const _Tp __pi_2 = 1.5707963267948966192313216916397514L; 64 return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); 65 } 66 67#if _GLIBCXX_USE_C99_COMPLEX_TR1 68 inline __complex__ float 69 __complex_acos(__complex__ float __z) 70 { return __builtin_cacosf(__z); } 71 72 inline __complex__ double 73 __complex_acos(__complex__ double __z) 74 { return __builtin_cacos(__z); } 75 76 inline __complex__ long double 77 __complex_acos(const __complex__ long double& __z) 78 { return __builtin_cacosl(__z); } 79 80 template<typename _Tp> 81 inline std::complex<_Tp> 82 acos(const std::complex<_Tp>& __z) 83 { return __complex_acos(__z.__rep()); } 84#else 85 template<typename _Tp> 86 inline std::complex<_Tp> 87 acos(const std::complex<_Tp>& __z) 88 { return __complex_acos(__z); } 89#endif 90 91 /// @brief asin(__z) [8.1.3]. 92 // Effects: Behaves the same as C99 function casin, defined 93 // in subclause 7.3.5.2. 94 template<typename _Tp> 95 inline std::complex<_Tp> 96 __complex_asin(const std::complex<_Tp>& __z) 97 { 98 std::complex<_Tp> __t(-__z.imag(), __z.real()); 99 __t = std::tr1::asinh(__t); 100 return std::complex<_Tp>(__t.imag(), -__t.real()); 101 } 102 103#if _GLIBCXX_USE_C99_COMPLEX_TR1 104 inline __complex__ float 105 __complex_asin(__complex__ float __z) 106 { return __builtin_casinf(__z); } 107 108 inline __complex__ double 109 __complex_asin(__complex__ double __z) 110 { return __builtin_casin(__z); } 111 112 inline __complex__ long double 113 __complex_asin(const __complex__ long double& __z) 114 { return __builtin_casinl(__z); } 115 116 template<typename _Tp> 117 inline std::complex<_Tp> 118 asin(const std::complex<_Tp>& __z) 119 { return __complex_asin(__z.__rep()); } 120#else 121 template<typename _Tp> 122 inline std::complex<_Tp> 123 asin(const std::complex<_Tp>& __z) 124 { return __complex_asin(__z); } 125#endif 126 127 /// @brief atan(__z) [8.1.4]. 128 // Effects: Behaves the same as C99 function catan, defined 129 // in subclause 7.3.5.3. 130 template<typename _Tp> 131 std::complex<_Tp> 132 __complex_atan(const std::complex<_Tp>& __z) 133 { 134 const _Tp __r2 = __z.real() * __z.real(); 135 const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); 136 137 _Tp __num = __z.imag() + _Tp(1.0); 138 _Tp __den = __z.imag() - _Tp(1.0); 139 140 __num = __r2 + __num * __num; 141 __den = __r2 + __den * __den; 142 143 return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), 144 _Tp(0.25) * log(__num / __den)); 145 } 146 147#if _GLIBCXX_USE_C99_COMPLEX_TR1 148 inline __complex__ float 149 __complex_atan(__complex__ float __z) 150 { return __builtin_catanf(__z); } 151 152 inline __complex__ double 153 __complex_atan(__complex__ double __z) 154 { return __builtin_catan(__z); } 155 156 inline __complex__ long double 157 __complex_atan(const __complex__ long double& __z) 158 { return __builtin_catanl(__z); } 159 160 template<typename _Tp> 161 inline std::complex<_Tp> 162 atan(const std::complex<_Tp>& __z) 163 { return __complex_atan(__z.__rep()); } 164#else 165 template<typename _Tp> 166 inline std::complex<_Tp> 167 atan(const std::complex<_Tp>& __z) 168 { return __complex_atan(__z); } 169#endif 170 171 /// @brief acosh(__z) [8.1.5]. 172 // Effects: Behaves the same as C99 function cacosh, defined 173 // in subclause 7.3.6.1. 174 template<typename _Tp> 175 std::complex<_Tp> 176 __complex_acosh(const std::complex<_Tp>& __z) 177 { 178 std::complex<_Tp> __t((__z.real() - __z.imag()) 179 * (__z.real() + __z.imag()) - _Tp(1.0), 180 _Tp(2.0) * __z.real() * __z.imag()); 181 __t = std::sqrt(__t); 182 183 return std::log(__t + __z); 184 } 185 186#if _GLIBCXX_USE_C99_COMPLEX_TR1 187 inline __complex__ float 188 __complex_acosh(__complex__ float __z) 189 { return __builtin_cacoshf(__z); } 190 191 inline __complex__ double 192 __complex_acosh(__complex__ double __z) 193 { return __builtin_cacosh(__z); } 194 195 inline __complex__ long double 196 __complex_acosh(const __complex__ long double& __z) 197 { return __builtin_cacoshl(__z); } 198 199 template<typename _Tp> 200 inline std::complex<_Tp> 201 acosh(const std::complex<_Tp>& __z) 202 { return __complex_acosh(__z.__rep()); } 203#else 204 template<typename _Tp> 205 inline std::complex<_Tp> 206 acosh(const std::complex<_Tp>& __z) 207 { return __complex_acosh(__z); } 208#endif 209 210 /// @brief asinh(__z) [8.1.6]. 211 // Effects: Behaves the same as C99 function casin, defined 212 // in subclause 7.3.6.2. 213 template<typename _Tp> 214 std::complex<_Tp> 215 __complex_asinh(const std::complex<_Tp>& __z) 216 { 217 std::complex<_Tp> __t((__z.real() - __z.imag()) 218 * (__z.real() + __z.imag()) + _Tp(1.0), 219 _Tp(2.0) * __z.real() * __z.imag()); 220 __t = std::sqrt(__t); 221 222 return std::log(__t + __z); 223 } 224 225#if _GLIBCXX_USE_C99_COMPLEX_TR1 226 inline __complex__ float 227 __complex_asinh(__complex__ float __z) 228 { return __builtin_casinhf(__z); } 229 230 inline __complex__ double 231 __complex_asinh(__complex__ double __z) 232 { return __builtin_casinh(__z); } 233 234 inline __complex__ long double 235 __complex_asinh(const __complex__ long double& __z) 236 { return __builtin_casinhl(__z); } 237 238 template<typename _Tp> 239 inline std::complex<_Tp> 240 asinh(const std::complex<_Tp>& __z) 241 { return __complex_asinh(__z.__rep()); } 242#else 243 template<typename _Tp> 244 inline std::complex<_Tp> 245 asinh(const std::complex<_Tp>& __z) 246 { return __complex_asinh(__z); } 247#endif 248 249 /// @brief atanh(__z) [8.1.7]. 250 // Effects: Behaves the same as C99 function catanh, defined 251 // in subclause 7.3.6.3. 252 template<typename _Tp> 253 std::complex<_Tp> 254 __complex_atanh(const std::complex<_Tp>& __z) 255 { 256 const _Tp __i2 = __z.imag() * __z.imag(); 257 const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); 258 259 _Tp __num = _Tp(1.0) + __z.real(); 260 _Tp __den = _Tp(1.0) - __z.real(); 261 262 __num = __i2 + __num * __num; 263 __den = __i2 + __den * __den; 264 265 return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), 266 _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); 267 } 268 269#if _GLIBCXX_USE_C99_COMPLEX_TR1 270 inline __complex__ float 271 __complex_atanh(__complex__ float __z) 272 { return __builtin_catanhf(__z); } 273 274 inline __complex__ double 275 __complex_atanh(__complex__ double __z) 276 { return __builtin_catanh(__z); } 277 278 inline __complex__ long double 279 __complex_atanh(const __complex__ long double& __z) 280 { return __builtin_catanhl(__z); } 281 282 template<typename _Tp> 283 inline std::complex<_Tp> 284 atanh(const std::complex<_Tp>& __z) 285 { return __complex_atanh(__z.__rep()); } 286#else 287 template<typename _Tp> 288 inline std::complex<_Tp> 289 atanh(const std::complex<_Tp>& __z) 290 { return __complex_atanh(__z); } 291#endif 292 293 /// @brief fabs(__z) [8.1.8]. 294 // Effects: Behaves the same as C99 function cabs, defined 295 // in subclause 7.3.8.1. 296 template<typename _Tp> 297 inline std::complex<_Tp> 298 fabs(const std::complex<_Tp>& __z) 299 { return std::abs(__z); } 300 301 302 /// @brief Additional overloads [8.1.9]. 303 // 304 305 // See common.h for the primary template. 306 template<typename _Tp, typename _Up> 307 struct __promote_2<std::complex<_Tp>, _Up> 308 { 309 public: 310 typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 311 }; 312 313 template<typename _Tp, typename _Up> 314 struct __promote_2<_Tp, std::complex<_Up> > 315 { 316 public: 317 typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 318 }; 319 320 template<typename _Tp, typename _Up> 321 struct __promote_2<std::complex<_Tp>, std::complex<_Up> > 322 { 323 public: 324 typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 325 }; 326 327 328 using std::arg; 329 330 template<typename _Tp> 331 inline typename __promote<_Tp>::__type 332 arg(_Tp __x) 333 { 334 typedef typename __promote<_Tp>::__type __type; 335 return std::arg(std::complex<__type>(__x)); 336 } 337 338 using std::conj; 339 340 template<typename _Tp> 341 inline std::complex<typename __promote<_Tp>::__type> 342 conj(_Tp __x) 343 { return __x; } 344 345 using std::imag; 346 347 template<typename _Tp> 348 inline typename __promote<_Tp>::__type 349 imag(_Tp) 350 { return _Tp(); } 351 352 using std::norm; 353 354 template<typename _Tp> 355 inline typename __promote<_Tp>::__type 356 norm(_Tp __x) 357 { 358 typedef typename __promote<_Tp>::__type __type; 359 return __type(__x) * __type(__x); 360 } 361 362 using std::polar; 363 364 template<typename _Tp, typename _Up> 365 inline std::complex<typename __promote_2<_Tp, _Up>::__type> 366 polar(const _Tp& __rho, const _Up& __theta) 367 { 368 typedef typename __promote_2<_Tp, _Up>::__type __type; 369 return std::polar(__type(__rho), __type(__theta)); 370 } 371 372 using std::pow; 373 374 template<typename _Tp, typename _Up> 375 inline std::complex<typename __promote_2<_Tp, _Up>::__type> 376 pow(const std::complex<_Tp>& __x, const _Up& __y) 377 { 378 typedef typename __promote_2<_Tp, _Up>::__type __type; 379 return std::pow(std::complex<__type>(__x), __type(__y)); 380 } 381 382 template<typename _Tp, typename _Up> 383 inline std::complex<typename __promote_2<_Tp, _Up>::__type> 384 pow(const _Tp& __x, const std::complex<_Up>& __y) 385 { 386 typedef typename __promote_2<_Tp, _Up>::__type __type; 387 return std::pow(__type(__x), std::complex<__type>(__y)); 388 } 389 390 template<typename _Tp, typename _Up> 391 inline std::complex<typename __promote_2<_Tp, _Up>::__type> 392 pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) 393 { 394 typedef typename __promote_2<_Tp, _Up>::__type __type; 395 return std::pow(std::complex<__type>(__x), 396 std::complex<__type>(__y)); 397 } 398 399 using std::real; 400 401 template<typename _Tp> 402 inline typename __promote<_Tp>::__type 403 real(_Tp __x) 404 { return __x; } 405 406_GLIBCXX_END_NAMESPACE 407} 408 409#endif 410