]>
Commit | Line | Data |
---|---|---|
84a7b1fc PC |
1 | // TR1 complex -*- C++ -*- |
2 | ||
cbe34bb5 | 3 | // Copyright (C) 2006-2017 Free Software Foundation, Inc. |
84a7b1fc PC |
4 | // |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
84a7b1fc PC |
9 | // any later version. |
10 | ||
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. | |
15 | ||
748086b7 JJ |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
84a7b1fc | 24 | |
143c27b0 | 25 | /** @file tr1/complex |
84a7b1fc PC |
26 | * This is a TR1 C++ Library header. |
27 | */ | |
28 | ||
e133ace8 PC |
29 | #ifndef _GLIBCXX_TR1_COMPLEX |
30 | #define _GLIBCXX_TR1_COMPLEX 1 | |
84a7b1fc | 31 | |
e133ace8 | 32 | #pragma GCC system_header |
84a7b1fc | 33 | |
e133ace8 | 34 | #include <complex> |
84a7b1fc | 35 | |
12ffa228 | 36 | namespace std _GLIBCXX_VISIBILITY(default) |
e133ace8 | 37 | { |
12ffa228 BK |
38 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
39 | ||
4a15d842 FD |
40 | namespace tr1 |
41 | { | |
53dc5044 PC |
42 | /** |
43 | * @addtogroup complex_numbers | |
44 | * @{ | |
45 | */ | |
46 | ||
734f5023 | 47 | #if __cplusplus >= 201103L |
db094732 JW |
48 | using std::acos; |
49 | using std::asin; | |
50 | using std::atan; | |
9aee022e JW |
51 | using std::acosh; |
52 | using std::asinh; | |
53 | using std::atanh; | |
db094732 | 54 | #else |
53dc5044 PC |
55 | template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); |
56 | template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); | |
57 | template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); | |
53dc5044 PC |
58 | template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); |
59 | template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); | |
60 | template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); | |
9aee022e | 61 | #endif |
db094732 | 62 | |
9aee022e | 63 | // The std::fabs return type in C++11 mode is different (just _Tp). |
53dc5044 PC |
64 | template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); |
65 | ||
734f5023 | 66 | #if __cplusplus < 201103L |
53dc5044 PC |
67 | template<typename _Tp> |
68 | inline std::complex<_Tp> | |
69 | __complex_acos(const std::complex<_Tp>& __z) | |
70 | { | |
71 | const std::complex<_Tp> __t = std::tr1::asin(__z); | |
72 | const _Tp __pi_2 = 1.5707963267948966192313216916397514L; | |
73 | return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); | |
74 | } | |
75 | ||
76 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
77 | inline __complex__ float | |
78 | __complex_acos(__complex__ float __z) | |
79 | { return __builtin_cacosf(__z); } | |
80 | ||
81 | inline __complex__ double | |
82 | __complex_acos(__complex__ double __z) | |
83 | { return __builtin_cacos(__z); } | |
84 | ||
85 | inline __complex__ long double | |
86 | __complex_acos(const __complex__ long double& __z) | |
87 | { return __builtin_cacosl(__z); } | |
88 | ||
89 | template<typename _Tp> | |
90 | inline std::complex<_Tp> | |
91 | acos(const std::complex<_Tp>& __z) | |
92 | { return __complex_acos(__z.__rep()); } | |
93 | #else | |
94 | /// acos(__z) [8.1.2]. | |
95 | // Effects: Behaves the same as C99 function cacos, defined | |
96 | // in subclause 7.3.5.1. | |
97 | template<typename _Tp> | |
98 | inline std::complex<_Tp> | |
99 | acos(const std::complex<_Tp>& __z) | |
100 | { return __complex_acos(__z); } | |
101 | #endif | |
102 | ||
103 | template<typename _Tp> | |
104 | inline std::complex<_Tp> | |
105 | __complex_asin(const std::complex<_Tp>& __z) | |
106 | { | |
107 | std::complex<_Tp> __t(-__z.imag(), __z.real()); | |
108 | __t = std::tr1::asinh(__t); | |
109 | return std::complex<_Tp>(__t.imag(), -__t.real()); | |
110 | } | |
111 | ||
112 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
113 | inline __complex__ float | |
114 | __complex_asin(__complex__ float __z) | |
115 | { return __builtin_casinf(__z); } | |
116 | ||
117 | inline __complex__ double | |
118 | __complex_asin(__complex__ double __z) | |
119 | { return __builtin_casin(__z); } | |
120 | ||
121 | inline __complex__ long double | |
122 | __complex_asin(const __complex__ long double& __z) | |
123 | { return __builtin_casinl(__z); } | |
124 | ||
125 | template<typename _Tp> | |
126 | inline std::complex<_Tp> | |
127 | asin(const std::complex<_Tp>& __z) | |
128 | { return __complex_asin(__z.__rep()); } | |
129 | #else | |
130 | /// asin(__z) [8.1.3]. | |
131 | // Effects: Behaves the same as C99 function casin, defined | |
132 | // in subclause 7.3.5.2. | |
133 | template<typename _Tp> | |
134 | inline std::complex<_Tp> | |
135 | asin(const std::complex<_Tp>& __z) | |
136 | { return __complex_asin(__z); } | |
137 | #endif | |
138 | ||
139 | template<typename _Tp> | |
140 | std::complex<_Tp> | |
141 | __complex_atan(const std::complex<_Tp>& __z) | |
142 | { | |
143 | const _Tp __r2 = __z.real() * __z.real(); | |
144 | const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); | |
145 | ||
146 | _Tp __num = __z.imag() + _Tp(1.0); | |
147 | _Tp __den = __z.imag() - _Tp(1.0); | |
148 | ||
149 | __num = __r2 + __num * __num; | |
150 | __den = __r2 + __den * __den; | |
151 | ||
152 | return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), | |
153 | _Tp(0.25) * log(__num / __den)); | |
154 | } | |
155 | ||
156 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
157 | inline __complex__ float | |
158 | __complex_atan(__complex__ float __z) | |
159 | { return __builtin_catanf(__z); } | |
160 | ||
161 | inline __complex__ double | |
162 | __complex_atan(__complex__ double __z) | |
163 | { return __builtin_catan(__z); } | |
164 | ||
165 | inline __complex__ long double | |
166 | __complex_atan(const __complex__ long double& __z) | |
167 | { return __builtin_catanl(__z); } | |
168 | ||
169 | template<typename _Tp> | |
170 | inline std::complex<_Tp> | |
171 | atan(const std::complex<_Tp>& __z) | |
172 | { return __complex_atan(__z.__rep()); } | |
173 | #else | |
174 | /// atan(__z) [8.1.4]. | |
175 | // Effects: Behaves the same as C99 function catan, defined | |
176 | // in subclause 7.3.5.3. | |
177 | template<typename _Tp> | |
178 | inline std::complex<_Tp> | |
179 | atan(const std::complex<_Tp>& __z) | |
180 | { return __complex_atan(__z); } | |
181 | #endif | |
182 | ||
183 | template<typename _Tp> | |
184 | std::complex<_Tp> | |
185 | __complex_acosh(const std::complex<_Tp>& __z) | |
186 | { | |
af7c1858 RK |
187 | // Kahan's formula. |
188 | return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0))) | |
189 | + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0)))); | |
53dc5044 PC |
190 | } |
191 | ||
192 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
193 | inline __complex__ float | |
194 | __complex_acosh(__complex__ float __z) | |
195 | { return __builtin_cacoshf(__z); } | |
196 | ||
197 | inline __complex__ double | |
198 | __complex_acosh(__complex__ double __z) | |
199 | { return __builtin_cacosh(__z); } | |
200 | ||
201 | inline __complex__ long double | |
202 | __complex_acosh(const __complex__ long double& __z) | |
203 | { return __builtin_cacoshl(__z); } | |
204 | ||
205 | template<typename _Tp> | |
206 | inline std::complex<_Tp> | |
207 | acosh(const std::complex<_Tp>& __z) | |
208 | { return __complex_acosh(__z.__rep()); } | |
209 | #else | |
210 | /// acosh(__z) [8.1.5]. | |
211 | // Effects: Behaves the same as C99 function cacosh, defined | |
212 | // in subclause 7.3.6.1. | |
213 | template<typename _Tp> | |
214 | inline std::complex<_Tp> | |
215 | acosh(const std::complex<_Tp>& __z) | |
216 | { return __complex_acosh(__z); } | |
217 | #endif | |
218 | ||
219 | template<typename _Tp> | |
220 | std::complex<_Tp> | |
221 | __complex_asinh(const std::complex<_Tp>& __z) | |
222 | { | |
223 | std::complex<_Tp> __t((__z.real() - __z.imag()) | |
224 | * (__z.real() + __z.imag()) + _Tp(1.0), | |
225 | _Tp(2.0) * __z.real() * __z.imag()); | |
226 | __t = std::sqrt(__t); | |
227 | ||
228 | return std::log(__t + __z); | |
229 | } | |
230 | ||
231 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
232 | inline __complex__ float | |
233 | __complex_asinh(__complex__ float __z) | |
234 | { return __builtin_casinhf(__z); } | |
235 | ||
236 | inline __complex__ double | |
237 | __complex_asinh(__complex__ double __z) | |
238 | { return __builtin_casinh(__z); } | |
239 | ||
240 | inline __complex__ long double | |
241 | __complex_asinh(const __complex__ long double& __z) | |
242 | { return __builtin_casinhl(__z); } | |
243 | ||
244 | template<typename _Tp> | |
245 | inline std::complex<_Tp> | |
246 | asinh(const std::complex<_Tp>& __z) | |
247 | { return __complex_asinh(__z.__rep()); } | |
248 | #else | |
249 | /// asinh(__z) [8.1.6]. | |
250 | // Effects: Behaves the same as C99 function casin, defined | |
251 | // in subclause 7.3.6.2. | |
252 | template<typename _Tp> | |
253 | inline std::complex<_Tp> | |
254 | asinh(const std::complex<_Tp>& __z) | |
255 | { return __complex_asinh(__z); } | |
256 | #endif | |
257 | ||
258 | template<typename _Tp> | |
259 | std::complex<_Tp> | |
260 | __complex_atanh(const std::complex<_Tp>& __z) | |
261 | { | |
262 | const _Tp __i2 = __z.imag() * __z.imag(); | |
263 | const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); | |
264 | ||
265 | _Tp __num = _Tp(1.0) + __z.real(); | |
266 | _Tp __den = _Tp(1.0) - __z.real(); | |
267 | ||
268 | __num = __i2 + __num * __num; | |
269 | __den = __i2 + __den * __den; | |
270 | ||
271 | return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), | |
272 | _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); | |
273 | } | |
274 | ||
275 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
276 | inline __complex__ float | |
277 | __complex_atanh(__complex__ float __z) | |
278 | { return __builtin_catanhf(__z); } | |
279 | ||
280 | inline __complex__ double | |
281 | __complex_atanh(__complex__ double __z) | |
282 | { return __builtin_catanh(__z); } | |
283 | ||
284 | inline __complex__ long double | |
285 | __complex_atanh(const __complex__ long double& __z) | |
286 | { return __builtin_catanhl(__z); } | |
287 | ||
288 | template<typename _Tp> | |
289 | inline std::complex<_Tp> | |
290 | atanh(const std::complex<_Tp>& __z) | |
291 | { return __complex_atanh(__z.__rep()); } | |
292 | #else | |
293 | /// atanh(__z) [8.1.7]. | |
294 | // Effects: Behaves the same as C99 function catanh, defined | |
295 | // in subclause 7.3.6.3. | |
296 | template<typename _Tp> | |
297 | inline std::complex<_Tp> | |
298 | atanh(const std::complex<_Tp>& __z) | |
299 | { return __complex_atanh(__z); } | |
300 | #endif | |
301 | ||
9aee022e JW |
302 | #endif // C++11 |
303 | ||
53dc5044 PC |
304 | template<typename _Tp> |
305 | inline std::complex<_Tp> | |
306 | /// fabs(__z) [8.1.8]. | |
307 | // Effects: Behaves the same as C99 function cabs, defined | |
308 | // in subclause 7.3.8.1. | |
309 | fabs(const std::complex<_Tp>& __z) | |
310 | { return std::abs(__z); } | |
311 | ||
312 | /// Additional overloads [8.1.9]. | |
734f5023 | 313 | #if __cplusplus < 201103L |
53dc5044 PC |
314 | |
315 | template<typename _Tp> | |
316 | inline typename __gnu_cxx::__promote<_Tp>::__type | |
317 | arg(_Tp __x) | |
318 | { | |
319 | typedef typename __gnu_cxx::__promote<_Tp>::__type __type; | |
320 | #if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) | |
321 | return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L) | |
322 | : __type(); | |
323 | #else | |
324 | return std::arg(std::complex<__type>(__x)); | |
325 | #endif | |
326 | } | |
327 | ||
328 | template<typename _Tp> | |
329 | inline typename __gnu_cxx::__promote<_Tp>::__type | |
330 | imag(_Tp) | |
331 | { return _Tp(); } | |
332 | ||
333 | template<typename _Tp> | |
334 | inline typename __gnu_cxx::__promote<_Tp>::__type | |
335 | norm(_Tp __x) | |
336 | { | |
337 | typedef typename __gnu_cxx::__promote<_Tp>::__type __type; | |
338 | return __type(__x) * __type(__x); | |
339 | } | |
340 | ||
341 | template<typename _Tp> | |
342 | inline typename __gnu_cxx::__promote<_Tp>::__type | |
343 | real(_Tp __x) | |
344 | { return __x; } | |
345 | ||
346 | #endif | |
347 | ||
348 | template<typename _Tp, typename _Up> | |
349 | inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> | |
350 | pow(const std::complex<_Tp>& __x, const _Up& __y) | |
351 | { | |
352 | typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; | |
353 | return std::pow(std::complex<__type>(__x), __type(__y)); | |
354 | } | |
355 | ||
356 | template<typename _Tp, typename _Up> | |
357 | inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> | |
358 | pow(const _Tp& __x, const std::complex<_Up>& __y) | |
359 | { | |
360 | typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; | |
361 | return std::pow(__type(__x), std::complex<__type>(__y)); | |
362 | } | |
363 | ||
364 | template<typename _Tp, typename _Up> | |
365 | inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> | |
366 | pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) | |
367 | { | |
368 | typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; | |
369 | return std::pow(std::complex<__type>(__x), | |
370 | std::complex<__type>(__y)); | |
371 | } | |
372 | ||
9a7ab578 | 373 | using std::arg; |
c8699672 JW |
374 | |
375 | template<typename _Tp> | |
376 | inline std::complex<_Tp> | |
377 | conj(const std::complex<_Tp>& __z) | |
378 | { return std::conj(__z); } | |
379 | ||
380 | template<typename _Tp> | |
381 | inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type> | |
382 | conj(_Tp __x) | |
383 | { return __x; } | |
384 | ||
9a7ab578 | 385 | using std::imag; |
9a7ab578 | 386 | using std::norm; |
9a7ab578 | 387 | using std::polar; |
3cd54fc9 PC |
388 | |
389 | template<typename _Tp, typename _Up> | |
390 | inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> | |
391 | polar(const _Tp& __rho, const _Up& __theta) | |
392 | { | |
393 | typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; | |
394 | return std::polar(__type(__rho), __type(__theta)); | |
395 | } | |
396 | ||
9a7ab578 | 397 | using std::real; |
774c3d86 | 398 | |
774c3d86 PC |
399 | template<typename _Tp> |
400 | inline std::complex<_Tp> | |
401 | pow(const std::complex<_Tp>& __x, const _Tp& __y) | |
402 | { return std::pow(__x, __y); } | |
403 | ||
404 | template<typename _Tp> | |
405 | inline std::complex<_Tp> | |
406 | pow(const _Tp& __x, const std::complex<_Tp>& __y) | |
407 | { return std::pow(__x, __y); } | |
408 | ||
409 | template<typename _Tp> | |
410 | inline std::complex<_Tp> | |
411 | pow(const std::complex<_Tp>& __x, const std::complex<_Tp>& __y) | |
412 | { return std::pow(__x, __y); } | |
53dc5044 PC |
413 | |
414 | // @} group complex_numbers | |
4a15d842 | 415 | } |
12ffa228 BK |
416 | |
417 | _GLIBCXX_END_NAMESPACE_VERSION | |
e133ace8 | 418 | } |
84a7b1fc | 419 | |
e133ace8 | 420 | #endif // _GLIBCXX_TR1_COMPLEX |