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#include "stlport_prefix.h" 19e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 20e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 21e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Trigonometric and hyperbolic functions for complex<float>, 22e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// complex<double>, and complex<long double> 23e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <complex> 24e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <cfloat> 25e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <cmath> 26e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 27e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_BEGIN_NAMESPACE 28e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 29e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 30e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//---------------------------------------------------------------------- 31e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// helpers 32e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__sgi) 33e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const union { unsigned int i; float f; } float_ulimit = { 0x42b2d4fc }; 34e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const float float_limit = float_ulimit.f; 35e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static union { 36e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott struct { unsigned int h; unsigned int l; } w; 37e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott double d; 38e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } double_ulimit = { 0x408633ce, 0x8fb9f87d }; 39e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const double double_limit = double_ulimit.d; 40e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static union { 41e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott struct { unsigned int h[2]; unsigned int l[2]; } w; 42e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott long double ld; 43e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } ldouble_ulimit = {0x408633ce, 0x8fb9f87e, 0xbd23b659, 0x4e9bd8b1}; 44e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 45e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const long double ldouble_limit = ldouble_ulimit.ld; 46e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 47e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else 48e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (M_LN2) && defined (FLT_MAX_EXP) 49e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const float float_limit = float(M_LN2 * FLT_MAX_EXP); 50e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const double double_limit = M_LN2 * DBL_MAX_EXP; 51e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 52e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const float float_limit = ::log(FLT_MAX); 53e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const double double_limit = ::log(DBL_MAX); 54e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 55e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 56e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (M_LN2l) 57e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const long double ldouble_limit = M_LN2l * LDBL_MAX_EXP; 58e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 59e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const long double ldouble_limit = ::log(LDBL_MAX); 60e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 61e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 62e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 63e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 64e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 65e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//---------------------------------------------------------------------- 66e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// sin 67e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp> 68e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> sinT(const complex<_Tp>& z) { 69e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return complex<_Tp>(::sin(z._M_re) * ::cosh(z._M_im), 70e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ::cos(z._M_re) * ::sinh(z._M_im)); 71e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 72e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 73e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL sin(const complex<float>& z) 74e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return sinT(z); } 75e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 76e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL sin(const complex<double>& z) 77e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return sinT(z); } 78e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 79e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE) 80e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL sin(const complex<long double>& z) 81e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return sinT(z); } 82e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 83e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 84e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//---------------------------------------------------------------------- 85e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// cos 86e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp> 87e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> cosT(const complex<_Tp>& z) { 88e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return complex<_Tp>(::cos(z._M_re) * ::cosh(z._M_im), 89e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott -::sin(z._M_re) * ::sinh(z._M_im)); 90e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 91e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 92e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL cos(const complex<float>& z) 93e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return cosT(z); } 94e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 95e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL cos(const complex<double>& z) 96e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return cosT(z); } 97e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 98e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE) 99e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL cos(const complex<long double>& z) 100e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return cosT(z); } 101e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 102e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 103e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//---------------------------------------------------------------------- 104e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// tan 105e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp> 106e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> tanT(const complex<_Tp>& z, const _Tp& Tp_limit) { 107e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _Tp re2 = 2.f * z._M_re; 108e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _Tp im2 = 2.f * z._M_im; 109e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 110e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (::abs(im2) > Tp_limit) 111e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return complex<_Tp>(0.f, (im2 > 0 ? 1.f : -1.f)); 112e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else { 113e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _Tp den = ::cos(re2) + ::cosh(im2); 114e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return complex<_Tp>(::sin(re2) / den, ::sinh(im2) / den); 115e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 116e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 117e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 118e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL tan(const complex<float>& z) 119e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return tanT(z, float_limit); } 120e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 121e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL tan(const complex<double>& z) 122e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return tanT(z, double_limit); } 123e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 124e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE) 125e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL tan(const complex<long double>& z) 126e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return tanT(z, ldouble_limit); } 127e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 128e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 129e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//---------------------------------------------------------------------- 130e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// sinh 131e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp> 132e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> sinhT(const complex<_Tp>& z) { 133e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return complex<_Tp>(::sinh(z._M_re) * ::cos(z._M_im), 134e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ::cosh(z._M_re) * ::sin(z._M_im)); 135e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 136e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 137e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL sinh(const complex<float>& z) 138e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return sinhT(z); } 139e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 140e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL sinh(const complex<double>& z) 141e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return sinhT(z); } 142e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 143e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE) 144e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL sinh(const complex<long double>& z) 145e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return sinhT(z); } 146e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 147e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 148e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//---------------------------------------------------------------------- 149e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// cosh 150e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp> 151e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> coshT(const complex<_Tp>& z) { 152e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return complex<_Tp>(::cosh(z._M_re) * ::cos(z._M_im), 153e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ::sinh(z._M_re) * ::sin(z._M_im)); 154e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 155e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 156e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL cosh(const complex<float>& z) 157e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return coshT(z); } 158e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 159e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL cosh(const complex<double>& z) 160e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return coshT(z); } 161e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 162e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE) 163e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL cosh(const complex<long double>& z) 164e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return coshT(z); } 165e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 166e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 167e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//---------------------------------------------------------------------- 168e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// tanh 169e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _Tp> 170e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic complex<_Tp> tanhT(const complex<_Tp>& z, const _Tp& Tp_limit) { 171e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _Tp re2 = 2.f * z._M_re; 172e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _Tp im2 = 2.f * z._M_im; 173e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (::abs(re2) > Tp_limit) 174e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return complex<_Tp>((re2 > 0 ? 1.f : -1.f), 0.f); 175e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else { 176e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _Tp den = ::cosh(re2) + ::cos(im2); 177e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return complex<_Tp>(::sinh(re2) / den, ::sin(im2) / den); 178e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 179e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 180e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 181e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<float> _STLP_CALL tanh(const complex<float>& z) 182e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return tanhT(z, float_limit); } 183e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 184e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<double> _STLP_CALL tanh(const complex<double>& z) 185e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return tanhT(z, double_limit); } 186e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 187e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE) 188e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_DECLSPEC complex<long double> _STLP_CALL tanh(const complex<long double>& z) 189e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return tanhT(z, ldouble_limit); } 190e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 191e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 192e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_END_NAMESPACE 193