# complex

Go to the documentation of this file.

    00001 // TR1 complex -*- C++ -*-
    00002
    00003 // Copyright (C) 2006 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 2, 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 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /** @file tr1/complex
    00031  *  This is a TR1 C++ Library header.
    00032  */
    00033
    00034 #ifndef _TR1_COMPLEX
    00035 #define _TR1_COMPLEX 1
    00036
    00037 #include "../complex"
    00038 #include <tr1/common.h>
    00039
    00040 // namespace std::tr1
    00041 namespace std
    00042 {
    00043 _GLIBCXX_BEGIN_NAMESPACE(tr1)
    00044
    00045   // Forward declarations.
    00046   template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
    00047   template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
    00048   template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
    00049
    00050   template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
    00051   template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
    00052   template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
    00053   template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
    00054
    00055   /// @brief acos(__z) [8.1.2].
    00056   //  Effects:  Behaves the same as C99 function cacos, defined
    00057   //            in subclause 7.3.5.1.
    00058   template<typename _Tp>
    00059     inline std::complex<_Tp>
    00060     __complex_acos(const std::complex<_Tp>& __z)
    00061     {
    00062       const std::complex<_Tp> __t = std::tr1::asin(__z);
    00063       const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
    00064       return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
    00065     }
    00066
    00067 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00068   inline __complex__ float
    00069   __complex_acos(__complex__ float __z)
    00070   { return __builtin_cacosf(__z); }
    00071
    00072   inline __complex__ double
    00073   __complex_acos(__complex__ double __z)
    00074   { return __builtin_cacos(__z); }
    00075
    00076   inline __complex__ long double
    00077   __complex_acos(const __complex__ long double& __z)
    00078   { return __builtin_cacosl(__z); }
    00079
    00080   template<typename _Tp>
    00081     inline std::complex<_Tp>
    00082     acos(const std::complex<_Tp>& __z)
    00083     { return __complex_acos(__z.__rep()); }
    00084 #else
    00085   template<typename _Tp>
    00086     inline std::complex<_Tp>
    00087     acos(const std::complex<_Tp>& __z)
    00088     { return __complex_acos(__z); }
    00089 #endif
    00090
    00091   /// @brief asin(__z) [8.1.3].
    00092   //  Effects:  Behaves the same as C99 function casin, defined
    00093   //            in subclause 7.3.5.2.
    00094   template<typename _Tp>
    00095     inline std::complex<_Tp>
    00096     __complex_asin(const std::complex<_Tp>& __z)
    00097     {
    00098       std::complex<_Tp> __t(-__z.imag(), __z.real());
    00099       __t = std::tr1::asinh(__t);
    00100       return std::complex<_Tp>(__t.imag(), -__t.real());
    00101     }
    00102
    00103 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00104   inline __complex__ float
    00105   __complex_asin(__complex__ float __z)
    00106   { return __builtin_casinf(__z); }
    00107
    00108   inline __complex__ double
    00109   __complex_asin(__complex__ double __z)
    00110   { return __builtin_casin(__z); }
    00111
    00112   inline __complex__ long double
    00113   __complex_asin(const __complex__ long double& __z)
    00114   { return __builtin_casinl(__z); }
    00115
    00116   template<typename _Tp>
    00117     inline std::complex<_Tp>
    00118     asin(const std::complex<_Tp>& __z)
    00119     { return __complex_asin(__z.__rep()); }
    00120 #else
    00121   template<typename _Tp>
    00122     inline std::complex<_Tp>
    00123     asin(const std::complex<_Tp>& __z)
    00124     { return __complex_asin(__z); }
    00125 #endif
    00126
    00127   /// @brief atan(__z) [8.1.4].
    00128   //  Effects:  Behaves the same as C99 function catan, defined
    00129   //            in subclause 7.3.5.3.
    00130   template<typename _Tp>
    00131     std::complex<_Tp>
    00132     __complex_atan(const std::complex<_Tp>& __z)
    00133     {
    00134       const _Tp __r2 = __z.real() * __z.real();
    00135       const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
    00136
    00137       _Tp __num = __z.imag() + _Tp(1.0);
    00138       _Tp __den = __z.imag() - _Tp(1.0);
    00139
    00140       __num = __r2 + __num * __num;
    00141       __den = __r2 + __den * __den;
    00142
    00143       return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
    00144                    _Tp(0.25) * log(__num / __den));
    00145     }
    00146
    00147 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00148   inline __complex__ float
    00149   __complex_atan(__complex__ float __z)
    00150   { return __builtin_catanf(__z); }
    00151
    00152   inline __complex__ double
    00153   __complex_atan(__complex__ double __z)
    00154   { return __builtin_catan(__z); }
    00155
    00156   inline __complex__ long double
    00157   __complex_atan(const __complex__ long double& __z)
    00158   { return __builtin_catanl(__z); }
    00159
    00160   template<typename _Tp>
    00161     inline std::complex<_Tp>
    00162     atan(const std::complex<_Tp>& __z)
    00163     { return __complex_atan(__z.__rep()); }
    00164 #else
    00165   template<typename _Tp>
    00166     inline std::complex<_Tp>
    00167     atan(const std::complex<_Tp>& __z)
    00168     { return __complex_atan(__z); }
    00169 #endif
    00170
    00171   /// @brief acosh(__z) [8.1.5].
    00172   //  Effects:  Behaves the same as C99 function cacosh, defined
    00173   //            in subclause 7.3.6.1.
    00174   template<typename _Tp>
    00175     std::complex<_Tp>
    00176     __complex_acosh(const std::complex<_Tp>& __z)
    00177     {
    00178       std::complex<_Tp> __t((__z.real() - __z.imag())
    00179                 * (__z.real() + __z.imag()) - _Tp(1.0),
    00180                 _Tp(2.0) * __z.real() * __z.imag());
    00181       __t = std::sqrt(__t);
    00182
    00183       return std::log(__t + __z);
    00184     }
    00185
    00186 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00187   inline __complex__ float
    00188   __complex_acosh(__complex__ float __z)
    00189   { return __builtin_cacoshf(__z); }
    00190
    00191   inline __complex__ double
    00192   __complex_acosh(__complex__ double __z)
    00193   { return __builtin_cacosh(__z); }
    00194
    00195   inline __complex__ long double
    00196   __complex_acosh(const __complex__ long double& __z)
    00197   { return __builtin_cacoshl(__z); }
    00198
    00199   template<typename _Tp>
    00200     inline std::complex<_Tp>
    00201     acosh(const std::complex<_Tp>& __z)
    00202     { return __complex_acosh(__z.__rep()); }
    00203 #else
    00204   template<typename _Tp>
    00205     inline std::complex<_Tp>
    00206     acosh(const std::complex<_Tp>& __z)
    00207     { return __complex_acosh(__z); }
    00208 #endif
    00209
    00210   /// @brief asinh(__z) [8.1.6].
    00211   //  Effects:  Behaves the same as C99 function casin, defined
    00212   //            in subclause 7.3.6.2.
    00213   template<typename _Tp>
    00214     std::complex<_Tp>
    00215     __complex_asinh(const std::complex<_Tp>& __z)
    00216     {
    00217       std::complex<_Tp> __t((__z.real() - __z.imag())
    00218                 * (__z.real() + __z.imag()) + _Tp(1.0),
    00219                 _Tp(2.0) * __z.real() * __z.imag());
    00220       __t = std::sqrt(__t);
    00221
    00222       return std::log(__t + __z);
    00223     }
    00224
    00225 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00226   inline __complex__ float
    00227   __complex_asinh(__complex__ float __z)
    00228   { return __builtin_casinhf(__z); }
    00229
    00230   inline __complex__ double
    00231   __complex_asinh(__complex__ double __z)
    00232   { return __builtin_casinh(__z); }
    00233
    00234   inline __complex__ long double
    00235   __complex_asinh(const __complex__ long double& __z)
    00236   { return __builtin_casinhl(__z); }
    00237
    00238   template<typename _Tp>
    00239     inline std::complex<_Tp>
    00240     asinh(const std::complex<_Tp>& __z)
    00241     { return __complex_asinh(__z.__rep()); }
    00242 #else
    00243   template<typename _Tp>
    00244     inline std::complex<_Tp>
    00245     asinh(const std::complex<_Tp>& __z)
    00246     { return __complex_asinh(__z); }
    00247 #endif
    00248
    00249   /// @brief atanh(__z) [8.1.7].
    00250   //  Effects:  Behaves the same as C99 function catanh, defined
    00251   //            in subclause 7.3.6.3.
    00252   template<typename _Tp>
    00253     std::complex<_Tp>
    00254     __complex_atanh(const std::complex<_Tp>& __z)
    00255     {
    00256       const _Tp __i2 = __z.imag() * __z.imag();
    00257       const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
    00258
    00259       _Tp __num = _Tp(1.0) + __z.real();
    00260       _Tp __den = _Tp(1.0) - __z.real();
    00261
    00262       __num = __i2 + __num * __num;
    00263       __den = __i2 + __den * __den;
    00264
    00265       return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
    00266                    _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
    00267     }
    00268
    00269 #if _GLIBCXX_USE_C99_COMPLEX_TR1
    00270   inline __complex__ float
    00271   __complex_atanh(__complex__ float __z)
    00272   { return __builtin_catanhf(__z); }
    00273
    00274   inline __complex__ double
    00275   __complex_atanh(__complex__ double __z)
    00276   { return __builtin_catanh(__z); }
    00277
    00278   inline __complex__ long double
    00279   __complex_atanh(const __complex__ long double& __z)
    00280   { return __builtin_catanhl(__z); }
    00281
    00282   template<typename _Tp>
    00283     inline std::complex<_Tp>
    00284     atanh(const std::complex<_Tp>& __z)
    00285     { return __complex_atanh(__z.__rep()); }
    00286 #else
    00287   template<typename _Tp>
    00288     inline std::complex<_Tp>
    00289     atanh(const std::complex<_Tp>& __z)
    00290     { return __complex_atanh(__z); }
    00291 #endif
    00292
    00293   /// @brief fabs(__z) [8.1.8].
    00294   //  Effects:  Behaves the same as C99 function cabs, defined
    00295   //            in subclause 7.3.8.1.
    00296   template<typename _Tp>
    00297     inline std::complex<_Tp>
    00298     fabs(const std::complex<_Tp>& __z)
    00299     { return std::abs(__z); }
    00300
    00301
    00302   /// @brief Additional overloads [8.1.9].
    00303   //
    00304
    00305   // See common.h for the primary template.
    00306   template<typename _Tp, typename _Up>
    00307     struct __promote_2<std::complex<_Tp>, _Up>
    00308     {
    00309     public:
    00310       typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
    00311     };
    00312
    00313   template<typename _Tp, typename _Up>
    00314     struct __promote_2<_Tp, std::complex<_Up> >
    00315     {
    00316     public:
    00317       typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
    00318     };
    00319
    00320   template<typename _Tp, typename _Up>
    00321     struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
    00322     {
    00323     public:
    00324       typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
    00325     };
    00326
    00327
    00328   using std::arg;
    00329
    00330   template<typename _Tp>
    00331     inline typename __promote<_Tp>::__type
    00332     arg(_Tp __x)
    00333     {
    00334       typedef typename __promote<_Tp>::__type __type;
    00335       return std::arg(std::complex<__type>(__x));
    00336     }
    00337
    00338   using std::conj;
    00339
    00340   template<typename _Tp>
    00341     inline std::complex<typename __promote<_Tp>::__type>
    00342     conj(_Tp __x)
    00343     { return __x; }
    00344
    00345   using std::imag;
    00346
    00347   template<typename _Tp>
    00348     inline typename __promote<_Tp>::__type
    00349     imag(_Tp)
    00350     { return _Tp(); }
    00351
    00352   using std::norm;
    00353
    00354   template<typename _Tp>
    00355     inline typename __promote<_Tp>::__type
    00356     norm(_Tp __x)
    00357     {
    00358       typedef typename __promote<_Tp>::__type __type;
    00359       return __type(__x) * __type(__x);
    00360     }
    00361
    00362   using std::polar;
    00363
    00364   template<typename _Tp, typename _Up>
    00365     inline std::complex<typename __promote_2<_Tp, _Up>::__type>
    00366     polar(const _Tp& __rho, const _Up& __theta)
    00367     {
    00368       typedef typename __promote_2<_Tp, _Up>::__type __type;
    00369       return std::polar(__type(__rho), __type(__theta));
    00370     }
    00371
    00372   using std::pow;
    00373
    00374   template<typename _Tp, typename _Up>
    00375     inline std::complex<typename __promote_2<_Tp, _Up>::__type>
    00376     pow(const std::complex<_Tp>& __x, const _Up& __y)
    00377     {
    00378       typedef typename __promote_2<_Tp, _Up>::__type __type;
    00379       return std::pow(std::complex<__type>(__x), __type(__y));
    00380     }
    00381
    00382   template<typename _Tp, typename _Up>
    00383     inline std::complex<typename __promote_2<_Tp, _Up>::__type>
    00384     pow(const _Tp& __x, const std::complex<_Up>& __y)
    00385     {
    00386       typedef typename __promote_2<_Tp, _Up>::__type __type;
    00387       return std::pow(__type(__x), std::complex<__type>(__y));
    00388     }
    00389
    00390   template<typename _Tp, typename _Up>
    00391     inline std::complex<typename __promote_2<_Tp, _Up>::__type>
    00392     pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
    00393     {
    00394       typedef typename __promote_2<_Tp, _Up>::__type __type;
    00395       return std::pow(std::complex<__type>(__x),
    00396               std::complex<__type>(__y));
    00397     }
    00398
    00399   using std::real;
    00400
    00401   template<typename _Tp>
    00402     inline typename __promote<_Tp>::__type
    00403     real(_Tp __x)
    00404     { return __x; }
    00405
    00406 _GLIBCXX_END_NAMESPACE
    00407 }
    00408
    00409 #endif