# tr1_impl/complex

Go to the documentation of this file.

    00001 // TR1 complex -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 3, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // Under Section 7 of GPL version 3, you are granted additional
    00017 // permissions described in the GCC Runtime Library Exception, version
    00018 // 3.1, as published by the Free Software Foundation.
    00019
    00020 // You should have received a copy of the GNU General Public License and
    00021 // a copy of the GCC Runtime Library Exception along with this program;
    00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00023 // <http://www.gnu.org/licenses/>.
    00024
    00025 /** @file tr1_impl/complex
    00026  *  This is an internal header file, included by other library headers.
    00027  *  You should not attempt to use it directly.
    00028  */
    00029
    00030 namespace std
    00031 {
    00032 _GLIBCXX_BEGIN_NAMESPACE_TR1
    00033
    00034   /**
    00035    * @addtogroup complex_numbers
    00036    * @{
    00037    */
    00038
    00039   // Forward declarations.
    00040   template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
    00041   template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
    00042   template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
    00043
    00044   template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
    00045   template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
    00046   template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
    00047 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    00048   // DR 595.
    00049   template<typename _Tp> _Tp               fabs(const std::complex<_Tp>&);
    00050 #else
    00051   template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
    00052 #endif
    00053
    00054   template<typename _Tp>
    00055     inline std::complex<_Tp>
    00056     __complex_acos(const std::complex<_Tp>& __z)
    00057     {
    00058       const std::complex<_Tp> __t = std::_GLIBCXX_TR1 asin(__z);
    00059       const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
    00060       return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
    00061     }
    00062
    00063 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00064   inline __complex__ float
    00065   __complex_acos(__complex__ float __z)
    00066   { return __builtin_cacosf(__z); }
    00067
    00068   inline __complex__ double
    00069   __complex_acos(__complex__ double __z)
    00070   { return __builtin_cacos(__z); }
    00071
    00072   inline __complex__ long double
    00073   __complex_acos(const __complex__ long double& __z)
    00074   { return __builtin_cacosl(__z); }
    00075
    00076   template<typename _Tp>
    00077     inline std::complex<_Tp>
    00078     acos(const std::complex<_Tp>& __z)
    00079     { return __complex_acos(__z.__rep()); }
    00080 #else
    00081   /// acos(__z) [8.1.2].
    00082   //  Effects:  Behaves the same as C99 function cacos, defined
    00083   //            in subclause 7.3.5.1.
    00084   template<typename _Tp>
    00085     inline std::complex<_Tp>
    00086     acos(const std::complex<_Tp>& __z)
    00087     { return __complex_acos(__z); }
    00088 #endif
    00089
    00090   template<typename _Tp>
    00091     inline std::complex<_Tp>
    00092     __complex_asin(const std::complex<_Tp>& __z)
    00093     {
    00094       std::complex<_Tp> __t(-__z.imag(), __z.real());
    00095       __t = std::_GLIBCXX_TR1 asinh(__t);
    00096       return std::complex<_Tp>(__t.imag(), -__t.real());
    00097     }
    00098
    00099 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00100   inline __complex__ float
    00101   __complex_asin(__complex__ float __z)
    00102   { return __builtin_casinf(__z); }
    00103
    00104   inline __complex__ double
    00105   __complex_asin(__complex__ double __z)
    00106   { return __builtin_casin(__z); }
    00107
    00108   inline __complex__ long double
    00109   __complex_asin(const __complex__ long double& __z)
    00110   { return __builtin_casinl(__z); }
    00111
    00112   template<typename _Tp>
    00113     inline std::complex<_Tp>
    00114     asin(const std::complex<_Tp>& __z)
    00115     { return __complex_asin(__z.__rep()); }
    00116 #else
    00117   /// asin(__z) [8.1.3].
    00118   //  Effects:  Behaves the same as C99 function casin, defined
    00119   //            in subclause 7.3.5.2.
    00120   template<typename _Tp>
    00121     inline std::complex<_Tp>
    00122     asin(const std::complex<_Tp>& __z)
    00123     { return __complex_asin(__z); }
    00124 #endif
    00125
    00126   template<typename _Tp>
    00127     std::complex<_Tp>
    00128     __complex_atan(const std::complex<_Tp>& __z)
    00129     {
    00130       const _Tp __r2 = __z.real() * __z.real();
    00131       const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
    00132
    00133       _Tp __num = __z.imag() + _Tp(1.0);
    00134       _Tp __den = __z.imag() - _Tp(1.0);
    00135
    00136       __num = __r2 + __num * __num;
    00137       __den = __r2 + __den * __den;
    00138
    00139       return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
    00140                    _Tp(0.25) * log(__num / __den));
    00141     }
    00142
    00143 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00144   inline __complex__ float
    00145   __complex_atan(__complex__ float __z)
    00146   { return __builtin_catanf(__z); }
    00147
    00148   inline __complex__ double
    00149   __complex_atan(__complex__ double __z)
    00150   { return __builtin_catan(__z); }
    00151
    00152   inline __complex__ long double
    00153   __complex_atan(const __complex__ long double& __z)
    00154   { return __builtin_catanl(__z); }
    00155
    00156   template<typename _Tp>
    00157     inline std::complex<_Tp>
    00158     atan(const std::complex<_Tp>& __z)
    00159     { return __complex_atan(__z.__rep()); }
    00160 #else
    00161   /// atan(__z) [8.1.4].
    00162   //  Effects:  Behaves the same as C99 function catan, defined
    00163   //            in subclause 7.3.5.3.
    00164   template<typename _Tp>
    00165     inline std::complex<_Tp>
    00166     atan(const std::complex<_Tp>& __z)
    00167     { return __complex_atan(__z); }
    00168 #endif
    00169
    00170   template<typename _Tp>
    00171     std::complex<_Tp>
    00172     __complex_acosh(const std::complex<_Tp>& __z)
    00173     {
    00174       std::complex<_Tp> __t((__z.real() - __z.imag())
    00175                 * (__z.real() + __z.imag()) - _Tp(1.0),
    00176                 _Tp(2.0) * __z.real() * __z.imag());
    00177       __t = std::sqrt(__t);
    00178
    00179       return std::log(__t + __z);
    00180     }
    00181
    00182 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00183   inline __complex__ float
    00184   __complex_acosh(__complex__ float __z)
    00185   { return __builtin_cacoshf(__z); }
    00186
    00187   inline __complex__ double
    00188   __complex_acosh(__complex__ double __z)
    00189   { return __builtin_cacosh(__z); }
    00190
    00191   inline __complex__ long double
    00192   __complex_acosh(const __complex__ long double& __z)
    00193   { return __builtin_cacoshl(__z); }
    00194
    00195   template<typename _Tp>
    00196     inline std::complex<_Tp>
    00197     acosh(const std::complex<_Tp>& __z)
    00198     { return __complex_acosh(__z.__rep()); }
    00199 #else
    00200   /// acosh(__z) [8.1.5].
    00201   //  Effects:  Behaves the same as C99 function cacosh, defined
    00202   //            in subclause 7.3.6.1.
    00203   template<typename _Tp>
    00204     inline std::complex<_Tp>
    00205     acosh(const std::complex<_Tp>& __z)
    00206     { return __complex_acosh(__z); }
    00207 #endif
    00208
    00209   template<typename _Tp>
    00210     std::complex<_Tp>
    00211     __complex_asinh(const std::complex<_Tp>& __z)
    00212     {
    00213       std::complex<_Tp> __t((__z.real() - __z.imag())
    00214                 * (__z.real() + __z.imag()) + _Tp(1.0),
    00215                 _Tp(2.0) * __z.real() * __z.imag());
    00216       __t = std::sqrt(__t);
    00217
    00218       return std::log(__t + __z);
    00219     }
    00220
    00221 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00222   inline __complex__ float
    00223   __complex_asinh(__complex__ float __z)
    00224   { return __builtin_casinhf(__z); }
    00225
    00226   inline __complex__ double
    00227   __complex_asinh(__complex__ double __z)
    00228   { return __builtin_casinh(__z); }
    00229
    00230   inline __complex__ long double
    00231   __complex_asinh(const __complex__ long double& __z)
    00232   { return __builtin_casinhl(__z); }
    00233
    00234   template<typename _Tp>
    00235     inline std::complex<_Tp>
    00236     asinh(const std::complex<_Tp>& __z)
    00237     { return __complex_asinh(__z.__rep()); }
    00238 #else
    00239   /// asinh(__z) [8.1.6].
    00240   //  Effects:  Behaves the same as C99 function casin, defined
    00241   //            in subclause 7.3.6.2.
    00242   template<typename _Tp>
    00243     inline std::complex<_Tp>
    00244     asinh(const std::complex<_Tp>& __z)
    00245     { return __complex_asinh(__z); }
    00246 #endif
    00247
    00248   template<typename _Tp>
    00249     std::complex<_Tp>
    00250     __complex_atanh(const std::complex<_Tp>& __z)
    00251     {
    00252       const _Tp __i2 = __z.imag() * __z.imag();
    00253       const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
    00254
    00255       _Tp __num = _Tp(1.0) + __z.real();
    00256       _Tp __den = _Tp(1.0) - __z.real();
    00257
    00258       __num = __i2 + __num * __num;
    00259       __den = __i2 + __den * __den;
    00260
    00261       return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
    00262                    _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
    00263     }
    00264
    00265 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00266   inline __complex__ float
    00267   __complex_atanh(__complex__ float __z)
    00268   { return __builtin_catanhf(__z); }
    00269
    00270   inline __complex__ double
    00271   __complex_atanh(__complex__ double __z)
    00272   { return __builtin_catanh(__z); }
    00273
    00274   inline __complex__ long double
    00275   __complex_atanh(const __complex__ long double& __z)
    00276   { return __builtin_catanhl(__z); }
    00277
    00278   template<typename _Tp>
    00279     inline std::complex<_Tp>
    00280     atanh(const std::complex<_Tp>& __z)
    00281     { return __complex_atanh(__z.__rep()); }
    00282 #else
    00283   /// atanh(__z) [8.1.7].
    00284   //  Effects:  Behaves the same as C99 function catanh, defined
    00285   //            in subclause 7.3.6.3.
    00286   template<typename _Tp>
    00287     inline std::complex<_Tp>
    00288     atanh(const std::complex<_Tp>& __z)
    00289     { return __complex_atanh(__z); }
    00290 #endif
    00291
    00292   template<typename _Tp>
    00293 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    00294     inline _Tp
    00295 #else
    00296     inline std::complex<_Tp>
    00297 #endif
    00298     /// fabs(__z) [8.1.8].
    00299     //  Effects:  Behaves the same as C99 function cabs, defined
    00300     //            in subclause 7.3.8.1.
    00301     fabs(const std::complex<_Tp>& __z)
    00302     { return std::abs(__z); }
    00303
    00304   /// Additional overloads [8.1.9].
    00305 #if (defined(_GLIBCXX_INCLUDE_AS_CXX0X) \
    00306      || (defined(_GLIBCXX_INCLUDE_AS_TR1) \
    00307      && !defined(__GXX_EXPERIMENTAL_CXX0X__)))
    00308
    00309   template<typename _Tp>
    00310     inline typename __gnu_cxx::__promote<_Tp>::__type
    00311     arg(_Tp __x)
    00312     {
    00313       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
    00314       return std::arg(std::complex<__type>(__x));
    00315     }
    00316
    00317   template<typename _Tp>
    00318     inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
    00319     conj(_Tp __x)
    00320     { return __x; }
    00321
    00322   template<typename _Tp>
    00323     inline typename __gnu_cxx::__promote<_Tp>::__type
    00324     imag(_Tp)
    00325     { return _Tp(); }
    00326
    00327   template<typename _Tp>
    00328     inline typename __gnu_cxx::__promote<_Tp>::__type
    00329     norm(_Tp __x)
    00330     {
    00331       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
    00332       return __type(__x) * __type(__x);
    00333     }
    00334
    00335   template<typename _Tp>
    00336     inline typename __gnu_cxx::__promote<_Tp>::__type
    00337     real(_Tp __x)
    00338     { return __x; }
    00339
    00340 #endif
    00341
    00342   template<typename _Tp, typename _Up>
    00343     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
    00344     pow(const std::complex<_Tp>& __x, const _Up& __y)
    00345     {
    00346       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
    00347       return std::pow(std::complex<__type>(__x), __type(__y));
    00348     }
    00349
    00350   template<typename _Tp, typename _Up>
    00351     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
    00352     pow(const _Tp& __x, const std::complex<_Up>& __y)
    00353     {
    00354       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
    00355       return std::pow(__type(__x), std::complex<__type>(__y));
    00356     }
    00357
    00358   template<typename _Tp, typename _Up>
    00359     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
    00360     pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
    00361     {
    00362       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
    00363       return std::pow(std::complex<__type>(__x),
    00364               std::complex<__type>(__y));
    00365     }
    00366
    00367   // @} group complex_numbers
    00368
    00369 _GLIBCXX_END_NAMESPACE_TR1
    00370 }