1169691Skan// TR1 complex -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2006 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the
7169691Skan// terms of the GNU General Public License as published by the
8169691Skan// Free Software Foundation; either version 2, or (at your option)
9169691Skan// any later version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful,
12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169691Skan// GNU General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License along
17169691Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19169691Skan// USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free software
22169691Skan// library without restriction.  Specifically, if other files instantiate
23169691Skan// templates or use macros or inline functions from this file, or you compile
24169691Skan// this file and link it with other files to produce an executable, this
25169691Skan// file does not by itself cause the resulting executable to be covered by
26169691Skan// the GNU General Public License.  This exception does not however
27169691Skan// invalidate any other reasons why the executable file might be covered by
28169691Skan// the GNU General Public License.
29169691Skan
30169691Skan/** @file tr1/complex
31169691Skan *  This is a TR1 C++ Library header. 
32169691Skan */
33169691Skan
34169691Skan#ifndef _TR1_COMPLEX
35169691Skan#define _TR1_COMPLEX 1
36169691Skan
37169691Skan#include "../complex"
38169691Skan#include <tr1/common.h>
39169691Skan
40169691Skan// namespace std::tr1
41169691Skannamespace std
42169691Skan{
43169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1)
44169691Skan
45169691Skan  // Forward declarations.
46169691Skan  template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
47169691Skan  template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
48169691Skan  template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
49169691Skan
50169691Skan  template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
51169691Skan  template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
52169691Skan  template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
53169691Skan  template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
54169691Skan
55169691Skan  /// @brief acos(__z) [8.1.2].
56169691Skan  //  Effects:  Behaves the same as C99 function cacos, defined
57169691Skan  //            in subclause 7.3.5.1.
58169691Skan  template<typename _Tp>
59169691Skan    inline std::complex<_Tp>
60169691Skan    __complex_acos(const std::complex<_Tp>& __z)
61169691Skan    {
62169691Skan      const std::complex<_Tp> __t = std::tr1::asin(__z);
63169691Skan      const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
64169691Skan      return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
65169691Skan    }
66169691Skan
67169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1
68169691Skan  inline __complex__ float
69169691Skan  __complex_acos(__complex__ float __z)
70169691Skan  { return __builtin_cacosf(__z); }
71169691Skan
72169691Skan  inline __complex__ double
73169691Skan  __complex_acos(__complex__ double __z)
74169691Skan  { return __builtin_cacos(__z); }
75169691Skan
76169691Skan  inline __complex__ long double
77169691Skan  __complex_acos(const __complex__ long double& __z)
78169691Skan  { return __builtin_cacosl(__z); }
79169691Skan
80169691Skan  template<typename _Tp>
81169691Skan    inline std::complex<_Tp>
82169691Skan    acos(const std::complex<_Tp>& __z)
83169691Skan    { return __complex_acos(__z.__rep()); }
84169691Skan#else
85169691Skan  template<typename _Tp>
86169691Skan    inline std::complex<_Tp>
87169691Skan    acos(const std::complex<_Tp>& __z)
88169691Skan    { return __complex_acos(__z); }
89169691Skan#endif
90169691Skan
91169691Skan  /// @brief asin(__z) [8.1.3].
92169691Skan  //  Effects:  Behaves the same as C99 function casin, defined
93169691Skan  //            in subclause 7.3.5.2.
94169691Skan  template<typename _Tp>
95169691Skan    inline std::complex<_Tp>
96169691Skan    __complex_asin(const std::complex<_Tp>& __z)
97169691Skan    {
98169691Skan      std::complex<_Tp> __t(-__z.imag(), __z.real());
99169691Skan      __t = std::tr1::asinh(__t);
100169691Skan      return std::complex<_Tp>(__t.imag(), -__t.real());
101169691Skan    }
102169691Skan
103169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1
104169691Skan  inline __complex__ float
105169691Skan  __complex_asin(__complex__ float __z)
106169691Skan  { return __builtin_casinf(__z); }
107169691Skan
108169691Skan  inline __complex__ double
109169691Skan  __complex_asin(__complex__ double __z)
110169691Skan  { return __builtin_casin(__z); }
111169691Skan
112169691Skan  inline __complex__ long double
113169691Skan  __complex_asin(const __complex__ long double& __z)
114169691Skan  { return __builtin_casinl(__z); }
115169691Skan
116169691Skan  template<typename _Tp>
117169691Skan    inline std::complex<_Tp>
118169691Skan    asin(const std::complex<_Tp>& __z)
119169691Skan    { return __complex_asin(__z.__rep()); }
120169691Skan#else
121169691Skan  template<typename _Tp>
122169691Skan    inline std::complex<_Tp>
123169691Skan    asin(const std::complex<_Tp>& __z)
124169691Skan    { return __complex_asin(__z); }
125169691Skan#endif
126169691Skan  
127169691Skan  /// @brief atan(__z) [8.1.4].
128169691Skan  //  Effects:  Behaves the same as C99 function catan, defined
129169691Skan  //            in subclause 7.3.5.3.
130169691Skan  template<typename _Tp>
131169691Skan    std::complex<_Tp>
132169691Skan    __complex_atan(const std::complex<_Tp>& __z)
133169691Skan    {
134169691Skan      const _Tp __r2 = __z.real() * __z.real();
135169691Skan      const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
136169691Skan
137169691Skan      _Tp __num = __z.imag() + _Tp(1.0);
138169691Skan      _Tp __den = __z.imag() - _Tp(1.0);
139169691Skan
140169691Skan      __num = __r2 + __num * __num;
141169691Skan      __den = __r2 + __den * __den;
142169691Skan
143169691Skan      return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
144169691Skan			       _Tp(0.25) * log(__num / __den));
145169691Skan    }
146169691Skan
147169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1
148169691Skan  inline __complex__ float
149169691Skan  __complex_atan(__complex__ float __z)
150169691Skan  { return __builtin_catanf(__z); }
151169691Skan
152169691Skan  inline __complex__ double
153169691Skan  __complex_atan(__complex__ double __z)
154169691Skan  { return __builtin_catan(__z); }
155169691Skan
156169691Skan  inline __complex__ long double
157169691Skan  __complex_atan(const __complex__ long double& __z)
158169691Skan  { return __builtin_catanl(__z); }
159169691Skan
160169691Skan  template<typename _Tp>
161169691Skan    inline std::complex<_Tp>
162169691Skan    atan(const std::complex<_Tp>& __z)
163169691Skan    { return __complex_atan(__z.__rep()); }
164169691Skan#else
165169691Skan  template<typename _Tp>
166169691Skan    inline std::complex<_Tp>
167169691Skan    atan(const std::complex<_Tp>& __z)
168169691Skan    { return __complex_atan(__z); }
169169691Skan#endif
170169691Skan
171169691Skan  /// @brief acosh(__z) [8.1.5].
172169691Skan  //  Effects:  Behaves the same as C99 function cacosh, defined
173169691Skan  //            in subclause 7.3.6.1.
174169691Skan  template<typename _Tp>
175169691Skan    std::complex<_Tp>
176169691Skan    __complex_acosh(const std::complex<_Tp>& __z)
177169691Skan    {
178169691Skan      std::complex<_Tp> __t((__z.real() - __z.imag())
179169691Skan			    * (__z.real() + __z.imag()) - _Tp(1.0),
180169691Skan			    _Tp(2.0) * __z.real() * __z.imag());
181169691Skan      __t = std::sqrt(__t);
182169691Skan
183169691Skan      return std::log(__t + __z);
184169691Skan    }
185169691Skan
186169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1
187169691Skan  inline __complex__ float
188169691Skan  __complex_acosh(__complex__ float __z)
189169691Skan  { return __builtin_cacoshf(__z); }
190169691Skan
191169691Skan  inline __complex__ double
192169691Skan  __complex_acosh(__complex__ double __z)
193169691Skan  { return __builtin_cacosh(__z); }
194169691Skan
195169691Skan  inline __complex__ long double
196169691Skan  __complex_acosh(const __complex__ long double& __z)
197169691Skan  { return __builtin_cacoshl(__z); }
198169691Skan
199169691Skan  template<typename _Tp>
200169691Skan    inline std::complex<_Tp>
201169691Skan    acosh(const std::complex<_Tp>& __z)
202169691Skan    { return __complex_acosh(__z.__rep()); }
203169691Skan#else
204169691Skan  template<typename _Tp>
205169691Skan    inline std::complex<_Tp>
206169691Skan    acosh(const std::complex<_Tp>& __z)
207169691Skan    { return __complex_acosh(__z); }
208169691Skan#endif
209169691Skan
210169691Skan  /// @brief asinh(__z) [8.1.6].
211169691Skan  //  Effects:  Behaves the same as C99 function casin, defined
212169691Skan  //            in subclause 7.3.6.2.
213169691Skan  template<typename _Tp>
214169691Skan    std::complex<_Tp>
215169691Skan    __complex_asinh(const std::complex<_Tp>& __z)
216169691Skan    {
217169691Skan      std::complex<_Tp> __t((__z.real() - __z.imag())
218169691Skan			    * (__z.real() + __z.imag()) + _Tp(1.0),
219169691Skan			    _Tp(2.0) * __z.real() * __z.imag());
220169691Skan      __t = std::sqrt(__t);
221169691Skan
222169691Skan      return std::log(__t + __z);
223169691Skan    }
224169691Skan
225169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1
226169691Skan  inline __complex__ float
227169691Skan  __complex_asinh(__complex__ float __z)
228169691Skan  { return __builtin_casinhf(__z); }
229169691Skan
230169691Skan  inline __complex__ double
231169691Skan  __complex_asinh(__complex__ double __z)
232169691Skan  { return __builtin_casinh(__z); }
233169691Skan
234169691Skan  inline __complex__ long double
235169691Skan  __complex_asinh(const __complex__ long double& __z)
236169691Skan  { return __builtin_casinhl(__z); }
237169691Skan
238169691Skan  template<typename _Tp>
239169691Skan    inline std::complex<_Tp>
240169691Skan    asinh(const std::complex<_Tp>& __z)
241169691Skan    { return __complex_asinh(__z.__rep()); }
242169691Skan#else
243169691Skan  template<typename _Tp>
244169691Skan    inline std::complex<_Tp>
245169691Skan    asinh(const std::complex<_Tp>& __z)
246169691Skan    { return __complex_asinh(__z); }
247169691Skan#endif
248169691Skan
249169691Skan  /// @brief atanh(__z) [8.1.7].
250169691Skan  //  Effects:  Behaves the same as C99 function catanh, defined
251169691Skan  //            in subclause 7.3.6.3.
252169691Skan  template<typename _Tp>
253169691Skan    std::complex<_Tp>
254169691Skan    __complex_atanh(const std::complex<_Tp>& __z)
255169691Skan    {
256169691Skan      const _Tp __i2 = __z.imag() * __z.imag();
257169691Skan      const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
258169691Skan
259169691Skan      _Tp __num = _Tp(1.0) + __z.real();
260169691Skan      _Tp __den = _Tp(1.0) - __z.real();
261169691Skan
262169691Skan      __num = __i2 + __num * __num;
263169691Skan      __den = __i2 + __den * __den;
264169691Skan
265169691Skan      return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
266169691Skan			       _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
267169691Skan    }
268169691Skan
269169691Skan#if _GLIBCXX_USE_C99_COMPLEX_TR1
270169691Skan  inline __complex__ float
271169691Skan  __complex_atanh(__complex__ float __z)
272169691Skan  { return __builtin_catanhf(__z); }
273169691Skan
274169691Skan  inline __complex__ double
275169691Skan  __complex_atanh(__complex__ double __z)
276169691Skan  { return __builtin_catanh(__z); }
277169691Skan
278169691Skan  inline __complex__ long double
279169691Skan  __complex_atanh(const __complex__ long double& __z)
280169691Skan  { return __builtin_catanhl(__z); }
281169691Skan
282169691Skan  template<typename _Tp>
283169691Skan    inline std::complex<_Tp>
284169691Skan    atanh(const std::complex<_Tp>& __z)
285169691Skan    { return __complex_atanh(__z.__rep()); }
286169691Skan#else
287169691Skan  template<typename _Tp>
288169691Skan    inline std::complex<_Tp>
289169691Skan    atanh(const std::complex<_Tp>& __z)
290169691Skan    { return __complex_atanh(__z); }
291169691Skan#endif
292169691Skan
293169691Skan  /// @brief fabs(__z) [8.1.8].
294169691Skan  //  Effects:  Behaves the same as C99 function cabs, defined
295169691Skan  //            in subclause 7.3.8.1.
296169691Skan  template<typename _Tp>
297169691Skan    inline std::complex<_Tp>
298169691Skan    fabs(const std::complex<_Tp>& __z)
299169691Skan    { return std::abs(__z); }
300169691Skan
301169691Skan
302169691Skan  /// @brief Additional overloads [8.1.9].
303169691Skan  //
304169691Skan
305169691Skan  // See common.h for the primary template.
306169691Skan  template<typename _Tp, typename _Up>
307169691Skan    struct __promote_2<std::complex<_Tp>, _Up>
308169691Skan    {
309169691Skan    public:
310169691Skan      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
311169691Skan    };
312169691Skan
313169691Skan  template<typename _Tp, typename _Up>
314169691Skan    struct __promote_2<_Tp, std::complex<_Up> >
315169691Skan    {
316169691Skan    public:
317169691Skan      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
318169691Skan    };
319169691Skan  
320169691Skan  template<typename _Tp, typename _Up>
321169691Skan    struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
322169691Skan    {
323169691Skan    public:
324169691Skan      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
325169691Skan    };
326169691Skan
327169691Skan
328169691Skan  using std::arg;
329169691Skan
330169691Skan  template<typename _Tp>
331169691Skan    inline typename __promote<_Tp>::__type
332169691Skan    arg(_Tp __x)
333169691Skan    {
334169691Skan      typedef typename __promote<_Tp>::__type __type;
335169691Skan      return std::arg(std::complex<__type>(__x));
336169691Skan    }
337169691Skan
338169691Skan  using std::conj;
339169691Skan
340169691Skan  template<typename _Tp>
341169691Skan    inline std::complex<typename __promote<_Tp>::__type>
342169691Skan    conj(_Tp __x)
343169691Skan    { return __x; }
344169691Skan
345169691Skan  using std::imag;
346169691Skan
347169691Skan  template<typename _Tp>
348169691Skan    inline typename __promote<_Tp>::__type
349169691Skan    imag(_Tp)
350169691Skan    { return _Tp(); }
351169691Skan
352169691Skan  using std::norm;
353169691Skan
354169691Skan  template<typename _Tp>
355169691Skan    inline typename __promote<_Tp>::__type
356169691Skan    norm(_Tp __x)
357169691Skan    {
358169691Skan      typedef typename __promote<_Tp>::__type __type;
359169691Skan      return __type(__x) * __type(__x);
360169691Skan    }
361169691Skan
362169691Skan  using std::polar;
363169691Skan
364169691Skan  template<typename _Tp, typename _Up>
365169691Skan    inline std::complex<typename __promote_2<_Tp, _Up>::__type>
366169691Skan    polar(const _Tp& __rho, const _Up& __theta)
367169691Skan    {
368169691Skan      typedef typename __promote_2<_Tp, _Up>::__type __type;
369169691Skan      return std::polar(__type(__rho), __type(__theta));
370169691Skan    }
371169691Skan  
372169691Skan  using std::pow;
373169691Skan  
374169691Skan  template<typename _Tp, typename _Up>
375169691Skan    inline std::complex<typename __promote_2<_Tp, _Up>::__type>
376169691Skan    pow(const std::complex<_Tp>& __x, const _Up& __y)
377169691Skan    {
378169691Skan      typedef typename __promote_2<_Tp, _Up>::__type __type;
379169691Skan      return std::pow(std::complex<__type>(__x), __type(__y));
380169691Skan    }
381169691Skan
382169691Skan  template<typename _Tp, typename _Up>
383169691Skan    inline std::complex<typename __promote_2<_Tp, _Up>::__type>
384169691Skan    pow(const _Tp& __x, const std::complex<_Up>& __y)
385169691Skan    {
386169691Skan      typedef typename __promote_2<_Tp, _Up>::__type __type;
387169691Skan      return std::pow(__type(__x), std::complex<__type>(__y));
388169691Skan    }
389169691Skan
390169691Skan  template<typename _Tp, typename _Up>
391169691Skan    inline std::complex<typename __promote_2<_Tp, _Up>::__type>
392169691Skan    pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
393169691Skan    {
394169691Skan      typedef typename __promote_2<_Tp, _Up>::__type __type;
395169691Skan      return std::pow(std::complex<__type>(__x),
396169691Skan		      std::complex<__type>(__y));
397169691Skan    }
398169691Skan
399169691Skan  using std::real;
400169691Skan
401169691Skan  template<typename _Tp>
402169691Skan    inline typename __promote<_Tp>::__type
403169691Skan    real(_Tp __x)
404169691Skan    { return __x; }
405169691Skan
406169691Skan_GLIBCXX_END_NAMESPACE
407169691Skan}
408169691Skan
409169691Skan#endif
410