1169691Skan// TR1 complex -*- C++ -*- 2169691Skan 3169691Skan// Copyright (C) 2006 Free Software Foundation, Inc. 4169691Skan// 5169691Skan// This file is part of the GNU ISO C++ Library. This library is free 6169691Skan// software; you can redistribute it and/or modify it under the 7169691Skan// terms of the GNU General Public License as published by the 8169691Skan// Free Software Foundation; either version 2, or (at your option) 9169691Skan// any later version. 10169691Skan 11169691Skan// This library is distributed in the hope that it will be useful, 12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169691Skan// GNU General Public License for more details. 15169691Skan 16169691Skan// You should have received a copy of the GNU General Public License along 17169691Skan// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19169691Skan// USA. 20169691Skan 21169691Skan// As a special exception, you may use this file as part of a free software 22169691Skan// library without restriction. Specifically, if other files instantiate 23169691Skan// templates or use macros or inline functions from this file, or you compile 24169691Skan// this file and link it with other files to produce an executable, this 25169691Skan// file does not by itself cause the resulting executable to be covered by 26169691Skan// the GNU General Public License. This exception does not however 27169691Skan// invalidate any other reasons why the executable file might be covered by 28169691Skan// the GNU General Public License. 29169691Skan 30169691Skan/** @file tr1/complex 31169691Skan * This is a TR1 C++ Library header. 32169691Skan */ 33169691Skan 34169691Skan#ifndef _TR1_COMPLEX 35169691Skan#define _TR1_COMPLEX 1 36169691Skan 37169691Skan#include "../complex" 38169691Skan#include <tr1/common.h> 39169691Skan 40169691Skan// namespace std::tr1 41169691Skannamespace std 42169691Skan{ 43169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1) 44169691Skan 45169691Skan // Forward declarations. 46169691Skan template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); 47169691Skan template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); 48169691Skan template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); 49169691Skan 50169691Skan template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); 51169691Skan template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); 52169691Skan template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); 53169691Skan template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); 54169691Skan 55169691Skan /// @brief acos(__z) [8.1.2]. 56169691Skan // Effects: Behaves the same as C99 function cacos, defined 57169691Skan // in subclause 7.3.5.1. 58169691Skan template<typename _Tp> 59169691Skan inline std::complex<_Tp> 60169691Skan __complex_acos(const std::complex<_Tp>& __z) 61169691Skan { 62169691Skan const std::complex<_Tp> __t = std::tr1::asin(__z); 63169691Skan const _Tp __pi_2 = 1.5707963267948966192313216916397514L; 64169691Skan return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); 65169691Skan } 66169691Skan 67169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1 68169691Skan inline __complex__ float 69169691Skan __complex_acos(__complex__ float __z) 70169691Skan { return __builtin_cacosf(__z); } 71169691Skan 72169691Skan inline __complex__ double 73169691Skan __complex_acos(__complex__ double __z) 74169691Skan { return __builtin_cacos(__z); } 75169691Skan 76169691Skan inline __complex__ long double 77169691Skan __complex_acos(const __complex__ long double& __z) 78169691Skan { return __builtin_cacosl(__z); } 79169691Skan 80169691Skan template<typename _Tp> 81169691Skan inline std::complex<_Tp> 82169691Skan acos(const std::complex<_Tp>& __z) 83169691Skan { return __complex_acos(__z.__rep()); } 84169691Skan#else 85169691Skan template<typename _Tp> 86169691Skan inline std::complex<_Tp> 87169691Skan acos(const std::complex<_Tp>& __z) 88169691Skan { return __complex_acos(__z); } 89169691Skan#endif 90169691Skan 91169691Skan /// @brief asin(__z) [8.1.3]. 92169691Skan // Effects: Behaves the same as C99 function casin, defined 93169691Skan // in subclause 7.3.5.2. 94169691Skan template<typename _Tp> 95169691Skan inline std::complex<_Tp> 96169691Skan __complex_asin(const std::complex<_Tp>& __z) 97169691Skan { 98169691Skan std::complex<_Tp> __t(-__z.imag(), __z.real()); 99169691Skan __t = std::tr1::asinh(__t); 100169691Skan return std::complex<_Tp>(__t.imag(), -__t.real()); 101169691Skan } 102169691Skan 103169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1 104169691Skan inline __complex__ float 105169691Skan __complex_asin(__complex__ float __z) 106169691Skan { return __builtin_casinf(__z); } 107169691Skan 108169691Skan inline __complex__ double 109169691Skan __complex_asin(__complex__ double __z) 110169691Skan { return __builtin_casin(__z); } 111169691Skan 112169691Skan inline __complex__ long double 113169691Skan __complex_asin(const __complex__ long double& __z) 114169691Skan { return __builtin_casinl(__z); } 115169691Skan 116169691Skan template<typename _Tp> 117169691Skan inline std::complex<_Tp> 118169691Skan asin(const std::complex<_Tp>& __z) 119169691Skan { return __complex_asin(__z.__rep()); } 120169691Skan#else 121169691Skan template<typename _Tp> 122169691Skan inline std::complex<_Tp> 123169691Skan asin(const std::complex<_Tp>& __z) 124169691Skan { return __complex_asin(__z); } 125169691Skan#endif 126169691Skan 127169691Skan /// @brief atan(__z) [8.1.4]. 128169691Skan // Effects: Behaves the same as C99 function catan, defined 129169691Skan // in subclause 7.3.5.3. 130169691Skan template<typename _Tp> 131169691Skan std::complex<_Tp> 132169691Skan __complex_atan(const std::complex<_Tp>& __z) 133169691Skan { 134169691Skan const _Tp __r2 = __z.real() * __z.real(); 135169691Skan const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); 136169691Skan 137169691Skan _Tp __num = __z.imag() + _Tp(1.0); 138169691Skan _Tp __den = __z.imag() - _Tp(1.0); 139169691Skan 140169691Skan __num = __r2 + __num * __num; 141169691Skan __den = __r2 + __den * __den; 142169691Skan 143169691Skan return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), 144169691Skan _Tp(0.25) * log(__num / __den)); 145169691Skan } 146169691Skan 147169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1 148169691Skan inline __complex__ float 149169691Skan __complex_atan(__complex__ float __z) 150169691Skan { return __builtin_catanf(__z); } 151169691Skan 152169691Skan inline __complex__ double 153169691Skan __complex_atan(__complex__ double __z) 154169691Skan { return __builtin_catan(__z); } 155169691Skan 156169691Skan inline __complex__ long double 157169691Skan __complex_atan(const __complex__ long double& __z) 158169691Skan { return __builtin_catanl(__z); } 159169691Skan 160169691Skan template<typename _Tp> 161169691Skan inline std::complex<_Tp> 162169691Skan atan(const std::complex<_Tp>& __z) 163169691Skan { return __complex_atan(__z.__rep()); } 164169691Skan#else 165169691Skan template<typename _Tp> 166169691Skan inline std::complex<_Tp> 167169691Skan atan(const std::complex<_Tp>& __z) 168169691Skan { return __complex_atan(__z); } 169169691Skan#endif 170169691Skan 171169691Skan /// @brief acosh(__z) [8.1.5]. 172169691Skan // Effects: Behaves the same as C99 function cacosh, defined 173169691Skan // in subclause 7.3.6.1. 174169691Skan template<typename _Tp> 175169691Skan std::complex<_Tp> 176169691Skan __complex_acosh(const std::complex<_Tp>& __z) 177169691Skan { 178169691Skan std::complex<_Tp> __t((__z.real() - __z.imag()) 179169691Skan * (__z.real() + __z.imag()) - _Tp(1.0), 180169691Skan _Tp(2.0) * __z.real() * __z.imag()); 181169691Skan __t = std::sqrt(__t); 182169691Skan 183169691Skan return std::log(__t + __z); 184169691Skan } 185169691Skan 186169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1 187169691Skan inline __complex__ float 188169691Skan __complex_acosh(__complex__ float __z) 189169691Skan { return __builtin_cacoshf(__z); } 190169691Skan 191169691Skan inline __complex__ double 192169691Skan __complex_acosh(__complex__ double __z) 193169691Skan { return __builtin_cacosh(__z); } 194169691Skan 195169691Skan inline __complex__ long double 196169691Skan __complex_acosh(const __complex__ long double& __z) 197169691Skan { return __builtin_cacoshl(__z); } 198169691Skan 199169691Skan template<typename _Tp> 200169691Skan inline std::complex<_Tp> 201169691Skan acosh(const std::complex<_Tp>& __z) 202169691Skan { return __complex_acosh(__z.__rep()); } 203169691Skan#else 204169691Skan template<typename _Tp> 205169691Skan inline std::complex<_Tp> 206169691Skan acosh(const std::complex<_Tp>& __z) 207169691Skan { return __complex_acosh(__z); } 208169691Skan#endif 209169691Skan 210169691Skan /// @brief asinh(__z) [8.1.6]. 211169691Skan // Effects: Behaves the same as C99 function casin, defined 212169691Skan // in subclause 7.3.6.2. 213169691Skan template<typename _Tp> 214169691Skan std::complex<_Tp> 215169691Skan __complex_asinh(const std::complex<_Tp>& __z) 216169691Skan { 217169691Skan std::complex<_Tp> __t((__z.real() - __z.imag()) 218169691Skan * (__z.real() + __z.imag()) + _Tp(1.0), 219169691Skan _Tp(2.0) * __z.real() * __z.imag()); 220169691Skan __t = std::sqrt(__t); 221169691Skan 222169691Skan return std::log(__t + __z); 223169691Skan } 224169691Skan 225169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1 226169691Skan inline __complex__ float 227169691Skan __complex_asinh(__complex__ float __z) 228169691Skan { return __builtin_casinhf(__z); } 229169691Skan 230169691Skan inline __complex__ double 231169691Skan __complex_asinh(__complex__ double __z) 232169691Skan { return __builtin_casinh(__z); } 233169691Skan 234169691Skan inline __complex__ long double 235169691Skan __complex_asinh(const __complex__ long double& __z) 236169691Skan { return __builtin_casinhl(__z); } 237169691Skan 238169691Skan template<typename _Tp> 239169691Skan inline std::complex<_Tp> 240169691Skan asinh(const std::complex<_Tp>& __z) 241169691Skan { return __complex_asinh(__z.__rep()); } 242169691Skan#else 243169691Skan template<typename _Tp> 244169691Skan inline std::complex<_Tp> 245169691Skan asinh(const std::complex<_Tp>& __z) 246169691Skan { return __complex_asinh(__z); } 247169691Skan#endif 248169691Skan 249169691Skan /// @brief atanh(__z) [8.1.7]. 250169691Skan // Effects: Behaves the same as C99 function catanh, defined 251169691Skan // in subclause 7.3.6.3. 252169691Skan template<typename _Tp> 253169691Skan std::complex<_Tp> 254169691Skan __complex_atanh(const std::complex<_Tp>& __z) 255169691Skan { 256169691Skan const _Tp __i2 = __z.imag() * __z.imag(); 257169691Skan const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); 258169691Skan 259169691Skan _Tp __num = _Tp(1.0) + __z.real(); 260169691Skan _Tp __den = _Tp(1.0) - __z.real(); 261169691Skan 262169691Skan __num = __i2 + __num * __num; 263169691Skan __den = __i2 + __den * __den; 264169691Skan 265169691Skan return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), 266169691Skan _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); 267169691Skan } 268169691Skan 269169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1 270169691Skan inline __complex__ float 271169691Skan __complex_atanh(__complex__ float __z) 272169691Skan { return __builtin_catanhf(__z); } 273169691Skan 274169691Skan inline __complex__ double 275169691Skan __complex_atanh(__complex__ double __z) 276169691Skan { return __builtin_catanh(__z); } 277169691Skan 278169691Skan inline __complex__ long double 279169691Skan __complex_atanh(const __complex__ long double& __z) 280169691Skan { return __builtin_catanhl(__z); } 281169691Skan 282169691Skan template<typename _Tp> 283169691Skan inline std::complex<_Tp> 284169691Skan atanh(const std::complex<_Tp>& __z) 285169691Skan { return __complex_atanh(__z.__rep()); } 286169691Skan#else 287169691Skan template<typename _Tp> 288169691Skan inline std::complex<_Tp> 289169691Skan atanh(const std::complex<_Tp>& __z) 290169691Skan { return __complex_atanh(__z); } 291169691Skan#endif 292169691Skan 293169691Skan /// @brief fabs(__z) [8.1.8]. 294169691Skan // Effects: Behaves the same as C99 function cabs, defined 295169691Skan // in subclause 7.3.8.1. 296169691Skan template<typename _Tp> 297169691Skan inline std::complex<_Tp> 298169691Skan fabs(const std::complex<_Tp>& __z) 299169691Skan { return std::abs(__z); } 300169691Skan 301169691Skan 302169691Skan /// @brief Additional overloads [8.1.9]. 303169691Skan // 304169691Skan 305169691Skan // See common.h for the primary template. 306169691Skan template<typename _Tp, typename _Up> 307169691Skan struct __promote_2<std::complex<_Tp>, _Up> 308169691Skan { 309169691Skan public: 310169691Skan typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 311169691Skan }; 312169691Skan 313169691Skan template<typename _Tp, typename _Up> 314169691Skan struct __promote_2<_Tp, std::complex<_Up> > 315169691Skan { 316169691Skan public: 317169691Skan typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 318169691Skan }; 319169691Skan 320169691Skan template<typename _Tp, typename _Up> 321169691Skan struct __promote_2<std::complex<_Tp>, std::complex<_Up> > 322169691Skan { 323169691Skan public: 324169691Skan typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 325169691Skan }; 326169691Skan 327169691Skan 328169691Skan using std::arg; 329169691Skan 330169691Skan template<typename _Tp> 331169691Skan inline typename __promote<_Tp>::__type 332169691Skan arg(_Tp __x) 333169691Skan { 334169691Skan typedef typename __promote<_Tp>::__type __type; 335169691Skan return std::arg(std::complex<__type>(__x)); 336169691Skan } 337169691Skan 338169691Skan using std::conj; 339169691Skan 340169691Skan template<typename _Tp> 341169691Skan inline std::complex<typename __promote<_Tp>::__type> 342169691Skan conj(_Tp __x) 343169691Skan { return __x; } 344169691Skan 345169691Skan using std::imag; 346169691Skan 347169691Skan template<typename _Tp> 348169691Skan inline typename __promote<_Tp>::__type 349169691Skan imag(_Tp) 350169691Skan { return _Tp(); } 351169691Skan 352169691Skan using std::norm; 353169691Skan 354169691Skan template<typename _Tp> 355169691Skan inline typename __promote<_Tp>::__type 356169691Skan norm(_Tp __x) 357169691Skan { 358169691Skan typedef typename __promote<_Tp>::__type __type; 359169691Skan return __type(__x) * __type(__x); 360169691Skan } 361169691Skan 362169691Skan using std::polar; 363169691Skan 364169691Skan template<typename _Tp, typename _Up> 365169691Skan inline std::complex<typename __promote_2<_Tp, _Up>::__type> 366169691Skan polar(const _Tp& __rho, const _Up& __theta) 367169691Skan { 368169691Skan typedef typename __promote_2<_Tp, _Up>::__type __type; 369169691Skan return std::polar(__type(__rho), __type(__theta)); 370169691Skan } 371169691Skan 372169691Skan using std::pow; 373169691Skan 374169691Skan template<typename _Tp, typename _Up> 375169691Skan inline std::complex<typename __promote_2<_Tp, _Up>::__type> 376169691Skan pow(const std::complex<_Tp>& __x, const _Up& __y) 377169691Skan { 378169691Skan typedef typename __promote_2<_Tp, _Up>::__type __type; 379169691Skan return std::pow(std::complex<__type>(__x), __type(__y)); 380169691Skan } 381169691Skan 382169691Skan template<typename _Tp, typename _Up> 383169691Skan inline std::complex<typename __promote_2<_Tp, _Up>::__type> 384169691Skan pow(const _Tp& __x, const std::complex<_Up>& __y) 385169691Skan { 386169691Skan typedef typename __promote_2<_Tp, _Up>::__type __type; 387169691Skan return std::pow(__type(__x), std::complex<__type>(__y)); 388169691Skan } 389169691Skan 390169691Skan template<typename _Tp, typename _Up> 391169691Skan inline std::complex<typename __promote_2<_Tp, _Up>::__type> 392169691Skan pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) 393169691Skan { 394169691Skan typedef typename __promote_2<_Tp, _Up>::__type __type; 395169691Skan return std::pow(std::complex<__type>(__x), 396169691Skan std::complex<__type>(__y)); 397169691Skan } 398169691Skan 399169691Skan using std::real; 400169691Skan 401169691Skan template<typename _Tp> 402169691Skan inline typename __promote<_Tp>::__type 403169691Skan real(_Tp __x) 404169691Skan { return __x; } 405169691Skan 406169691Skan_GLIBCXX_END_NAMESPACE 407169691Skan} 408169691Skan 409169691Skan#endif 410