1 // TR1 complex -*- C++ -*-
 
    3 // Copyright (C) 2006-2014 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)
 
   40 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   43    * @addtogroup complex_numbers
 
   47 #if __cplusplus >= 201103L
 
   52   template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
 
   53   template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
 
   54   template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
 
   57   template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
 
   58   template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
 
   59   template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
 
   61   // The std::fabs return type in C++0x mode is different (just _Tp).
 
   62   template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
 
   64 #if __cplusplus < 201103L
 
   65   template<typename _Tp>
 
   66     inline std::complex<_Tp>
 
   67     __complex_acos(const std::complex<_Tp>& __z)
 
   69       const std::complex<_Tp> __t = std::tr1::asin(__z);
 
   70       const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
 
   71       return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
 
   74 #if _GLIBCXX_USE_C99_COMPLEX_TR1
 
   75   inline __complex__ float
 
   76   __complex_acos(__complex__ float __z)
 
   77   { return __builtin_cacosf(__z); }
 
   79   inline __complex__ double
 
   80   __complex_acos(__complex__ double __z)
 
   81   { return __builtin_cacos(__z); }
 
   83   inline __complex__ long double
 
   84   __complex_acos(const __complex__ long double& __z)
 
   85   { return __builtin_cacosl(__z); }
 
   87   template<typename _Tp>
 
   88     inline std::complex<_Tp>
 
   89     acos(const std::complex<_Tp>& __z)
 
   90     { return __complex_acos(__z.__rep()); }
 
   92   /// acos(__z) [8.1.2].
 
   93   //  Effects:  Behaves the same as C99 function cacos, defined
 
   94   //            in subclause 7.3.5.1.
 
   95   template<typename _Tp>
 
   96     inline std::complex<_Tp>
 
   97     acos(const std::complex<_Tp>& __z)
 
   98     { return __complex_acos(__z); }
 
  101   template<typename _Tp>
 
  102     inline std::complex<_Tp>
 
  103     __complex_asin(const std::complex<_Tp>& __z)
 
  105       std::complex<_Tp> __t(-__z.imag(), __z.real());
 
  106       __t = std::tr1::asinh(__t);
 
  107       return std::complex<_Tp>(__t.imag(), -__t.real());
 
  110 #if _GLIBCXX_USE_C99_COMPLEX_TR1
 
  111   inline __complex__ float
 
  112   __complex_asin(__complex__ float __z)
 
  113   { return __builtin_casinf(__z); }
 
  115   inline __complex__ double
 
  116   __complex_asin(__complex__ double __z)
 
  117   { return __builtin_casin(__z); }
 
  119   inline __complex__ long double
 
  120   __complex_asin(const __complex__ long double& __z)
 
  121   { return __builtin_casinl(__z); }
 
  123   template<typename _Tp>
 
  124     inline std::complex<_Tp>
 
  125     asin(const std::complex<_Tp>& __z)
 
  126     { return __complex_asin(__z.__rep()); }
 
  128   /// asin(__z) [8.1.3].
 
  129   //  Effects:  Behaves the same as C99 function casin, defined
 
  130   //            in subclause 7.3.5.2.
 
  131   template<typename _Tp>
 
  132     inline std::complex<_Tp>
 
  133     asin(const std::complex<_Tp>& __z)
 
  134     { return __complex_asin(__z); }
 
  137   template<typename _Tp>
 
  139     __complex_atan(const std::complex<_Tp>& __z)
 
  141       const _Tp __r2 = __z.real() * __z.real();
 
  142       const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
 
  144       _Tp __num = __z.imag() + _Tp(1.0);
 
  145       _Tp __den = __z.imag() - _Tp(1.0);
 
  147       __num = __r2 + __num * __num;
 
  148       __den = __r2 + __den * __den;
 
  150       return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
 
  151                   _Tp(0.25) * log(__num / __den));
 
  154 #if _GLIBCXX_USE_C99_COMPLEX_TR1
 
  155   inline __complex__ float
 
  156   __complex_atan(__complex__ float __z)
 
  157   { return __builtin_catanf(__z); }
 
  159   inline __complex__ double
 
  160   __complex_atan(__complex__ double __z)
 
  161   { return __builtin_catan(__z); }
 
  163   inline __complex__ long double
 
  164   __complex_atan(const __complex__ long double& __z)
 
  165   { return __builtin_catanl(__z); }
 
  167   template<typename _Tp>
 
  168     inline std::complex<_Tp>
 
  169     atan(const std::complex<_Tp>& __z)
 
  170     { return __complex_atan(__z.__rep()); }
 
  172   /// atan(__z) [8.1.4].
 
  173   //  Effects:  Behaves the same as C99 function catan, defined
 
  174   //            in subclause 7.3.5.3.
 
  175   template<typename _Tp>
 
  176     inline std::complex<_Tp>
 
  177     atan(const std::complex<_Tp>& __z)
 
  178     { 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); }
 
  302   template<typename _Tp>
 
  303     inline std::complex<_Tp>
 
  304     /// fabs(__z) [8.1.8].
 
  305     //  Effects:  Behaves the same as C99 function cabs, defined
 
  306     //            in subclause 7.3.8.1.
 
  307     fabs(const std::complex<_Tp>& __z)
 
  308     { return std::abs(__z); }
 
  310   /// Additional overloads [8.1.9].
 
  311 #if __cplusplus < 201103L
 
  313   template<typename _Tp>
 
  314     inline typename __gnu_cxx::__promote<_Tp>::__type
 
  317       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
 
  318 #if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC)
 
  319       return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L)
 
  322       return std::arg(std::complex<__type>(__x));
 
  326   template<typename _Tp>
 
  327     inline typename __gnu_cxx::__promote<_Tp>::__type
 
  331   template<typename _Tp>
 
  332     inline typename __gnu_cxx::__promote<_Tp>::__type
 
  335       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
 
  336       return __type(__x) * __type(__x);
 
  339   template<typename _Tp>
 
  340     inline typename __gnu_cxx::__promote<_Tp>::__type
 
  346   template<typename _Tp, typename _Up>
 
  347     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
 
  348     pow(const std::complex<_Tp>& __x, const _Up& __y)
 
  350       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
 
  351       return std::pow(std::complex<__type>(__x), __type(__y));
 
  354   template<typename _Tp, typename _Up>
 
  355     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
 
  356     pow(const _Tp& __x, const std::complex<_Up>& __y)
 
  358       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
 
  359       return std::pow(__type(__x), std::complex<__type>(__y));
 
  362   template<typename _Tp, typename _Up>
 
  363     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
 
  364     pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
 
  366       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
 
  367       return std::pow(std::complex<__type>(__x),
 
  368              std::complex<__type>(__y));
 
  373   template<typename _Tp>
 
  374     inline std::complex<_Tp>
 
  375     conj(const std::complex<_Tp>& __z)
 
  376     { return std::conj(__z); }  
 
  378   template<typename _Tp>
 
  379     inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
 
  387   template<typename _Tp, typename _Up>
 
  388     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
 
  389     polar(const _Tp& __rho, const _Up& __theta)
 
  391       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
 
  392       return std::polar(__type(__rho), __type(__theta));
 
  397   template<typename _Tp>
 
  398     inline std::complex<_Tp>
 
  399     pow(const std::complex<_Tp>& __x, const _Tp& __y)
 
  400     { return std::pow(__x, __y); }
 
  402   template<typename _Tp>
 
  403     inline std::complex<_Tp>
 
  404     pow(const _Tp& __x, const std::complex<_Tp>& __y)
 
  405     { return std::pow(__x, __y); }
 
  407   template<typename _Tp>
 
  408     inline std::complex<_Tp>
 
  409     pow(const std::complex<_Tp>& __x, const std::complex<_Tp>& __y)
 
  410     { return std::pow(__x, __y); }
 
  412 // @} group complex_numbers
 
  414 _GLIBCXX_END_NAMESPACE_VERSION
 
  418 #endif // _GLIBCXX_TR1_COMPLEX