1 // TR1 complex -*- C++ -*-
3 // Copyright (C) 2006 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.
31 * This is a TR1 C++ Library header.
35 #define _TR1_COMPLEX 1
38 #include <tr1/common.h>
43 _GLIBCXX_BEGIN_NAMESPACE(tr1)
45 // Forward declarations.
46 template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
47 template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
48 template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
50 template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
51 template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
52 template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
53 template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
55 /// @brief acos(__z) [8.1.2].
56 // Effects: Behaves the same as C99 function cacos, defined
57 // in subclause 7.3.5.1.
58 template<typename _Tp>
59 inline std::complex<_Tp>
60 __complex_acos(const std::complex<_Tp>& __z)
62 const std::complex<_Tp> __t = std::tr1::asin(__z);
63 const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
64 return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
67 #if _GLIBCXX_USE_C99_COMPLEX_TR1
68 inline __complex__ float
69 __complex_acos(__complex__ float __z)
70 { return __builtin_cacosf(__z); }
72 inline __complex__ double
73 __complex_acos(__complex__ double __z)
74 { return __builtin_cacos(__z); }
76 inline __complex__ long double
77 __complex_acos(const __complex__ long double& __z)
78 { return __builtin_cacosl(__z); }
80 template<typename _Tp>
81 inline std::complex<_Tp>
82 acos(const std::complex<_Tp>& __z)
83 { return __complex_acos(__z.__rep()); }
85 template<typename _Tp>
86 inline std::complex<_Tp>
87 acos(const std::complex<_Tp>& __z)
88 { return __complex_acos(__z); }
91 /// @brief asin(__z) [8.1.3].
92 // Effects: Behaves the same as C99 function casin, defined
93 // in subclause 7.3.5.2.
94 template<typename _Tp>
95 inline std::complex<_Tp>
96 __complex_asin(const std::complex<_Tp>& __z)
98 std::complex<_Tp> __t(-__z.imag(), __z.real());
99 __t = std::tr1::asinh(__t);
100 return std::complex<_Tp>(__t.imag(), -__t.real());
103 #if _GLIBCXX_USE_C99_COMPLEX_TR1
104 inline __complex__ float
105 __complex_asin(__complex__ float __z)
106 { return __builtin_casinf(__z); }
108 inline __complex__ double
109 __complex_asin(__complex__ double __z)
110 { return __builtin_casin(__z); }
112 inline __complex__ long double
113 __complex_asin(const __complex__ long double& __z)
114 { return __builtin_casinl(__z); }
116 template<typename _Tp>
117 inline std::complex<_Tp>
118 asin(const std::complex<_Tp>& __z)
119 { return __complex_asin(__z.__rep()); }
121 template<typename _Tp>
122 inline std::complex<_Tp>
123 asin(const std::complex<_Tp>& __z)
124 { return __complex_asin(__z); }
127 /// @brief atan(__z) [8.1.4].
128 // Effects: Behaves the same as C99 function catan, defined
129 // in subclause 7.3.5.3.
130 template<typename _Tp>
132 __complex_atan(const std::complex<_Tp>& __z)
134 const _Tp __r2 = __z.real() * __z.real();
135 const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
137 _Tp __num = __z.imag() + _Tp(1.0);
138 _Tp __den = __z.imag() - _Tp(1.0);
140 __num = __r2 + __num * __num;
141 __den = __r2 + __den * __den;
143 return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
144 _Tp(0.25) * log(__num / __den));
147 #if _GLIBCXX_USE_C99_COMPLEX_TR1
148 inline __complex__ float
149 __complex_atan(__complex__ float __z)
150 { return __builtin_catanf(__z); }
152 inline __complex__ double
153 __complex_atan(__complex__ double __z)
154 { return __builtin_catan(__z); }
156 inline __complex__ long double
157 __complex_atan(const __complex__ long double& __z)
158 { return __builtin_catanl(__z); }
160 template<typename _Tp>
161 inline std::complex<_Tp>
162 atan(const std::complex<_Tp>& __z)
163 { return __complex_atan(__z.__rep()); }
165 template<typename _Tp>
166 inline std::complex<_Tp>
167 atan(const std::complex<_Tp>& __z)
168 { return __complex_atan(__z); }
171 /// @brief acosh(__z) [8.1.5].
172 // Effects: Behaves the same as C99 function cacosh, defined
173 // in subclause 7.3.6.1.
174 template<typename _Tp>
176 __complex_acosh(const std::complex<_Tp>& __z)
178 std::complex<_Tp> __t((__z.real() - __z.imag())
179 * (__z.real() + __z.imag()) - _Tp(1.0),
180 _Tp(2.0) * __z.real() * __z.imag());
181 __t = std::sqrt(__t);
183 return std::log(__t + __z);
186 #if _GLIBCXX_USE_C99_COMPLEX_TR1
187 inline __complex__ float
188 __complex_acosh(__complex__ float __z)
189 { return __builtin_cacoshf(__z); }
191 inline __complex__ double
192 __complex_acosh(__complex__ double __z)
193 { return __builtin_cacosh(__z); }
195 inline __complex__ long double
196 __complex_acosh(const __complex__ long double& __z)
197 { return __builtin_cacoshl(__z); }
199 template<typename _Tp>
200 inline std::complex<_Tp>
201 acosh(const std::complex<_Tp>& __z)
202 { return __complex_acosh(__z.__rep()); }
204 template<typename _Tp>
205 inline std::complex<_Tp>
206 acosh(const std::complex<_Tp>& __z)
207 { return __complex_acosh(__z); }
210 /// @brief asinh(__z) [8.1.6].
211 // Effects: Behaves the same as C99 function casin, defined
212 // in subclause 7.3.6.2.
213 template<typename _Tp>
215 __complex_asinh(const std::complex<_Tp>& __z)
217 std::complex<_Tp> __t((__z.real() - __z.imag())
218 * (__z.real() + __z.imag()) + _Tp(1.0),
219 _Tp(2.0) * __z.real() * __z.imag());
220 __t = std::sqrt(__t);
222 return std::log(__t + __z);
225 #if _GLIBCXX_USE_C99_COMPLEX_TR1
226 inline __complex__ float
227 __complex_asinh(__complex__ float __z)
228 { return __builtin_casinhf(__z); }
230 inline __complex__ double
231 __complex_asinh(__complex__ double __z)
232 { return __builtin_casinh(__z); }
234 inline __complex__ long double
235 __complex_asinh(const __complex__ long double& __z)
236 { return __builtin_casinhl(__z); }
238 template<typename _Tp>
239 inline std::complex<_Tp>
240 asinh(const std::complex<_Tp>& __z)
241 { return __complex_asinh(__z.__rep()); }
243 template<typename _Tp>
244 inline std::complex<_Tp>
245 asinh(const std::complex<_Tp>& __z)
246 { return __complex_asinh(__z); }
249 /// @brief atanh(__z) [8.1.7].
250 // Effects: Behaves the same as C99 function catanh, defined
251 // in subclause 7.3.6.3.
252 template<typename _Tp>
254 __complex_atanh(const std::complex<_Tp>& __z)
256 const _Tp __i2 = __z.imag() * __z.imag();
257 const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
259 _Tp __num = _Tp(1.0) + __z.real();
260 _Tp __den = _Tp(1.0) - __z.real();
262 __num = __i2 + __num * __num;
263 __den = __i2 + __den * __den;
265 return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
266 _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
269 #if _GLIBCXX_USE_C99_COMPLEX_TR1
270 inline __complex__ float
271 __complex_atanh(__complex__ float __z)
272 { return __builtin_catanhf(__z); }
274 inline __complex__ double
275 __complex_atanh(__complex__ double __z)
276 { return __builtin_catanh(__z); }
278 inline __complex__ long double
279 __complex_atanh(const __complex__ long double& __z)
280 { return __builtin_catanhl(__z); }
282 template<typename _Tp>
283 inline std::complex<_Tp>
284 atanh(const std::complex<_Tp>& __z)
285 { return __complex_atanh(__z.__rep()); }
287 template<typename _Tp>
288 inline std::complex<_Tp>
289 atanh(const std::complex<_Tp>& __z)
290 { return __complex_atanh(__z); }
293 /// @brief fabs(__z) [8.1.8].
294 // Effects: Behaves the same as C99 function cabs, defined
295 // in subclause 7.3.8.1.
296 template<typename _Tp>
297 inline std::complex<_Tp>
298 fabs(const std::complex<_Tp>& __z)
299 { return std::abs(__z); }
302 /// @brief Additional overloads [8.1.9].
305 // See common.h for the primary template.
306 template<typename _Tp, typename _Up>
307 struct __promote_2<std::complex<_Tp>, _Up>
310 typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
313 template<typename _Tp, typename _Up>
314 struct __promote_2<_Tp, std::complex<_Up> >
317 typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
320 template<typename _Tp, typename _Up>
321 struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
324 typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
330 template<typename _Tp>
331 inline typename __promote<_Tp>::__type
334 typedef typename __promote<_Tp>::__type __type;
335 return std::arg(std::complex<__type>(__x));
340 template<typename _Tp>
341 inline std::complex<typename __promote<_Tp>::__type>
347 template<typename _Tp>
348 inline typename __promote<_Tp>::__type
354 template<typename _Tp>
355 inline typename __promote<_Tp>::__type
358 typedef typename __promote<_Tp>::__type __type;
359 return __type(__x) * __type(__x);
364 template<typename _Tp, typename _Up>
365 inline std::complex<typename __promote_2<_Tp, _Up>::__type>
366 polar(const _Tp& __rho, const _Up& __theta)
368 typedef typename __promote_2<_Tp, _Up>::__type __type;
369 return std::polar(__type(__rho), __type(__theta));
374 template<typename _Tp, typename _Up>
375 inline std::complex<typename __promote_2<_Tp, _Up>::__type>
376 pow(const std::complex<_Tp>& __x, const _Up& __y)
378 typedef typename __promote_2<_Tp, _Up>::__type __type;
379 return std::pow(std::complex<__type>(__x), __type(__y));
382 template<typename _Tp, typename _Up>
383 inline std::complex<typename __promote_2<_Tp, _Up>::__type>
384 pow(const _Tp& __x, const std::complex<_Up>& __y)
386 typedef typename __promote_2<_Tp, _Up>::__type __type;
387 return std::pow(__type(__x), std::complex<__type>(__y));
390 template<typename _Tp, typename _Up>
391 inline std::complex<typename __promote_2<_Tp, _Up>::__type>
392 pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
394 typedef typename __promote_2<_Tp, _Up>::__type __type;
395 return std::pow(std::complex<__type>(__x),
396 std::complex<__type>(__y));
401 template<typename _Tp>
402 inline typename __promote<_Tp>::__type
406 _GLIBCXX_END_NAMESPACE