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