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