libstdc++
|
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 }