1e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott/*
2e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Copyright (c) 1999
3e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Silicon Graphics Computer Systems, Inc.
4e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *
5e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Copyright (c) 1999
6e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Boris Fomitchev
7e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *
8e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * This material is provided "as is", with absolutely no warranty expressed
9e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * or implied. Any use is at your own risk.
10e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *
11e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Permission to use or copy this software for any purpose is hereby granted
12e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * without fee, provided the above notices are retained on all copies.
13e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Permission to modify the code and to distribute modified code is granted,
14e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * provided the above notices are retained, and a notice that the code was
15e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * modified is included with the above copyright notice.
16e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *
17e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott */
18e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
19e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "stlport_prefix.h"
20e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
21e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <numeric>
22e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <cmath>
23e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <complex>
24e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
25e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (_STLP_MSVC_LIB) && (_STLP_MSVC_LIB >= 1400)
26e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// hypot is deprecated.
27e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  if defined (_STLP_MSVC)
28e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    pragma warning (disable : 4996)
29e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  elif defined (__ICL)
30e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    pragma warning (disable : 1478)
31e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  endif
32e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
33e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
34e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_BEGIN_NAMESPACE
35e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
36e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Complex division and square roots.
37e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
38e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Absolute value
39e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
40e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC float _STLP_CALL abs(const complex<float>& __z)
41e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ::hypot(__z._M_re, __z._M_im); }
42e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
43e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC double _STLP_CALL abs(const complex<double>& __z)
44e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ::hypot(__z._M_re, __z._M_im); }
45e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
46e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE)
47e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
48e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC long double _STLP_CALL abs(const complex<long double>& __z)
49e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ::hypot(__z._M_re, __z._M_im); }
50e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
51e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
52e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Phase
53e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
54e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
55e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC float _STLP_CALL arg(const complex<float>& __z)
56e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ::atan2(__z._M_im, __z._M_re); }
57e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
58e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
59e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC double _STLP_CALL arg(const complex<double>& __z)
60e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ::atan2(__z._M_im, __z._M_re); }
61e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
62e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE)
63e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
64e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC long double _STLP_CALL arg(const complex<long double>& __z)
65e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ::atan2(__z._M_im, __z._M_re); }
66e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
67e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
68e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Construct a complex number from polar representation
69e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
70e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL polar(const float& __rho, const float& __phi)
71e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return complex<float>(__rho * ::cos(__phi), __rho * ::sin(__phi)); }
72e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
73e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL polar(const double& __rho, const double& __phi)
74e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return complex<double>(__rho * ::cos(__phi), __rho * ::sin(__phi)); }
75e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
76e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE)
77e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL
78e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL polar(const long double& __rho, const long double& __phi)
79e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return complex<long double>(__rho * ::cos(__phi), __rho * ::sin(__phi)); }
80e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
81e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
82e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Division
83e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
84e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic void _divT(const _Tp& __z1_r, const _Tp& __z1_i,
85e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                  const _Tp& __z2_r, const _Tp& __z2_i,
86e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                  _Tp& __res_r, _Tp& __res_i) {
87e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
88e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
89e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
90e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (__ar <= __ai) {
91e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _Tp __ratio = __z2_r / __z2_i;
92e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _Tp __denom = __z2_i * (1 + __ratio * __ratio);
93e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    __res_r = (__z1_r * __ratio + __z1_i) / __denom;
94e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    __res_i = (__z1_i * __ratio - __z1_r) / __denom;
95e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
96e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  else {
97e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _Tp __ratio = __z2_i / __z2_r;
98e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _Tp __denom = __z2_r * (1 + __ratio * __ratio);
99e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    __res_r = (__z1_r + __z1_i * __ratio) / __denom;
100e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    __res_i = (__z1_i - __z1_r * __ratio) / __denom;
101e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
102e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
103e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
104e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
105e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic void _divT(const _Tp& __z1_r,
106e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                  const _Tp& __z2_r, const _Tp& __z2_i,
107e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                  _Tp& __res_r, _Tp& __res_i) {
108e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
109e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
110e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
111e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (__ar <= __ai) {
112e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _Tp __ratio = __z2_r / __z2_i;
113e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _Tp __denom = __z2_i * (1 + __ratio * __ratio);
114e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    __res_r = (__z1_r * __ratio) / __denom;
115e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    __res_i = - __z1_r / __denom;
116e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
117e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  else {
118e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _Tp __ratio = __z2_i / __z2_r;
119e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    _Tp __denom = __z2_r * (1 + __ratio * __ratio);
120e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    __res_r = __z1_r / __denom;
121e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    __res_i = - (__z1_r * __ratio) / __denom;
122e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
123e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
124e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
125e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _STLP_CALL
126e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<float>::_div(const float& __z1_r, const float& __z1_i,
127e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                     const float& __z2_r, const float& __z2_i,
128e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                     float& __res_r, float& __res_i)
129e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ _divT(__z1_r, __z1_i, __z2_r, __z2_i, __res_r, __res_i); }
130e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
131e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _STLP_CALL
132e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<float>::_div(const float& __z1_r,
133e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                     const float& __z2_r, const float& __z2_i,
134e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                     float& __res_r, float& __res_i)
135e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ _divT(__z1_r, __z2_r, __z2_i, __res_r, __res_i); }
136e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
137e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
138e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid  _STLP_CALL
139e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<double>::_div(const double& __z1_r, const double& __z1_i,
140e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                      const double& __z2_r, const double& __z2_i,
141e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                      double& __res_r, double& __res_i)
142e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ _divT(__z1_r, __z1_i, __z2_r, __z2_i, __res_r, __res_i); }
143e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
144e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _STLP_CALL
145e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<double>::_div(const double& __z1_r,
146e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                      const double& __z2_r, const double& __z2_i,
147e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                      double& __res_r, double& __res_i)
148e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ _divT(__z1_r, __z2_r, __z2_i, __res_r, __res_i); }
149e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
150e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE)
151e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid  _STLP_CALL
152e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<long double>::_div(const long double& __z1_r, const long double& __z1_i,
153e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                           const long double& __z2_r, const long double& __z2_i,
154e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                           long double& __res_r, long double& __res_i)
155e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ _divT(__z1_r, __z1_i, __z2_r, __z2_i, __res_r, __res_i); }
156e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
157e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _STLP_CALL
158e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<long double>::_div(const long double& __z1_r,
159e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                           const long double& __z2_r, const long double& __z2_i,
160e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                           long double& __res_r, long double& __res_i)
161e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ _divT(__z1_r, __z2_r, __z2_i, __res_r, __res_i); }
162e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
163e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
164e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//----------------------------------------------------------------------
165e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Square root
166e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
167e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> sqrtT(const complex<_Tp>& z) {
168e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp re = z._M_re;
169e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp im = z._M_im;
170e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp mag = ::hypot(re, im);
171e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  complex<_Tp> result;
172e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
173e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (mag == 0.f) {
174e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    result._M_re = result._M_im = 0.f;
175e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  } else if (re > 0.f) {
176e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    result._M_re = ::sqrt(0.5f * (mag + re));
177e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    result._M_im = im/result._M_re/2.f;
178e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  } else {
179e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    result._M_im = ::sqrt(0.5f * (mag - re));
180e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    if (im < 0.f)
181e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott      result._M_im = - result._M_im;
182e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    result._M_re = im/result._M_im/2.f;
183e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  }
184e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return result;
185e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
186e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
187e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<float> _STLP_CALL
188e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottsqrt(const complex<float>& z) { return sqrtT(z); }
189e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
190e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<double>  _STLP_CALL
191e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottsqrt(const complex<double>& z) { return sqrtT(z); }
192e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
193e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE)
194e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottcomplex<long double> _STLP_CALL
195e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottsqrt(const complex<long double>& z) { return sqrtT(z); }
196e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
197e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
198e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// exp, log, pow for complex<float>, complex<double>, and complex<long double>
199e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//----------------------------------------------------------------------
200e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// exp
201e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
202e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> expT(const complex<_Tp>& z) {
203e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp expx = ::exp(z._M_re);
204e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return complex<_Tp>(expx * ::cos(z._M_im),
205e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                      expx * ::sin(z._M_im));
206e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
207e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float>  _STLP_CALL exp(const complex<float>& z)
208e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return expT(z); }
209e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
210e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL exp(const complex<double>& z)
211e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return expT(z); }
212e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
213e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE)
214e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL exp(const complex<long double>& z)
215e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return expT(z); }
216e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
217e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
218e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//----------------------------------------------------------------------
219e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// log10
220e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
221e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> log10T(const complex<_Tp>& z, const _Tp& ln10_inv) {
222e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  complex<_Tp> r;
223e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
224e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  r._M_im = ::atan2(z._M_im, z._M_re) * ln10_inv;
225e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  r._M_re = ::log10(::hypot(z._M_re, z._M_im));
226e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return r;
227e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
228e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
229e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL log10(const complex<float>& z)
2307eced231853cc34e9f2710a81664dee108176317Andrew Hsieh{
2317eced231853cc34e9f2710a81664dee108176317Andrew Hsieh  const float LN10_INVF = 1.f / ::log(10.f);
2327eced231853cc34e9f2710a81664dee108176317Andrew Hsieh  return log10T(z, LN10_INVF);
2337eced231853cc34e9f2710a81664dee108176317Andrew Hsieh}
234e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
235e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL log10(const complex<double>& z)
2367eced231853cc34e9f2710a81664dee108176317Andrew Hsieh{
2377eced231853cc34e9f2710a81664dee108176317Andrew Hsieh  const double LN10_INV = 1. / ::log10(10.);
2387eced231853cc34e9f2710a81664dee108176317Andrew Hsieh  return log10T(z, LN10_INV);
2397eced231853cc34e9f2710a81664dee108176317Andrew Hsieh}
240e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
241e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE)
242e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL log10(const complex<long double>& z)
2437eced231853cc34e9f2710a81664dee108176317Andrew Hsieh{
2447eced231853cc34e9f2710a81664dee108176317Andrew Hsieh  const long double LN10_INVL = 1.l / ::log(10.l);
2457eced231853cc34e9f2710a81664dee108176317Andrew Hsieh  return log10T(z, LN10_INVL);
2467eced231853cc34e9f2710a81664dee108176317Andrew Hsieh}
247e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
248e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
249e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//----------------------------------------------------------------------
250e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// log
251e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
252e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> logT(const complex<_Tp>& z) {
253e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  complex<_Tp> r;
254e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
255e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  r._M_im = ::atan2(z._M_im, z._M_re);
256e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  r._M_re = ::log(::hypot(z._M_re, z._M_im));
257e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return r;
258e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
259e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL log(const complex<float>& z)
260e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return logT(z); }
261e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
262e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL log(const complex<double>& z)
263e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return logT(z); }
264e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
265e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#ifndef _STLP_NO_LONG_DOUBLE
266e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL log(const complex<long double>& z)
267e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return logT(z); }
268e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif
269e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
270e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//----------------------------------------------------------------------
271e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// pow
272e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
273e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> powT(const _Tp& a, const complex<_Tp>& b) {
274e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp logr = ::log(a);
275e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp x = ::exp(logr * b._M_re);
276e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp y = logr * b._M_im;
277e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
278e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return complex<_Tp>(x * ::cos(y), x * ::sin(y));
279e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
280e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
281e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
282e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> powT(const complex<_Tp>& z_in, int n) {
283e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  complex<_Tp> z = z_in;
284e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  z = _STLP_PRIV __power(z, (n < 0 ? -n : n), multiplies< complex<_Tp> >());
285e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (n < 0)
286e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    return _Tp(1.0) / z;
287e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  else
288e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    return z;
289e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
290e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
291e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
292e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> powT(const complex<_Tp>& a, const _Tp& b) {
293e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp logr = ::log(::hypot(a._M_re,a._M_im));
294e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp logi = ::atan2(a._M_im, a._M_re);
295e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp x = ::exp(logr * b);
296e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp y = logi * b;
297e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
298e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return complex<_Tp>(x * ::cos(y), x * ::sin(y));
299e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
300e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
301e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp>
302e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> powT(const complex<_Tp>& a, const complex<_Tp>& b) {
303e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp logr = ::log(::hypot(a._M_re,a._M_im));
304e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp logi = ::atan2(a._M_im, a._M_re);
305e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp x = ::exp(logr * b._M_re - logi * b._M_im);
306e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  _Tp y = logr * b._M_im + logi * b._M_re;
307e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
308e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return complex<_Tp>(x * ::cos(y), x * ::sin(y));
309e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
310e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
311e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL pow(const float& a, const complex<float>& b)
312e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
313e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
314e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL pow(const complex<float>& z_in, int n)
315e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(z_in, n); }
316e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
317e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL pow(const complex<float>& a, const float& b)
318e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
319e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
320e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL pow(const complex<float>& a, const complex<float>& b)
321e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
322e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
323e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL pow(const double& a, const complex<double>& b)
324e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
325e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
326e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL pow(const complex<double>& z_in, int n)
327e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(z_in, n); }
328e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
329e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL pow(const complex<double>& a, const double& b)
330e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
331e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
332e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL pow(const complex<double>& a, const complex<double>& b)
333e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
334e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
335e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE)
336e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL pow(const long double& a,
337e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                                                   const complex<long double>& b)
338e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
339e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
340e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
341e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL pow(const complex<long double>& z_in, int n)
342e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(z_in, n); }
343e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
344e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL pow(const complex<long double>& a,
345e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                                                   const long double& b)
346e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
347e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
348e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL pow(const complex<long double>& a,
349e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                                                   const complex<long double>& b)
350e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return powT(a, b); }
351e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
352e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
353e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_END_NAMESPACE
354