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