Home | History | Annotate | Download | only in tr1_impl
      1 // TR1 complex -*- C++ -*-
      2 
      3 // Copyright (C) 2007, 2008, 2009 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 3, 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 // 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.
     19 
     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/>.
     24 
     25 /** @file tr1_impl/complex
     26  *  This is an internal header file, included by other library headers.
     27  *  You should not attempt to use it directly.
     28  */
     29 
     30 namespace std
     31 {
     32 _GLIBCXX_BEGIN_NAMESPACE_TR1
     33 
     34   /**
     35    * @addtogroup complex_numbers
     36    * @{
     37    */
     38 
     39   // Forward declarations.
     40   template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
     41   template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
     42   template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
     43 
     44   template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
     45   template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
     46   template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
     47 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
     48   // DR 595.
     49   template<typename _Tp> _Tp               fabs(const std::complex<_Tp>&);
     50 #else
     51   template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
     52 #endif
     53 
     54   template<typename _Tp>
     55     inline std::complex<_Tp>
     56     __complex_acos(const std::complex<_Tp>& __z)
     57     {
     58       const std::complex<_Tp> __t = std::_GLIBCXX_TR1 asin(__z);
     59       const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
     60       return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
     61     }
     62 
     63 #if _GLIBCXX_USE_C99_COMPLEX_TR1
     64   inline __complex__ float
     65   __complex_acos(__complex__ float __z)
     66   { return __builtin_cacosf(__z); }
     67 
     68   inline __complex__ double
     69   __complex_acos(__complex__ double __z)
     70   { return __builtin_cacos(__z); }
     71 
     72   inline __complex__ long double
     73   __complex_acos(const __complex__ long double& __z)
     74   { return __builtin_cacosl(__z); }
     75 
     76   template<typename _Tp>
     77     inline std::complex<_Tp>
     78     acos(const std::complex<_Tp>& __z)
     79     { return __complex_acos(__z.__rep()); }
     80 #else
     81   /// acos(__z) [8.1.2].
     82   //  Effects:  Behaves the same as C99 function cacos, defined
     83   //            in subclause 7.3.5.1.
     84   template<typename _Tp>
     85     inline std::complex<_Tp>
     86     acos(const std::complex<_Tp>& __z)
     87     { return __complex_acos(__z); }
     88 #endif
     89 
     90   template<typename _Tp>
     91     inline std::complex<_Tp>
     92     __complex_asin(const std::complex<_Tp>& __z)
     93     {
     94       std::complex<_Tp> __t(-__z.imag(), __z.real());
     95       __t = std::_GLIBCXX_TR1 asinh(__t);
     96       return std::complex<_Tp>(__t.imag(), -__t.real());
     97     }
     98 
     99 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    100   inline __complex__ float
    101   __complex_asin(__complex__ float __z)
    102   { return __builtin_casinf(__z); }
    103 
    104   inline __complex__ double
    105   __complex_asin(__complex__ double __z)
    106   { return __builtin_casin(__z); }
    107 
    108   inline __complex__ long double
    109   __complex_asin(const __complex__ long double& __z)
    110   { return __builtin_casinl(__z); }
    111 
    112   template<typename _Tp>
    113     inline std::complex<_Tp>
    114     asin(const std::complex<_Tp>& __z)
    115     { return __complex_asin(__z.__rep()); }
    116 #else
    117   /// asin(__z) [8.1.3].
    118   //  Effects:  Behaves the same as C99 function casin, defined
    119   //            in subclause 7.3.5.2.
    120   template<typename _Tp>
    121     inline std::complex<_Tp>
    122     asin(const std::complex<_Tp>& __z)
    123     { return __complex_asin(__z); }
    124 #endif
    125   
    126   template<typename _Tp>
    127     std::complex<_Tp>
    128     __complex_atan(const std::complex<_Tp>& __z)
    129     {
    130       const _Tp __r2 = __z.real() * __z.real();
    131       const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
    132 
    133       _Tp __num = __z.imag() + _Tp(1.0);
    134       _Tp __den = __z.imag() - _Tp(1.0);
    135 
    136       __num = __r2 + __num * __num;
    137       __den = __r2 + __den * __den;
    138 
    139       return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
    140 			       _Tp(0.25) * log(__num / __den));
    141     }
    142 
    143 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    144   inline __complex__ float
    145   __complex_atan(__complex__ float __z)
    146   { return __builtin_catanf(__z); }
    147 
    148   inline __complex__ double
    149   __complex_atan(__complex__ double __z)
    150   { return __builtin_catan(__z); }
    151 
    152   inline __complex__ long double
    153   __complex_atan(const __complex__ long double& __z)
    154   { return __builtin_catanl(__z); }
    155 
    156   template<typename _Tp>
    157     inline std::complex<_Tp>
    158     atan(const std::complex<_Tp>& __z)
    159     { return __complex_atan(__z.__rep()); }
    160 #else
    161   /// atan(__z) [8.1.4].
    162   //  Effects:  Behaves the same as C99 function catan, defined
    163   //            in subclause 7.3.5.3.
    164   template<typename _Tp>
    165     inline std::complex<_Tp>
    166     atan(const std::complex<_Tp>& __z)
    167     { return __complex_atan(__z); }
    168 #endif
    169 
    170   template<typename _Tp>
    171     std::complex<_Tp>
    172     __complex_acosh(const std::complex<_Tp>& __z)
    173     {
    174       std::complex<_Tp> __t((__z.real() - __z.imag())
    175 			    * (__z.real() + __z.imag()) - _Tp(1.0),
    176 			    _Tp(2.0) * __z.real() * __z.imag());
    177       __t = std::sqrt(__t);
    178 
    179       return std::log(__t + __z);
    180     }
    181 
    182 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    183   inline __complex__ float
    184   __complex_acosh(__complex__ float __z)
    185   { return __builtin_cacoshf(__z); }
    186 
    187   inline __complex__ double
    188   __complex_acosh(__complex__ double __z)
    189   { return __builtin_cacosh(__z); }
    190 
    191   inline __complex__ long double
    192   __complex_acosh(const __complex__ long double& __z)
    193   { return __builtin_cacoshl(__z); }
    194 
    195   template<typename _Tp>
    196     inline std::complex<_Tp>
    197     acosh(const std::complex<_Tp>& __z)
    198     { return __complex_acosh(__z.__rep()); }
    199 #else
    200   /// acosh(__z) [8.1.5].
    201   //  Effects:  Behaves the same as C99 function cacosh, defined
    202   //            in subclause 7.3.6.1.
    203   template<typename _Tp>
    204     inline std::complex<_Tp>
    205     acosh(const std::complex<_Tp>& __z)
    206     { return __complex_acosh(__z); }
    207 #endif
    208 
    209   template<typename _Tp>
    210     std::complex<_Tp>
    211     __complex_asinh(const std::complex<_Tp>& __z)
    212     {
    213       std::complex<_Tp> __t((__z.real() - __z.imag())
    214 			    * (__z.real() + __z.imag()) + _Tp(1.0),
    215 			    _Tp(2.0) * __z.real() * __z.imag());
    216       __t = std::sqrt(__t);
    217 
    218       return std::log(__t + __z);
    219     }
    220 
    221 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    222   inline __complex__ float
    223   __complex_asinh(__complex__ float __z)
    224   { return __builtin_casinhf(__z); }
    225 
    226   inline __complex__ double
    227   __complex_asinh(__complex__ double __z)
    228   { return __builtin_casinh(__z); }
    229 
    230   inline __complex__ long double
    231   __complex_asinh(const __complex__ long double& __z)
    232   { return __builtin_casinhl(__z); }
    233 
    234   template<typename _Tp>
    235     inline std::complex<_Tp>
    236     asinh(const std::complex<_Tp>& __z)
    237     { return __complex_asinh(__z.__rep()); }
    238 #else
    239   /// asinh(__z) [8.1.6].
    240   //  Effects:  Behaves the same as C99 function casin, defined
    241   //            in subclause 7.3.6.2.
    242   template<typename _Tp>
    243     inline std::complex<_Tp>
    244     asinh(const std::complex<_Tp>& __z)
    245     { return __complex_asinh(__z); }
    246 #endif
    247 
    248   template<typename _Tp>
    249     std::complex<_Tp>
    250     __complex_atanh(const std::complex<_Tp>& __z)
    251     {
    252       const _Tp __i2 = __z.imag() * __z.imag();
    253       const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
    254 
    255       _Tp __num = _Tp(1.0) + __z.real();
    256       _Tp __den = _Tp(1.0) - __z.real();
    257 
    258       __num = __i2 + __num * __num;
    259       __den = __i2 + __den * __den;
    260 
    261       return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
    262 			       _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
    263     }
    264 
    265 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    266   inline __complex__ float
    267   __complex_atanh(__complex__ float __z)
    268   { return __builtin_catanhf(__z); }
    269 
    270   inline __complex__ double
    271   __complex_atanh(__complex__ double __z)
    272   { return __builtin_catanh(__z); }
    273 
    274   inline __complex__ long double
    275   __complex_atanh(const __complex__ long double& __z)
    276   { return __builtin_catanhl(__z); }
    277 
    278   template<typename _Tp>
    279     inline std::complex<_Tp>
    280     atanh(const std::complex<_Tp>& __z)
    281     { return __complex_atanh(__z.__rep()); }
    282 #else
    283   /// atanh(__z) [8.1.7].
    284   //  Effects:  Behaves the same as C99 function catanh, defined
    285   //            in subclause 7.3.6.3.
    286   template<typename _Tp>
    287     inline std::complex<_Tp>
    288     atanh(const std::complex<_Tp>& __z)
    289     { return __complex_atanh(__z); }
    290 #endif
    291 
    292   template<typename _Tp>
    293 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    294     inline _Tp
    295 #else
    296     inline std::complex<_Tp>
    297 #endif
    298     /// fabs(__z) [8.1.8].
    299     //  Effects:  Behaves the same as C99 function cabs, defined
    300     //            in subclause 7.3.8.1.
    301     fabs(const std::complex<_Tp>& __z)
    302     { return std::abs(__z); }
    303 
    304   /// Additional overloads [8.1.9].
    305 #if (defined(_GLIBCXX_INCLUDE_AS_CXX0X) \
    306      || (defined(_GLIBCXX_INCLUDE_AS_TR1) \
    307 	 && !defined(__GXX_EXPERIMENTAL_CXX0X__)))
    308 
    309   template<typename _Tp>
    310     inline typename __gnu_cxx::__promote<_Tp>::__type
    311     arg(_Tp __x)
    312     {
    313       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
    314       return std::arg(std::complex<__type>(__x));
    315     }
    316 
    317   template<typename _Tp>
    318     inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
    319     conj(_Tp __x)
    320     { return __x; }
    321 
    322   template<typename _Tp>
    323     inline typename __gnu_cxx::__promote<_Tp>::__type
    324     imag(_Tp)
    325     { return _Tp(); }
    326 
    327   template<typename _Tp>
    328     inline typename __gnu_cxx::__promote<_Tp>::__type
    329     norm(_Tp __x)
    330     {
    331       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
    332       return __type(__x) * __type(__x);
    333     }
    334 
    335   template<typename _Tp>
    336     inline typename __gnu_cxx::__promote<_Tp>::__type
    337     real(_Tp __x)
    338     { return __x; }
    339 
    340 #endif
    341 
    342   template<typename _Tp, typename _Up>
    343     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
    344     pow(const std::complex<_Tp>& __x, const _Up& __y)
    345     {
    346       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
    347       return std::pow(std::complex<__type>(__x), __type(__y));
    348     }
    349 
    350   template<typename _Tp, typename _Up>
    351     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
    352     pow(const _Tp& __x, const std::complex<_Up>& __y)
    353     {
    354       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
    355       return std::pow(__type(__x), std::complex<__type>(__y));
    356     }
    357 
    358   template<typename _Tp, typename _Up>
    359     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
    360     pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
    361     {
    362       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
    363       return std::pow(std::complex<__type>(__x),
    364 		      std::complex<__type>(__y));
    365     }
    366 
    367   // @} group complex_numbers
    368 
    369 _GLIBCXX_END_NAMESPACE_TR1
    370 }
    371