]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/tr1_impl/complex
Licensing changes to GPLv3 resp. GPLv3 with GCC Runtime Exception.
[thirdparty/gcc.git] / libstdc++-v3 / include / tr1_impl / complex
1 // TR1 complex -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
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
8 // Free Software Foundation; either version 3, or (at your option)
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
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/>.
24
25 /** @file tr1_impl/complex
26 * This is an internal header file, included by other library headers.
27 * You should not attempt to use it directly.
28 */
29
30 namespace std
31 {
32 _GLIBCXX_BEGIN_NAMESPACE_TR1
33
34 /**
35 * @addtogroup complex_numbers
36 * @{
37 */
38
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>&);
43
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 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
48 // DR 595.
49 template<typename _Tp> _Tp fabs(const std::complex<_Tp>&);
50 #else
51 template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
52 #endif
53
54 template<typename _Tp>
55 inline std::complex<_Tp>
56 __complex_acos(const std::complex<_Tp>& __z)
57 {
58 const std::complex<_Tp> __t = std::_GLIBCXX_TR1 asin(__z);
59 const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
60 return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
61 }
62
63 #if _GLIBCXX_USE_C99_COMPLEX_TR1
64 inline __complex__ float
65 __complex_acos(__complex__ float __z)
66 { return __builtin_cacosf(__z); }
67
68 inline __complex__ double
69 __complex_acos(__complex__ double __z)
70 { return __builtin_cacos(__z); }
71
72 inline __complex__ long double
73 __complex_acos(const __complex__ long double& __z)
74 { return __builtin_cacosl(__z); }
75
76 template<typename _Tp>
77 inline std::complex<_Tp>
78 acos(const std::complex<_Tp>& __z)
79 { return __complex_acos(__z.__rep()); }
80 #else
81 /// acos(__z) [8.1.2].
82 // Effects: Behaves the same as C99 function cacos, defined
83 // in subclause 7.3.5.1.
84 template<typename _Tp>
85 inline std::complex<_Tp>
86 acos(const std::complex<_Tp>& __z)
87 { return __complex_acos(__z); }
88 #endif
89
90 template<typename _Tp>
91 inline std::complex<_Tp>
92 __complex_asin(const std::complex<_Tp>& __z)
93 {
94 std::complex<_Tp> __t(-__z.imag(), __z.real());
95 __t = std::_GLIBCXX_TR1 asinh(__t);
96 return std::complex<_Tp>(__t.imag(), -__t.real());
97 }
98
99 #if _GLIBCXX_USE_C99_COMPLEX_TR1
100 inline __complex__ float
101 __complex_asin(__complex__ float __z)
102 { return __builtin_casinf(__z); }
103
104 inline __complex__ double
105 __complex_asin(__complex__ double __z)
106 { return __builtin_casin(__z); }
107
108 inline __complex__ long double
109 __complex_asin(const __complex__ long double& __z)
110 { return __builtin_casinl(__z); }
111
112 template<typename _Tp>
113 inline std::complex<_Tp>
114 asin(const std::complex<_Tp>& __z)
115 { return __complex_asin(__z.__rep()); }
116 #else
117 /// asin(__z) [8.1.3].
118 // Effects: Behaves the same as C99 function casin, defined
119 // in subclause 7.3.5.2.
120 template<typename _Tp>
121 inline std::complex<_Tp>
122 asin(const std::complex<_Tp>& __z)
123 { return __complex_asin(__z); }
124 #endif
125
126 template<typename _Tp>
127 std::complex<_Tp>
128 __complex_atan(const std::complex<_Tp>& __z)
129 {
130 const _Tp __r2 = __z.real() * __z.real();
131 const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
132
133 _Tp __num = __z.imag() + _Tp(1.0);
134 _Tp __den = __z.imag() - _Tp(1.0);
135
136 __num = __r2 + __num * __num;
137 __den = __r2 + __den * __den;
138
139 return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
140 _Tp(0.25) * log(__num / __den));
141 }
142
143 #if _GLIBCXX_USE_C99_COMPLEX_TR1
144 inline __complex__ float
145 __complex_atan(__complex__ float __z)
146 { return __builtin_catanf(__z); }
147
148 inline __complex__ double
149 __complex_atan(__complex__ double __z)
150 { return __builtin_catan(__z); }
151
152 inline __complex__ long double
153 __complex_atan(const __complex__ long double& __z)
154 { return __builtin_catanl(__z); }
155
156 template<typename _Tp>
157 inline std::complex<_Tp>
158 atan(const std::complex<_Tp>& __z)
159 { return __complex_atan(__z.__rep()); }
160 #else
161 /// atan(__z) [8.1.4].
162 // Effects: Behaves the same as C99 function catan, defined
163 // in subclause 7.3.5.3.
164 template<typename _Tp>
165 inline std::complex<_Tp>
166 atan(const std::complex<_Tp>& __z)
167 { return __complex_atan(__z); }
168 #endif
169
170 template<typename _Tp>
171 std::complex<_Tp>
172 __complex_acosh(const std::complex<_Tp>& __z)
173 {
174 std::complex<_Tp> __t((__z.real() - __z.imag())
175 * (__z.real() + __z.imag()) - _Tp(1.0),
176 _Tp(2.0) * __z.real() * __z.imag());
177 __t = std::sqrt(__t);
178
179 return std::log(__t + __z);
180 }
181
182 #if _GLIBCXX_USE_C99_COMPLEX_TR1
183 inline __complex__ float
184 __complex_acosh(__complex__ float __z)
185 { return __builtin_cacoshf(__z); }
186
187 inline __complex__ double
188 __complex_acosh(__complex__ double __z)
189 { return __builtin_cacosh(__z); }
190
191 inline __complex__ long double
192 __complex_acosh(const __complex__ long double& __z)
193 { return __builtin_cacoshl(__z); }
194
195 template<typename _Tp>
196 inline std::complex<_Tp>
197 acosh(const std::complex<_Tp>& __z)
198 { return __complex_acosh(__z.__rep()); }
199 #else
200 /// acosh(__z) [8.1.5].
201 // Effects: Behaves the same as C99 function cacosh, defined
202 // in subclause 7.3.6.1.
203 template<typename _Tp>
204 inline std::complex<_Tp>
205 acosh(const std::complex<_Tp>& __z)
206 { return __complex_acosh(__z); }
207 #endif
208
209 template<typename _Tp>
210 std::complex<_Tp>
211 __complex_asinh(const std::complex<_Tp>& __z)
212 {
213 std::complex<_Tp> __t((__z.real() - __z.imag())
214 * (__z.real() + __z.imag()) + _Tp(1.0),
215 _Tp(2.0) * __z.real() * __z.imag());
216 __t = std::sqrt(__t);
217
218 return std::log(__t + __z);
219 }
220
221 #if _GLIBCXX_USE_C99_COMPLEX_TR1
222 inline __complex__ float
223 __complex_asinh(__complex__ float __z)
224 { return __builtin_casinhf(__z); }
225
226 inline __complex__ double
227 __complex_asinh(__complex__ double __z)
228 { return __builtin_casinh(__z); }
229
230 inline __complex__ long double
231 __complex_asinh(const __complex__ long double& __z)
232 { return __builtin_casinhl(__z); }
233
234 template<typename _Tp>
235 inline std::complex<_Tp>
236 asinh(const std::complex<_Tp>& __z)
237 { return __complex_asinh(__z.__rep()); }
238 #else
239 /// asinh(__z) [8.1.6].
240 // Effects: Behaves the same as C99 function casin, defined
241 // in subclause 7.3.6.2.
242 template<typename _Tp>
243 inline std::complex<_Tp>
244 asinh(const std::complex<_Tp>& __z)
245 { return __complex_asinh(__z); }
246 #endif
247
248 template<typename _Tp>
249 std::complex<_Tp>
250 __complex_atanh(const std::complex<_Tp>& __z)
251 {
252 const _Tp __i2 = __z.imag() * __z.imag();
253 const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
254
255 _Tp __num = _Tp(1.0) + __z.real();
256 _Tp __den = _Tp(1.0) - __z.real();
257
258 __num = __i2 + __num * __num;
259 __den = __i2 + __den * __den;
260
261 return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
262 _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
263 }
264
265 #if _GLIBCXX_USE_C99_COMPLEX_TR1
266 inline __complex__ float
267 __complex_atanh(__complex__ float __z)
268 { return __builtin_catanhf(__z); }
269
270 inline __complex__ double
271 __complex_atanh(__complex__ double __z)
272 { return __builtin_catanh(__z); }
273
274 inline __complex__ long double
275 __complex_atanh(const __complex__ long double& __z)
276 { return __builtin_catanhl(__z); }
277
278 template<typename _Tp>
279 inline std::complex<_Tp>
280 atanh(const std::complex<_Tp>& __z)
281 { return __complex_atanh(__z.__rep()); }
282 #else
283 /// atanh(__z) [8.1.7].
284 // Effects: Behaves the same as C99 function catanh, defined
285 // in subclause 7.3.6.3.
286 template<typename _Tp>
287 inline std::complex<_Tp>
288 atanh(const std::complex<_Tp>& __z)
289 { return __complex_atanh(__z); }
290 #endif
291
292 template<typename _Tp>
293 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
294 inline _Tp
295 #else
296 inline std::complex<_Tp>
297 #endif
298 /// fabs(__z) [8.1.8].
299 // Effects: Behaves the same as C99 function cabs, defined
300 // in subclause 7.3.8.1.
301 fabs(const std::complex<_Tp>& __z)
302 { return std::abs(__z); }
303
304 /// Additional overloads [8.1.9].
305 #if (defined(_GLIBCXX_INCLUDE_AS_CXX0X) \
306 || (defined(_GLIBCXX_INCLUDE_AS_TR1) \
307 && !defined(__GXX_EXPERIMENTAL_CXX0X__)))
308
309 template<typename _Tp>
310 inline typename __gnu_cxx::__promote<_Tp>::__type
311 arg(_Tp __x)
312 {
313 typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
314 return std::arg(std::complex<__type>(__x));
315 }
316
317 template<typename _Tp>
318 inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
319 conj(_Tp __x)
320 { return __x; }
321
322 template<typename _Tp>
323 inline typename __gnu_cxx::__promote<_Tp>::__type
324 imag(_Tp)
325 { return _Tp(); }
326
327 template<typename _Tp>
328 inline typename __gnu_cxx::__promote<_Tp>::__type
329 norm(_Tp __x)
330 {
331 typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
332 return __type(__x) * __type(__x);
333 }
334
335 template<typename _Tp>
336 inline typename __gnu_cxx::__promote<_Tp>::__type
337 real(_Tp __x)
338 { return __x; }
339
340 #endif
341
342 template<typename _Tp, typename _Up>
343 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
344 pow(const std::complex<_Tp>& __x, const _Up& __y)
345 {
346 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
347 return std::pow(std::complex<__type>(__x), __type(__y));
348 }
349
350 template<typename _Tp, typename _Up>
351 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
352 pow(const _Tp& __x, const std::complex<_Up>& __y)
353 {
354 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
355 return std::pow(__type(__x), std::complex<__type>(__y));
356 }
357
358 template<typename _Tp, typename _Up>
359 inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
360 pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
361 {
362 typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
363 return std::pow(std::complex<__type>(__x),
364 std::complex<__type>(__y));
365 }
366
367 // @} group complex_numbers
368
369 _GLIBCXX_END_NAMESPACE_TR1
370 }