libstdc++
tr1_impl/complex
Go to the documentation of this file.
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>
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>
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>
206  { return __complex_acosh(__z); }
207 #endif
208 
209  template<typename _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>
245  { return __complex_asinh(__z); }
246 #endif
247 
248  template<typename _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>
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>
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>
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>
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>
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 }
complex< _Tp > log(const complex< _Tp > &)
Return complex natural logarithm of z.
Definition: complex:782
complex< _Tp > sqrt(const complex< _Tp > &)
Return complex square root of z.
Definition: complex:891
_Tp arg(const complex< _Tp > &)
Return phase angle of z.
Definition: complex:621
complex< _Tp > pow(const complex< _Tp > &, const _Tp &)
Return x to the y'th power.
Definition: complex:964
std::complex< _Tp > asinh(const std::complex< _Tp > &)
asinh(__z) [8.1.6].
std::complex< _Tp > atanh(const std::complex< _Tp > &)
atanh(__z) [8.1.7].
complex< _Tp > conj(const complex< _Tp > &)
Return complex conjugate of z.
Definition: complex:667
_Tp norm(const complex< _Tp > &)
Return z magnitude squared.
Definition: complex:654
_Tp abs(const complex< _Tp > &)
Return magnitude of z.
Definition: complex:594
std::complex< _Tp > acosh(const std::complex< _Tp > &)
acosh(__z) [8.1.5].