1 // TR1 complex -*- C++ -*-
3 // Copyright (C) 2007 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 2, 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 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 /** @file tr1_impl/complex
31 * This is an internal header file, included by other library headers.
32 * You should not attempt to use it directly.
37 _GLIBCXX_BEGIN_NAMESPACE_TR1
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>&);
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 template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
49 /// @brief acos(__z) [8.1.2].
50 // Effects: Behaves the same as C99 function cacos, defined
51 // in subclause 7.3.5.1.
52 template<typename _Tp>
53 inline std::complex<_Tp>
54 __complex_acos(const std::complex<_Tp>& __z)
56 const std::complex<_Tp> __t = std::_GLIBCXX_TR1 asin(__z);
57 const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
58 return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
61 #if _GLIBCXX_USE_C99_COMPLEX_TR1
62 inline __complex__ float
63 __complex_acos(__complex__ float __z)
64 { return __builtin_cacosf(__z); }
66 inline __complex__ double
67 __complex_acos(__complex__ double __z)
68 { return __builtin_cacos(__z); }
70 inline __complex__ long double
71 __complex_acos(const __complex__ long double& __z)
72 { return __builtin_cacosl(__z); }
74 template<typename _Tp>
75 inline std::complex<_Tp>
76 acos(const std::complex<_Tp>& __z)
77 { return __complex_acos(__z.__rep()); }
79 template<typename _Tp>
80 inline std::complex<_Tp>
81 acos(const std::complex<_Tp>& __z)
82 { return __complex_acos(__z); }
85 /// @brief asin(__z) [8.1.3].
86 // Effects: Behaves the same as C99 function casin, defined
87 // in subclause 7.3.5.2.
88 template<typename _Tp>
89 inline std::complex<_Tp>
90 __complex_asin(const std::complex<_Tp>& __z)
92 std::complex<_Tp> __t(-__z.imag(), __z.real());
93 __t = std::_GLIBCXX_TR1 asinh(__t);
94 return std::complex<_Tp>(__t.imag(), -__t.real());
97 #if _GLIBCXX_USE_C99_COMPLEX_TR1
98 inline __complex__ float
99 __complex_asin(__complex__ float __z)
100 { return __builtin_casinf(__z); }
102 inline __complex__ double
103 __complex_asin(__complex__ double __z)
104 { return __builtin_casin(__z); }
106 inline __complex__ long double
107 __complex_asin(const __complex__ long double& __z)
108 { return __builtin_casinl(__z); }
110 template<typename _Tp>
111 inline std::complex<_Tp>
112 asin(const std::complex<_Tp>& __z)
113 { return __complex_asin(__z.__rep()); }
115 template<typename _Tp>
116 inline std::complex<_Tp>
117 asin(const std::complex<_Tp>& __z)
118 { return __complex_asin(__z); }
121 /// @brief atan(__z) [8.1.4].
122 // Effects: Behaves the same as C99 function catan, defined
123 // in subclause 7.3.5.3.
124 template<typename _Tp>
126 __complex_atan(const std::complex<_Tp>& __z)
128 const _Tp __r2 = __z.real() * __z.real();
129 const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
131 _Tp __num = __z.imag() + _Tp(1.0);
132 _Tp __den = __z.imag() - _Tp(1.0);
134 __num = __r2 + __num * __num;
135 __den = __r2 + __den * __den;
137 return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
138 _Tp(0.25) * log(__num / __den));
141 #if _GLIBCXX_USE_C99_COMPLEX_TR1
142 inline __complex__ float
143 __complex_atan(__complex__ float __z)
144 { return __builtin_catanf(__z); }
146 inline __complex__ double
147 __complex_atan(__complex__ double __z)
148 { return __builtin_catan(__z); }
150 inline __complex__ long double
151 __complex_atan(const __complex__ long double& __z)
152 { return __builtin_catanl(__z); }
154 template<typename _Tp>
155 inline std::complex<_Tp>
156 atan(const std::complex<_Tp>& __z)
157 { return __complex_atan(__z.__rep()); }
159 template<typename _Tp>
160 inline std::complex<_Tp>
161 atan(const std::complex<_Tp>& __z)
162 { return __complex_atan(__z); }
165 /// @brief acosh(__z) [8.1.5].
166 // Effects: Behaves the same as C99 function cacosh, defined
167 // in subclause 7.3.6.1.
168 template<typename _Tp>
170 __complex_acosh(const std::complex<_Tp>& __z)
172 std::complex<_Tp> __t((__z.real() - __z.imag())
173 * (__z.real() + __z.imag()) - _Tp(1.0),
174 _Tp(2.0) * __z.real() * __z.imag());
175 __t = std::sqrt(__t);
177 return std::log(__t + __z);
180 #if _GLIBCXX_USE_C99_COMPLEX_TR1
181 inline __complex__ float
182 __complex_acosh(__complex__ float __z)
183 { return __builtin_cacoshf(__z); }
185 inline __complex__ double
186 __complex_acosh(__complex__ double __z)
187 { return __builtin_cacosh(__z); }
189 inline __complex__ long double
190 __complex_acosh(const __complex__ long double& __z)
191 { return __builtin_cacoshl(__z); }
193 template<typename _Tp>
194 inline std::complex<_Tp>
195 acosh(const std::complex<_Tp>& __z)
196 { return __complex_acosh(__z.__rep()); }
198 template<typename _Tp>
199 inline std::complex<_Tp>
200 acosh(const std::complex<_Tp>& __z)
201 { return __complex_acosh(__z); }
204 /// @brief asinh(__z) [8.1.6].
205 // Effects: Behaves the same as C99 function casin, defined
206 // in subclause 7.3.6.2.
207 template<typename _Tp>
209 __complex_asinh(const std::complex<_Tp>& __z)
211 std::complex<_Tp> __t((__z.real() - __z.imag())
212 * (__z.real() + __z.imag()) + _Tp(1.0),
213 _Tp(2.0) * __z.real() * __z.imag());
214 __t = std::sqrt(__t);
216 return std::log(__t + __z);
219 #if _GLIBCXX_USE_C99_COMPLEX_TR1
220 inline __complex__ float
221 __complex_asinh(__complex__ float __z)
222 { return __builtin_casinhf(__z); }
224 inline __complex__ double
225 __complex_asinh(__complex__ double __z)
226 { return __builtin_casinh(__z); }
228 inline __complex__ long double
229 __complex_asinh(const __complex__ long double& __z)
230 { return __builtin_casinhl(__z); }
232 template<typename _Tp>
233 inline std::complex<_Tp>
234 asinh(const std::complex<_Tp>& __z)
235 { return __complex_asinh(__z.__rep()); }
237 template<typename _Tp>
238 inline std::complex<_Tp>
239 asinh(const std::complex<_Tp>& __z)
240 { return __complex_asinh(__z); }
243 /// @brief atanh(__z) [8.1.7].
244 // Effects: Behaves the same as C99 function catanh, defined
245 // in subclause 7.3.6.3.
246 template<typename _Tp>
248 __complex_atanh(const std::complex<_Tp>& __z)
250 const _Tp __i2 = __z.imag() * __z.imag();
251 const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
253 _Tp __num = _Tp(1.0) + __z.real();
254 _Tp __den = _Tp(1.0) - __z.real();
256 __num = __i2 + __num * __num;
257 __den = __i2 + __den * __den;
259 return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
260 _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
263 #if _GLIBCXX_USE_C99_COMPLEX_TR1
264 inline __complex__ float
265 __complex_atanh(__complex__ float __z)
266 { return __builtin_catanhf(__z); }
268 inline __complex__ double
269 __complex_atanh(__complex__ double __z)
270 { return __builtin_catanh(__z); }
272 inline __complex__ long double
273 __complex_atanh(const __complex__ long double& __z)
274 { return __builtin_catanhl(__z); }
276 template<typename _Tp>
277 inline std::complex<_Tp>
278 atanh(const std::complex<_Tp>& __z)
279 { return __complex_atanh(__z.__rep()); }
281 template<typename _Tp>
282 inline std::complex<_Tp>
283 atanh(const std::complex<_Tp>& __z)
284 { return __complex_atanh(__z); }
287 /// @brief fabs(__z) [8.1.8].
288 // Effects: Behaves the same as C99 function cabs, defined
289 // in subclause 7.3.8.1.
290 template<typename _Tp>
291 inline std::complex<_Tp>
292 fabs(const std::complex<_Tp>& __z)
293 { return std::abs(__z); }
296 #if (defined(_GLIBCXX_INCLUDE_AS_CXX0X) \
297 || (defined(_GLIBCXX_INCLUDE_AS_TR1) \
298 && !defined(__GXX_EXPERIMENTAL_CXX0X__)))
300 /// @brief Additional overloads [8.1.9].
302 template<typename _Tp>
303 inline typename __gnu_cxx::__promote<_Tp>::__type
306 typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
307 return std::arg(std::complex<__type>(__x));
310 template<typename _Tp>
311 inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
315 template<typename _Tp>
316 inline typename __gnu_cxx::__promote<_Tp>::__type
320 template<typename _Tp>
321 inline typename __gnu_cxx::__promote<_Tp>::__type
324 typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
325 return __type(__x) * __type(__x);
328 template<typename _Tp, typename _Up>
329 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
330 polar(const _Tp& __rho, const _Up& __theta)
332 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
333 return std::polar(__type(__rho), __type(__theta));
336 template<typename _Tp, typename _Up>
337 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
338 pow(const std::complex<_Tp>& __x, const _Up& __y)
340 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
341 return std::pow(std::complex<__type>(__x), __type(__y));
344 template<typename _Tp, typename _Up>
345 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
346 pow(const _Tp& __x, const std::complex<_Up>& __y)
348 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
349 return std::pow(__type(__x), std::complex<__type>(__y));
352 template<typename _Tp, typename _Up>
353 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
354 pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
356 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
357 return std::pow(std::complex<__type>(__x),
358 std::complex<__type>(__y));
361 template<typename _Tp>
362 inline typename __gnu_cxx::__promote<_Tp>::__type
368 _GLIBCXX_END_NAMESPACE_TR1