/home/ntakagi/work/STLport-5.1.5/src/complex_trig.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 #include "stlport_prefix.h"
00019 
00020 
00021 // Trigonometric and hyperbolic functions for complex<float>,
00022 // complex<double>, and complex<long double>
00023 #include <complex>
00024 #include <cfloat>
00025 #include <cmath>
00026 
00027 _STLP_BEGIN_NAMESPACE
00028 
00029 
00030 //----------------------------------------------------------------------
00031 // helpers
00032 #if defined (__sgi)
00033   static const union { unsigned int i; float f; } float_ulimit = { 0x42b2d4fc };
00034   static const float float_limit = float_ulimit.f;
00035   static union {
00036     struct { unsigned int h; unsigned int l; } w;
00037     double d;
00038   } double_ulimit = { 0x408633ce, 0x8fb9f87d };
00039   static const double double_limit = double_ulimit.d;
00040   static union {
00041     struct { unsigned int h[2]; unsigned int l[2]; } w;
00042     long double ld;
00043   } ldouble_ulimit = {0x408633ce, 0x8fb9f87e, 0xbd23b659, 0x4e9bd8b1};
00044 #  if !defined (_STLP_NO_LONG_DOUBLE)
00045   static const long double ldouble_limit = ldouble_ulimit.ld;
00046 #  endif
00047 #else
00048 #  if defined (M_LN2) && defined (FLT_MAX_EXP)
00049   static const float float_limit = float(M_LN2 * FLT_MAX_EXP);
00050   static const double double_limit = M_LN2 * DBL_MAX_EXP;
00051 #  else
00052   static const float float_limit = ::log(FLT_MAX);
00053   static const double double_limit = ::log(DBL_MAX);
00054 #  endif
00055 #  if !defined (_STLP_NO_LONG_DOUBLE)
00056 #    if defined (M_LN2l)
00057   static const long double ldouble_limit = M_LN2l * LDBL_MAX_EXP;
00058 #    else
00059   static const long double ldouble_limit = ::log(LDBL_MAX);
00060 #    endif
00061 #  endif
00062 #endif
00063 
00064 
00065 //----------------------------------------------------------------------
00066 // sin
00067 template <class _Tp>
00068 static complex<_Tp> sinT(const complex<_Tp>& z) {
00069   return complex<_Tp>(::sin(z._M_re) * ::cosh(z._M_im),
00070                       ::cos(z._M_re) * ::sinh(z._M_im));
00071 }
00072 
00073 _STLP_DECLSPEC complex<float> _STLP_CALL sin(const complex<float>& z)
00074 { return sinT(z); }
00075 
00076 _STLP_DECLSPEC complex<double> _STLP_CALL sin(const complex<double>& z)
00077 { return sinT(z); }
00078 
00079 #if !defined (_STLP_NO_LONG_DOUBLE)
00080 _STLP_DECLSPEC complex<long double> _STLP_CALL sin(const complex<long double>& z)
00081 { return sinT(z); }
00082 #endif
00083 
00084 //----------------------------------------------------------------------
00085 // cos
00086 template <class _Tp>
00087 static complex<_Tp> cosT(const complex<_Tp>& z) {
00088   return complex<_Tp>(::cos(z._M_re) * ::cosh(z._M_im),
00089                      -::sin(z._M_re) * ::sinh(z._M_im));
00090 }
00091 
00092 _STLP_DECLSPEC complex<float> _STLP_CALL cos(const complex<float>& z)
00093 { return cosT(z); }
00094 
00095 _STLP_DECLSPEC complex<double> _STLP_CALL cos(const complex<double>& z)
00096 { return cosT(z); }
00097 
00098 #if !defined (_STLP_NO_LONG_DOUBLE)
00099 _STLP_DECLSPEC complex<long double> _STLP_CALL cos(const complex<long double>& z)
00100 { return cosT(z); }
00101 #endif
00102 
00103 //----------------------------------------------------------------------
00104 // tan
00105 template <class _Tp>
00106 static complex<_Tp> tanT(const complex<_Tp>& z, const _Tp& Tp_limit) {
00107   _Tp re2 = 2.f * z._M_re;
00108   _Tp im2 = 2.f * z._M_im;
00109 
00110   if (::abs(im2) > Tp_limit)
00111     return complex<_Tp>(0.f, (im2 > 0 ? 1.f : -1.f));
00112   else {
00113     _Tp den = ::cos(re2) + ::cosh(im2);
00114     return complex<_Tp>(::sin(re2) / den, ::sinh(im2) / den);
00115   }
00116 }
00117 
00118 _STLP_DECLSPEC complex<float> _STLP_CALL tan(const complex<float>& z)
00119 { return tanT(z, float_limit); }
00120 
00121 _STLP_DECLSPEC complex<double> _STLP_CALL tan(const complex<double>& z)
00122 { return tanT(z, double_limit); }
00123 
00124 #if !defined (_STLP_NO_LONG_DOUBLE)
00125 _STLP_DECLSPEC complex<long double> _STLP_CALL tan(const complex<long double>& z)
00126 { return tanT(z, ldouble_limit); }
00127 #endif
00128 
00129 //----------------------------------------------------------------------
00130 // sinh
00131 template <class _Tp>
00132 static complex<_Tp> sinhT(const complex<_Tp>& z) {
00133   return complex<_Tp>(::sinh(z._M_re) * ::cos(z._M_im),
00134                       ::cosh(z._M_re) * ::sin(z._M_im));
00135 }
00136 
00137 _STLP_DECLSPEC complex<float> _STLP_CALL sinh(const complex<float>& z)
00138 { return sinhT(z); }
00139 
00140 _STLP_DECLSPEC complex<double> _STLP_CALL sinh(const complex<double>& z)
00141 { return sinhT(z); }
00142 
00143 #if !defined (_STLP_NO_LONG_DOUBLE)
00144 _STLP_DECLSPEC complex<long double> _STLP_CALL sinh(const complex<long double>& z)
00145 { return sinhT(z); }
00146 #endif
00147 
00148 //----------------------------------------------------------------------
00149 // cosh
00150 template <class _Tp>
00151 static complex<_Tp> coshT(const complex<_Tp>& z) {
00152   return complex<_Tp>(::cosh(z._M_re) * ::cos(z._M_im),
00153                       ::sinh(z._M_re) * ::sin(z._M_im));
00154 }
00155 
00156 _STLP_DECLSPEC complex<float> _STLP_CALL cosh(const complex<float>& z)
00157 { return coshT(z); }
00158 
00159 _STLP_DECLSPEC complex<double> _STLP_CALL cosh(const complex<double>& z)
00160 { return coshT(z); }
00161 
00162 #if !defined (_STLP_NO_LONG_DOUBLE)
00163 _STLP_DECLSPEC complex<long double> _STLP_CALL cosh(const complex<long double>& z)
00164 { return coshT(z); }
00165 #endif
00166 
00167 //----------------------------------------------------------------------
00168 // tanh
00169 template <class _Tp>
00170 static complex<_Tp> tanhT(const complex<_Tp>& z, const _Tp& Tp_limit) {
00171   _Tp re2 = 2.f * z._M_re;
00172   _Tp im2 = 2.f * z._M_im;
00173   if (::abs(re2) > Tp_limit)
00174     return complex<_Tp>((re2 > 0 ? 1.f : -1.f), 0.f);
00175   else {
00176     _Tp den = ::cosh(re2) + ::cos(im2);
00177     return complex<_Tp>(::sinh(re2) / den, ::sin(im2) / den);
00178   }
00179 }
00180 
00181 _STLP_DECLSPEC complex<float> _STLP_CALL tanh(const complex<float>& z)
00182 { return tanhT(z, float_limit); }
00183 
00184 _STLP_DECLSPEC complex<double> _STLP_CALL tanh(const complex<double>& z)
00185 { return tanhT(z, double_limit); }
00186 
00187 #if !defined (_STLP_NO_LONG_DOUBLE)
00188 _STLP_DECLSPEC complex<long double> _STLP_CALL tanh(const complex<long double>& z)
00189 { return tanhT(z, ldouble_limit); }
00190 #endif
00191 
00192 _STLP_END_NAMESPACE



Generated on Mon Mar 10 15:32:16 2008 by  doxygen 1.5.1