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