sl@0: /* sl@0: * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved. sl@0: * sl@0: * Copyright (c) 1999 sl@0: * Silicon Graphics Computer Systems, Inc. sl@0: * sl@0: * Copyright (c) 1999 sl@0: * Boris Fomitchev sl@0: * sl@0: * This material is provided "as is", with absolutely no warranty expressed sl@0: * or implied. Any use is at your own risk. sl@0: * sl@0: * Permission to use or copy this software for any purpose is hereby granted sl@0: * without fee, provided the above notices are retained on all copies. sl@0: * Permission to modify the code and to distribute modified code is granted, sl@0: * provided the above notices are retained, and a notice that the code was sl@0: * modified is included with the above copyright notice. sl@0: * sl@0: */ sl@0: # include "stlport_prefix.h" sl@0: // Complex division and square roots. sl@0: sl@0: #include "complex_impl.h" sl@0: #ifdef __ARMCC__ sl@0: #undef _STLP_TEMPLATE_NULL sl@0: #define _STLP_TEMPLATE_NULL sl@0: #endif sl@0: _STLP_BEGIN_NAMESPACE sl@0: sl@0: // Absolute value sl@0: #ifdef __SYMBIAN32__ sl@0: sl@0: float abs_l(const complex<float>& __z) sl@0: { sl@0: return _STLP_HYPOTF(__z._M_re, __z._M_im); sl@0: } sl@0: sl@0: double _STLP_CALL abs_l(const complex<double>& __z) sl@0: { sl@0: return _STLP_HYPOT(__z._M_re, __z._M_im); sl@0: } sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: long double _STLP_CALL abs_l(const complex<long double>& __z) sl@0: { sl@0: return _STLP_HYPOTL(__z._M_re, __z._M_im); sl@0: } sl@0: #endif sl@0: #else sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC float _STLP_CALL abs(const complex<float>& __z) sl@0: { sl@0: return _STLP_HYPOTF(__z._M_re, __z._M_im); sl@0: } sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC double _STLP_CALL abs(const complex<double>& __z) sl@0: { sl@0: return _STLP_HYPOT(__z._M_re, __z._M_im); sl@0: } sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC long double _STLP_CALL abs(const complex<long double>& __z) sl@0: { sl@0: return _STLP_HYPOTL(__z._M_re, __z._M_im); sl@0: } sl@0: #endif sl@0: #endif sl@0: sl@0: // Phase sl@0: #ifdef __SYMBIAN32__ sl@0: sl@0: float _STLP_CALL arg_l(const complex<float>& __z) sl@0: { sl@0: return _STLP_ATAN2F(__z._M_im, __z._M_re); sl@0: } sl@0: sl@0: sl@0: double _STLP_CALL arg_l(const complex<double>& __z) sl@0: { sl@0: return _STLP_ATAN2(__z._M_im, __z._M_re); sl@0: } sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: long double _STLP_CALL arg_l(const complex<long double>& __z) sl@0: { sl@0: return _STLP_ATAN2L(__z._M_im, __z._M_re); sl@0: } sl@0: #endif sl@0: #else sl@0: sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC float _STLP_CALL arg(const complex<float>& __z) sl@0: { sl@0: return _STLP_ATAN2F(__z._M_im, __z._M_re); sl@0: } sl@0: sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC double _STLP_CALL arg(const complex<double>& __z) sl@0: { sl@0: return _STLP_ATAN2(__z._M_im, __z._M_re); sl@0: } sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC long double _STLP_CALL arg(const complex<long double>& __z) sl@0: { sl@0: return _STLP_ATAN2L(__z._M_im, __z._M_re); sl@0: } sl@0: #endif sl@0: #endif sl@0: sl@0: // Construct a complex number from polar representation sl@0: #ifdef __SYMBIAN32__ sl@0: complex<float> _STLP_CALL polar_l(const float& __rho, const float& __phi) sl@0: { sl@0: return complex<float>(__rho * _STLP_COSF(__phi), __rho * _STLP_SINF(__phi)); sl@0: } sl@0: sl@0: complex<double> _STLP_CALL polar_l(const double& __rho, const double& __phi) sl@0: { sl@0: return complex<double>(__rho * _STLP_COS(__phi), __rho * _STLP_SIN(__phi)); sl@0: } sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: complex<long double> _STLP_CALL polar_l(const long double& __rho, const long double& __phi) sl@0: { sl@0: return complex<long double>(__rho * _STLP_COSL(__phi), __rho * _STLP_SINL(__phi)); sl@0: } sl@0: #endif sl@0: sl@0: #else sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC complex<float> _STLP_CALL polar(const float& __rho, const float& __phi) sl@0: { sl@0: return complex<float>(__rho * _STLP_COSF(__phi), __rho * _STLP_SINF(__phi)); sl@0: } sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC complex<double> _STLP_CALL polar(const double& __rho, const double& __phi) sl@0: { sl@0: return complex<double>(__rho * _STLP_COS(__phi), __rho * _STLP_SIN(__phi)); sl@0: } sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: _STLP_TEMPLATE_NULL sl@0: _STLP_EXP_DECLSPEC complex<long double> _STLP_CALL polar(const long double& __rho, const long double& __phi) sl@0: { sl@0: return complex<long double>(__rho * _STLP_COSL(__phi), __rho * _STLP_SINL(__phi)); sl@0: } sl@0: #endif sl@0: sl@0: #endif sl@0: // Division sl@0: sl@0: void _STLP_EXP_DECLSPEC sl@0: complex<float>::_div(const float& __z1_r, const float& __z1_i, sl@0: const float& __z2_r, const float& __z2_i, sl@0: float& __res_r, float& __res_i) { sl@0: float __ar = __z2_r >= 0 ? __z2_r : -__z2_r; sl@0: float __ai = __z2_i >= 0 ? __z2_i : -__z2_i; sl@0: sl@0: if (__ar <= __ai) { sl@0: float __ratio = __z2_r / __z2_i; sl@0: float __denom = __z2_i * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r * __ratio + __z1_i) / __denom; sl@0: __res_i = (__z1_i * __ratio - __z1_r) / __denom; sl@0: } sl@0: else { sl@0: float __ratio = __z2_i / __z2_r; sl@0: float __denom = __z2_r * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r + __z1_i * __ratio) / __denom; sl@0: __res_i = (__z1_i - __z1_r * __ratio) / __denom; sl@0: } sl@0: } sl@0: sl@0: void _STLP_EXP_DECLSPEC sl@0: complex<float>::_div(const float& __z1_r, sl@0: const float& __z2_r, const float& __z2_i, sl@0: float& __res_r, float& __res_i) { sl@0: float __ar = __z2_r >= 0 ? __z2_r : -__z2_r; sl@0: float __ai = __z2_i >= 0 ? __z2_i : -__z2_i; sl@0: sl@0: if (__ar <= __ai) { sl@0: float __ratio = __z2_r / __z2_i; sl@0: float __denom = __z2_i * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r * __ratio) / __denom; sl@0: __res_i = - __z1_r / __denom; sl@0: } sl@0: else { sl@0: float __ratio = __z2_i / __z2_r; sl@0: float __denom = __z2_r * (1 + __ratio * __ratio); sl@0: __res_r = __z1_r / __denom; sl@0: __res_i = - (__z1_r * __ratio) / __denom; sl@0: } sl@0: } sl@0: sl@0: sl@0: void _STLP_EXP_DECLSPEC sl@0: complex<double>::_div(const double& __z1_r, const double& __z1_i, sl@0: const double& __z2_r, const double& __z2_i, sl@0: double& __res_r, double& __res_i) { sl@0: double __ar = __z2_r >= 0 ? __z2_r : -__z2_r; sl@0: double __ai = __z2_i >= 0 ? __z2_i : -__z2_i; sl@0: sl@0: if (__ar <= __ai) { sl@0: double __ratio = __z2_r / __z2_i; sl@0: double __denom = __z2_i * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r * __ratio + __z1_i) / __denom; sl@0: __res_i = (__z1_i * __ratio - __z1_r) / __denom; sl@0: } sl@0: else { sl@0: double __ratio = __z2_i / __z2_r; sl@0: double __denom = __z2_r * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r + __z1_i * __ratio) / __denom; sl@0: __res_i = (__z1_i - __z1_r * __ratio) / __denom; sl@0: } sl@0: } sl@0: sl@0: void _STLP_EXP_DECLSPEC sl@0: complex<double>::_div(const double& __z1_r, sl@0: const double& __z2_r, const double& __z2_i, sl@0: double& __res_r, double& __res_i) { sl@0: double __ar = __z2_r >= 0 ? __z2_r : -__z2_r; sl@0: double __ai = __z2_i >= 0 ? __z2_i : -__z2_i; sl@0: sl@0: if (__ar <= __ai) { sl@0: double __ratio = __z2_r / __z2_i; sl@0: double __denom = __z2_i * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r * __ratio) / __denom; sl@0: __res_i = - __z1_r / __denom; sl@0: } sl@0: else { sl@0: double __ratio = __z2_i / __z2_r; sl@0: double __denom = __z2_r * (1 + __ratio * __ratio); sl@0: __res_r = __z1_r / __denom; sl@0: __res_i = - (__z1_r * __ratio) / __denom; sl@0: } sl@0: } sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: void _STLP_CALL sl@0: complex<long double>::_div(const long double& __z1_r, const long double& __z1_i, sl@0: const long double& __z2_r, const long double& __z2_i, sl@0: long double& __res_r, long double& __res_i) { sl@0: long double __ar = __z2_r >= 0 ? __z2_r : -__z2_r; sl@0: long double __ai = __z2_i >= 0 ? __z2_i : -__z2_i; sl@0: sl@0: if (__ar <= __ai) { sl@0: long double __ratio = __z2_r / __z2_i; sl@0: long double __denom = __z2_i * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r * __ratio + __z1_i) / __denom; sl@0: __res_i = (__z1_i * __ratio - __z1_r) / __denom; sl@0: } sl@0: else { sl@0: long double __ratio = __z2_i / __z2_r; sl@0: long double __denom = __z2_r * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r + __z1_i * __ratio) / __denom; sl@0: __res_i = (__z1_i - __z1_r * __ratio) / __denom; sl@0: } sl@0: } sl@0: sl@0: sl@0: void _STLP_CALL sl@0: complex<long double>::_div(const long double& __z1_r, sl@0: const long double& __z2_r, const long double& __z2_i, sl@0: long double& __res_r, long double& __res_i) { sl@0: long double __ar = __z2_r >= 0 ? __z2_r : -__z2_r; sl@0: long double __ai = __z2_i >= 0 ? __z2_i : -__z2_i; sl@0: sl@0: if (__ar <= __ai) { sl@0: long double __ratio = __z2_r / __z2_i; sl@0: long double __denom = __z2_i * (1 + __ratio * __ratio); sl@0: __res_r = (__z1_r * __ratio) / __denom; sl@0: __res_i = - __z1_r / __denom; sl@0: } sl@0: else { sl@0: long double __ratio = __z2_i / __z2_r; sl@0: long double __denom = __z2_r * (1 + __ratio * __ratio); sl@0: __res_r = __z1_r / __denom; sl@0: __res_i = - (__z1_r * __ratio) / __denom; sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: //---------------------------------------------------------------------- sl@0: // Square root sl@0: sl@0: sl@0: _STLP_EXP_DECLSPEC complex<float> _STLP_CALL sl@0: sqrt(const complex<float>& z) { sl@0: float re = z._M_re; sl@0: float im = z._M_im; sl@0: float mag = _STLP_HYPOTF(re, im); sl@0: complex<float> result; sl@0: sl@0: if (mag == 0.) { sl@0: result._M_re = result._M_im = 0.f; sl@0: } else if (re > 0.f) { sl@0: result._M_re = _STLP_SQRTF(0.5f * (mag + re)); sl@0: result._M_im = im/result._M_re/2.f; sl@0: } else { sl@0: result._M_im = _STLP_SQRTF(0.5f * (mag - re)); sl@0: if (im < 0.f) sl@0: result._M_im = - result._M_im; sl@0: result._M_re = im/result._M_im/2.f; sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: sl@0: _STLP_EXP_DECLSPEC complex<double> _STLP_CALL sl@0: sqrt(const complex<double>& z) { sl@0: double re = z._M_re; sl@0: double im = z._M_im; sl@0: double mag = _STLP_HYPOT(re, im); sl@0: complex<double> result; sl@0: sl@0: if (mag == 0.) { sl@0: result._M_re = result._M_im = 0.; sl@0: } else if (re > 0.) { sl@0: result._M_re = _STLP_SQRT(0.5 * (mag + re)); sl@0: result._M_im = im/result._M_re/2; sl@0: } else { sl@0: result._M_im = _STLP_SQRT(0.5 * (mag - re)); sl@0: if (im < 0.) sl@0: result._M_im = - result._M_im; sl@0: result._M_re = im/result._M_im/2; sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: _STLP_EXP_DECLSPEC complex<long double> _STLP_CALL sl@0: sqrt(const complex<long double>& z) { sl@0: long double re = z._M_re; sl@0: long double im = z._M_im; sl@0: long double mag = _STLP_HYPOTL(re, im); sl@0: complex<long double> result; sl@0: sl@0: if (mag == 0.L) { sl@0: result._M_re = result._M_im = 0.L; sl@0: } else if (re > 0.L) { sl@0: result._M_re = _STLP_SQRTL(0.5L * (mag + re)); sl@0: result._M_im = (im/result._M_re) * .5L; sl@0: } else { sl@0: result._M_im = _STLP_SQRTL(0.5L * (mag - re)); sl@0: if (im < 0.L) sl@0: result._M_im = - result._M_im; sl@0: result._M_re = (im/result._M_im) * .5L; sl@0: } sl@0: return result; sl@0: } sl@0: #endif sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: template <class _Tp> sl@0: _STLP_EXP_DECLSPEC _Tp _STLP_CALL abs_tp(const complex<_Tp>& val) sl@0: { sl@0: return abs_l(val); sl@0: } sl@0: sl@0: template <class _Tp> sl@0: _STLP_EXP_DECLSPEC _Tp _STLP_CALL arg_tp(const complex<_Tp>& val) sl@0: { sl@0: return arg_l(val); sl@0: } sl@0: sl@0: template <class _Tp> sl@0: _STLP_EXP_DECLSPEC complex<_Tp> _STLP_CALL polar_tp(const _Tp& __rho, const _Tp& __phi) sl@0: { sl@0: return polar_l(__rho, __phi); sl@0: } sl@0: sl@0: sl@0: void dummy_instantiate_func() sl@0: { sl@0: const complex<float> val; sl@0: float fval; sl@0: abs_tp(val); sl@0: arg_tp(val); sl@0: polar_tp(fval, fval); sl@0: const complex<double> dval; sl@0: double dv; sl@0: abs_tp(dval); sl@0: arg_tp(dval); sl@0: polar_tp(dv, dv); sl@0: sl@0: #ifndef _STLP_NO_LONG_DOUBLE sl@0: const complex<long double> lval; sl@0: long double lv; sl@0: abs_tp(lval); sl@0: arg_tp(lval); sl@0: polar_tp(lv, lv); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: #endif sl@0: //template <> sl@0: //_STLP_EXP_DECLSPEC float _STLP_CALL abs_tp(const complex<float>& val); sl@0: sl@0: _STLP_END_NAMESPACE sl@0: sl@0: #ifdef __ARMCC__ sl@0: #undef _STLP_TEMPLATE_NULL sl@0: #endif