1 // TR1 complex -*- C++ -*-
     3 // Copyright (C) 2006-2018 Free Software Foundation, Inc.
     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)
    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.
    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.
    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/>.
    26  *  This is a TR1 C++ Library header. 
    29 #ifndef _GLIBCXX_TR1_COMPLEX
    30 #define _GLIBCXX_TR1_COMPLEX 1
    32 #pragma GCC system_header
    36 namespace std _GLIBCXX_VISIBILITY(default)
    38 _GLIBCXX_BEGIN_NAMESPACE_VERSION
    43    * @addtogroup complex_numbers
    47 #if __cplusplus >= 201103L
    55   template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
    56   template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
    57   template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
    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>&);
    63   // The std::fabs return type in C++11 mode is different (just _Tp).
    64   template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
    66 #if __cplusplus < 201103L
    67   template<typename _Tp>
    68     inline std::complex<_Tp>
    69     __complex_acos(const std::complex<_Tp>& __z)
    71       const std::complex<_Tp> __t = std::tr1::asin(__z);
    72       const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
    73       return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
    76 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    77   inline __complex__ float
    78   __complex_acos(__complex__ float __z)
    79   { return __builtin_cacosf(__z); }
    81   inline __complex__ double
    82   __complex_acos(__complex__ double __z)
    83   { return __builtin_cacos(__z); }
    85   inline __complex__ long double
    86   __complex_acos(const __complex__ long double& __z)
    87   { return __builtin_cacosl(__z); }
    89   template<typename _Tp>
    90     inline std::complex<_Tp>
    91     acos(const std::complex<_Tp>& __z)
    92     { return __complex_acos(__z.__rep()); }
    94   /// acos(__z) [8.1.2].
    95   //  Effects:  Behaves the same as C99 function cacos, defined
    96   //            in subclause 7.3.5.1.
    97   template<typename _Tp>
    98     inline std::complex<_Tp>
    99     acos(const std::complex<_Tp>& __z)
   100     { return __complex_acos(__z); }
   103   template<typename _Tp>
   104     inline std::complex<_Tp>
   105     __complex_asin(const std::complex<_Tp>& __z)
   107       std::complex<_Tp> __t(-__z.imag(), __z.real());
   108       __t = std::tr1::asinh(__t);
   109       return std::complex<_Tp>(__t.imag(), -__t.real());
   112 #if _GLIBCXX_USE_C99_COMPLEX_TR1
   113   inline __complex__ float
   114   __complex_asin(__complex__ float __z)
   115   { return __builtin_casinf(__z); }
   117   inline __complex__ double
   118   __complex_asin(__complex__ double __z)
   119   { return __builtin_casin(__z); }
   121   inline __complex__ long double
   122   __complex_asin(const __complex__ long double& __z)
   123   { return __builtin_casinl(__z); }
   125   template<typename _Tp>
   126     inline std::complex<_Tp>
   127     asin(const std::complex<_Tp>& __z)
   128     { return __complex_asin(__z.__rep()); }
   130   /// asin(__z) [8.1.3].
   131   //  Effects:  Behaves the same as C99 function casin, defined
   132   //            in subclause 7.3.5.2.
   133   template<typename _Tp>
   134     inline std::complex<_Tp>
   135     asin(const std::complex<_Tp>& __z)
   136     { return __complex_asin(__z); }
   139   template<typename _Tp>
   141     __complex_atan(const std::complex<_Tp>& __z)
   143       const _Tp __r2 = __z.real() * __z.real();
   144       const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
   146       _Tp __num = __z.imag() + _Tp(1.0);
   147       _Tp __den = __z.imag() - _Tp(1.0);
   149       __num = __r2 + __num * __num;
   150       __den = __r2 + __den * __den;
   152       return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
   153                           _Tp(0.25) * log(__num / __den));
   156 #if _GLIBCXX_USE_C99_COMPLEX_TR1
   157   inline __complex__ float
   158   __complex_atan(__complex__ float __z)
   159   { return __builtin_catanf(__z); }
   161   inline __complex__ double
   162   __complex_atan(__complex__ double __z)
   163   { return __builtin_catan(__z); }
   165   inline __complex__ long double
   166   __complex_atan(const __complex__ long double& __z)
   167   { return __builtin_catanl(__z); }
   169   template<typename _Tp>
   170     inline std::complex<_Tp>
   171     atan(const std::complex<_Tp>& __z)
   172     { return __complex_atan(__z.__rep()); }
   174   /// atan(__z) [8.1.4].
   175   //  Effects:  Behaves the same as C99 function catan, defined
   176   //            in subclause 7.3.5.3.
   177   template<typename _Tp>
   178     inline std::complex<_Tp>
   179     atan(const std::complex<_Tp>& __z)
   180     { return __complex_atan(__z); }
   183   template<typename _Tp>
   185     __complex_acosh(const std::complex<_Tp>& __z)
   188       return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0)))
   189                             + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0))));
   192 #if _GLIBCXX_USE_C99_COMPLEX_TR1
   193   inline __complex__ float
   194   __complex_acosh(__complex__ float __z)
   195   { return __builtin_cacoshf(__z); }
   197   inline __complex__ double
   198   __complex_acosh(__complex__ double __z)
   199   { return __builtin_cacosh(__z); }
   201   inline __complex__ long double
   202   __complex_acosh(const __complex__ long double& __z)
   203   { return __builtin_cacoshl(__z); }
   205   template<typename _Tp>
   206     inline std::complex<_Tp>
   207     acosh(const std::complex<_Tp>& __z)
   208     { return __complex_acosh(__z.__rep()); }
   210   /// acosh(__z) [8.1.5].
   211   //  Effects:  Behaves the same as C99 function cacosh, defined
   212   //            in subclause 7.3.6.1.
   213   template<typename _Tp>
   214     inline std::complex<_Tp>
   215     acosh(const std::complex<_Tp>& __z)
   216     { return __complex_acosh(__z); }
   219   template<typename _Tp>
   221     __complex_asinh(const std::complex<_Tp>& __z)
   223       std::complex<_Tp> __t((__z.real() - __z.imag())
   224                        * (__z.real() + __z.imag()) + _Tp(1.0),
   225                        _Tp(2.0) * __z.real() * __z.imag());
   226       __t = std::sqrt(__t);
   228       return std::log(__t + __z);
   231 #if _GLIBCXX_USE_C99_COMPLEX_TR1
   232   inline __complex__ float
   233   __complex_asinh(__complex__ float __z)
   234   { return __builtin_casinhf(__z); }
   236   inline __complex__ double
   237   __complex_asinh(__complex__ double __z)
   238   { return __builtin_casinh(__z); }
   240   inline __complex__ long double
   241   __complex_asinh(const __complex__ long double& __z)
   242   { return __builtin_casinhl(__z); }
   244   template<typename _Tp>
   245     inline std::complex<_Tp>
   246     asinh(const std::complex<_Tp>& __z)
   247     { return __complex_asinh(__z.__rep()); }
   249   /// asinh(__z) [8.1.6].
   250   //  Effects:  Behaves the same as C99 function casin, defined
   251   //            in subclause 7.3.6.2.
   252   template<typename _Tp>
   253     inline std::complex<_Tp>
   254     asinh(const std::complex<_Tp>& __z)
   255     { return __complex_asinh(__z); }
   258   template<typename _Tp>
   260     __complex_atanh(const std::complex<_Tp>& __z)
   262       const _Tp __i2 = __z.imag() * __z.imag();
   263       const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
   265       _Tp __num = _Tp(1.0) + __z.real();
   266       _Tp __den = _Tp(1.0) - __z.real();
   268       __num = __i2 + __num * __num;
   269       __den = __i2 + __den * __den;
   271       return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
   272                           _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
   275 #if _GLIBCXX_USE_C99_COMPLEX_TR1
   276   inline __complex__ float
   277   __complex_atanh(__complex__ float __z)
   278   { return __builtin_catanhf(__z); }
   280   inline __complex__ double
   281   __complex_atanh(__complex__ double __z)
   282   { return __builtin_catanh(__z); }
   284   inline __complex__ long double
   285   __complex_atanh(const __complex__ long double& __z)
   286   { return __builtin_catanhl(__z); }
   288   template<typename _Tp>
   289     inline std::complex<_Tp>
   290     atanh(const std::complex<_Tp>& __z)
   291     { return __complex_atanh(__z.__rep()); }
   293   /// atanh(__z) [8.1.7].
   294   //  Effects:  Behaves the same as C99 function catanh, defined
   295   //            in subclause 7.3.6.3.
   296   template<typename _Tp>
   297     inline std::complex<_Tp>
   298     atanh(const std::complex<_Tp>& __z)
   299     { return __complex_atanh(__z); }
   304   template<typename _Tp>
   305     inline std::complex<_Tp>
   306     /// fabs(__z) [8.1.8].
   307     //  Effects:  Behaves the same as C99 function cabs, defined
   308     //            in subclause 7.3.8.1.
   309     fabs(const std::complex<_Tp>& __z)
   310     { return std::abs(__z); }
   312   /// Additional overloads [8.1.9].
   313 #if __cplusplus < 201103L
   315   template<typename _Tp>
   316     inline typename __gnu_cxx::__promote<_Tp>::__type
   319       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
   320 #if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC)
   321       return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L)
   324       return std::arg(std::complex<__type>(__x));
   328   template<typename _Tp>
   329     inline typename __gnu_cxx::__promote<_Tp>::__type
   333   template<typename _Tp>
   334     inline typename __gnu_cxx::__promote<_Tp>::__type
   337       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
   338       return __type(__x) * __type(__x);
   341   template<typename _Tp>
   342     inline typename __gnu_cxx::__promote<_Tp>::__type
   348   template<typename _Tp, typename _Up>
   349     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
   350     pow(const std::complex<_Tp>& __x, const _Up& __y)
   352       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
   353       return std::pow(std::complex<__type>(__x), __type(__y));
   356   template<typename _Tp, typename _Up>
   357     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
   358     pow(const _Tp& __x, const std::complex<_Up>& __y)
   360       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
   361       return std::pow(__type(__x), std::complex<__type>(__y));
   364   template<typename _Tp, typename _Up>
   365     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
   366     pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
   368       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
   369       return std::pow(std::complex<__type>(__x),
   370                  std::complex<__type>(__y));
   375   template<typename _Tp>
   376     inline std::complex<_Tp>
   377     conj(const std::complex<_Tp>& __z)
   378     { return std::conj(__z); }
   380   template<typename _Tp>
   381     inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
   389   template<typename _Tp, typename _Up>
   390     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
   391     polar(const _Tp& __rho, const _Up& __theta)
   393       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
   394       return std::polar(__type(__rho), __type(__theta));
   399   template<typename _Tp>
   400     inline std::complex<_Tp>
   401     pow(const std::complex<_Tp>& __x, const _Tp& __y)
   402     { return std::pow(__x, __y); }
   404   template<typename _Tp>
   405     inline std::complex<_Tp>
   406     pow(const _Tp& __x, const std::complex<_Tp>& __y)
   407     { return std::pow(__x, __y); }
   409   template<typename _Tp>
   410     inline std::complex<_Tp>
   411     pow(const std::complex<_Tp>& __x, const std::complex<_Tp>& __y)
   412     { return std::pow(__x, __y); }
   414 // @} group complex_numbers
   417 _GLIBCXX_END_NAMESPACE_VERSION
   420 #endif // _GLIBCXX_TR1_COMPLEX