os/ossrv/genericopenlibs/cppstdlib/stl/src/complex_trig.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
 * Copyright (c) 1999
sl@0
     3
 * Silicon Graphics Computer Systems, Inc.
sl@0
     4
 *
sl@0
     5
 * Copyright (c) 1999
sl@0
     6
 * Boris Fomitchev
sl@0
     7
 *
sl@0
     8
 * This material is provided "as is", with absolutely no warranty expressed
sl@0
     9
 * or implied. Any use is at your own risk.
sl@0
    10
 *
sl@0
    11
 * Permission to use or copy this software for any purpose is hereby granted
sl@0
    12
 * without fee, provided the above notices are retained on all copies.
sl@0
    13
 * Permission to modify the code and to distribute modified code is granted,
sl@0
    14
 * provided the above notices are retained, and a notice that the code was
sl@0
    15
 * modified is included with the above copyright notice.
sl@0
    16
 *
sl@0
    17
 */
sl@0
    18
#include "stlport_prefix.h"
sl@0
    19
sl@0
    20
sl@0
    21
// Trigonometric and hyperbolic functions for complex<float>,
sl@0
    22
// complex<double>, and complex<long double>
sl@0
    23
#include <complex>
sl@0
    24
#include <cfloat>
sl@0
    25
#include <cmath>
sl@0
    26
sl@0
    27
_STLP_BEGIN_NAMESPACE
sl@0
    28
sl@0
    29
sl@0
    30
//----------------------------------------------------------------------
sl@0
    31
// helpers
sl@0
    32
#if defined (__sgi)
sl@0
    33
  static const union { unsigned int i; float f; } float_ulimit = { 0x42b2d4fc };
sl@0
    34
  static const float float_limit = float_ulimit.f;
sl@0
    35
  static union {
sl@0
    36
    struct { unsigned int h; unsigned int l; } w;
sl@0
    37
    double d;
sl@0
    38
  } double_ulimit = { 0x408633ce, 0x8fb9f87d };
sl@0
    39
  static const double double_limit = double_ulimit.d;
sl@0
    40
  static union {
sl@0
    41
    struct { unsigned int h[2]; unsigned int l[2]; } w;
sl@0
    42
    long double ld;
sl@0
    43
  } ldouble_ulimit = {0x408633ce, 0x8fb9f87e, 0xbd23b659, 0x4e9bd8b1};
sl@0
    44
#  if !defined (_STLP_NO_LONG_DOUBLE)
sl@0
    45
  static const long double ldouble_limit = ldouble_ulimit.ld;
sl@0
    46
#  endif
sl@0
    47
#else
sl@0
    48
#  if defined (M_LN2) && defined (FLT_MAX_EXP)
sl@0
    49
  static const float float_limit = float(M_LN2 * FLT_MAX_EXP);
sl@0
    50
  static const double double_limit = M_LN2 * DBL_MAX_EXP;
sl@0
    51
#  else
sl@0
    52
  static const float float_limit = ::log(FLT_MAX);
sl@0
    53
  static const double double_limit = ::log(DBL_MAX);
sl@0
    54
#  endif
sl@0
    55
#  if !defined (_STLP_NO_LONG_DOUBLE)
sl@0
    56
#    if defined (M_LN2l)
sl@0
    57
  static const long double ldouble_limit = M_LN2l * LDBL_MAX_EXP;
sl@0
    58
#    else
sl@0
    59
  static const long double ldouble_limit = ::log(LDBL_MAX);
sl@0
    60
#    endif
sl@0
    61
#  endif
sl@0
    62
#endif
sl@0
    63
sl@0
    64
sl@0
    65
//----------------------------------------------------------------------
sl@0
    66
// sin
sl@0
    67
template <class _Tp>
sl@0
    68
static complex<_Tp> sinT(const complex<_Tp>& z) {
sl@0
    69
  return complex<_Tp>(::sin(z._M_re) * ::cosh(z._M_im),
sl@0
    70
                      ::cos(z._M_re) * ::sinh(z._M_im));
sl@0
    71
}
sl@0
    72
sl@0
    73
_STLP_DECLSPEC complex<float> _STLP_CALL sin(const complex<float>& z)
sl@0
    74
{ return sinT(z); }
sl@0
    75
sl@0
    76
_STLP_DECLSPEC complex<double> _STLP_CALL sin(const complex<double>& z)
sl@0
    77
{ return sinT(z); }
sl@0
    78
sl@0
    79
#if !defined (_STLP_NO_LONG_DOUBLE)
sl@0
    80
_STLP_DECLSPEC complex<long double> _STLP_CALL sin(const complex<long double>& z)
sl@0
    81
{ return sinT(z); }
sl@0
    82
#endif
sl@0
    83
sl@0
    84
//----------------------------------------------------------------------
sl@0
    85
// cos
sl@0
    86
template <class _Tp>
sl@0
    87
static complex<_Tp> cosT(const complex<_Tp>& z) {
sl@0
    88
  return complex<_Tp>(::cos(z._M_re) * ::cosh(z._M_im),
sl@0
    89
                     -::sin(z._M_re) * ::sinh(z._M_im));
sl@0
    90
}
sl@0
    91
sl@0
    92
_STLP_DECLSPEC complex<float> _STLP_CALL cos(const complex<float>& z)
sl@0
    93
{ return cosT(z); }
sl@0
    94
sl@0
    95
_STLP_DECLSPEC complex<double> _STLP_CALL cos(const complex<double>& z)
sl@0
    96
{ return cosT(z); }
sl@0
    97
sl@0
    98
#if !defined (_STLP_NO_LONG_DOUBLE)
sl@0
    99
_STLP_DECLSPEC complex<long double> _STLP_CALL cos(const complex<long double>& z)
sl@0
   100
{ return cosT(z); }
sl@0
   101
#endif
sl@0
   102
sl@0
   103
//----------------------------------------------------------------------
sl@0
   104
// tan
sl@0
   105
template <class _Tp>
sl@0
   106
static complex<_Tp> tanT(const complex<_Tp>& z, const _Tp& Tp_limit) {
sl@0
   107
  _Tp re2 = 2.f * z._M_re;
sl@0
   108
  _Tp im2 = 2.f * z._M_im;
sl@0
   109
sl@0
   110
  if (::abs(im2) > Tp_limit)
sl@0
   111
    return complex<_Tp>(0.f, (im2 > 0 ? 1.f : -1.f));
sl@0
   112
  else {
sl@0
   113
    _Tp den = ::cos(re2) + ::cosh(im2);
sl@0
   114
    return complex<_Tp>(::sin(re2) / den, ::sinh(im2) / den);
sl@0
   115
  }
sl@0
   116
}
sl@0
   117
sl@0
   118
_STLP_DECLSPEC complex<float> _STLP_CALL tan(const complex<float>& z)
sl@0
   119
{ return tanT(z, float_limit); }
sl@0
   120
sl@0
   121
_STLP_DECLSPEC complex<double> _STLP_CALL tan(const complex<double>& z)
sl@0
   122
{ return tanT(z, double_limit); }
sl@0
   123
sl@0
   124
#if !defined (_STLP_NO_LONG_DOUBLE)
sl@0
   125
_STLP_DECLSPEC complex<long double> _STLP_CALL tan(const complex<long double>& z)
sl@0
   126
{ return tanT(z, ldouble_limit); }
sl@0
   127
#endif
sl@0
   128
sl@0
   129
//----------------------------------------------------------------------
sl@0
   130
// sinh
sl@0
   131
template <class _Tp>
sl@0
   132
static complex<_Tp> sinhT(const complex<_Tp>& z) {
sl@0
   133
  return complex<_Tp>(::sinh(z._M_re) * ::cos(z._M_im),
sl@0
   134
                      ::cosh(z._M_re) * ::sin(z._M_im));
sl@0
   135
}
sl@0
   136
sl@0
   137
_STLP_DECLSPEC complex<float> _STLP_CALL sinh(const complex<float>& z)
sl@0
   138
{ return sinhT(z); }
sl@0
   139
sl@0
   140
_STLP_DECLSPEC complex<double> _STLP_CALL sinh(const complex<double>& z)
sl@0
   141
{ return sinhT(z); }
sl@0
   142
sl@0
   143
#if !defined (_STLP_NO_LONG_DOUBLE)
sl@0
   144
_STLP_DECLSPEC complex<long double> _STLP_CALL sinh(const complex<long double>& z)
sl@0
   145
{ return sinhT(z); }
sl@0
   146
#endif
sl@0
   147
sl@0
   148
//----------------------------------------------------------------------
sl@0
   149
// cosh
sl@0
   150
template <class _Tp>
sl@0
   151
static complex<_Tp> coshT(const complex<_Tp>& z) {
sl@0
   152
  return complex<_Tp>(::cosh(z._M_re) * ::cos(z._M_im),
sl@0
   153
                      ::sinh(z._M_re) * ::sin(z._M_im));
sl@0
   154
}
sl@0
   155
sl@0
   156
_STLP_DECLSPEC complex<float> _STLP_CALL cosh(const complex<float>& z)
sl@0
   157
{ return coshT(z); }
sl@0
   158
sl@0
   159
_STLP_DECLSPEC complex<double> _STLP_CALL cosh(const complex<double>& z)
sl@0
   160
{ return coshT(z); }
sl@0
   161
sl@0
   162
#if !defined (_STLP_NO_LONG_DOUBLE)
sl@0
   163
_STLP_DECLSPEC complex<long double> _STLP_CALL cosh(const complex<long double>& z)
sl@0
   164
{ return coshT(z); }
sl@0
   165
#endif
sl@0
   166
sl@0
   167
//----------------------------------------------------------------------
sl@0
   168
// tanh
sl@0
   169
template <class _Tp>
sl@0
   170
static complex<_Tp> tanhT(const complex<_Tp>& z, const _Tp& Tp_limit) {
sl@0
   171
  _Tp re2 = 2.f * z._M_re;
sl@0
   172
  _Tp im2 = 2.f * z._M_im;
sl@0
   173
  if (::abs(re2) > Tp_limit)
sl@0
   174
    return complex<_Tp>((re2 > 0 ? 1.f : -1.f), 0.f);
sl@0
   175
  else {
sl@0
   176
    _Tp den = ::cosh(re2) + ::cos(im2);
sl@0
   177
    return complex<_Tp>(::sinh(re2) / den, ::sin(im2) / den);
sl@0
   178
  }
sl@0
   179
}
sl@0
   180
sl@0
   181
_STLP_DECLSPEC complex<float> _STLP_CALL tanh(const complex<float>& z)
sl@0
   182
{ return tanhT(z, float_limit); }
sl@0
   183
sl@0
   184
_STLP_DECLSPEC complex<double> _STLP_CALL tanh(const complex<double>& z)
sl@0
   185
{ return tanhT(z, double_limit); }
sl@0
   186
sl@0
   187
#if !defined (_STLP_NO_LONG_DOUBLE)
sl@0
   188
_STLP_DECLSPEC complex<long double> _STLP_CALL tanh(const complex<long double>& z)
sl@0
   189
{ return tanhT(z, ldouble_limit); }
sl@0
   190
#endif
sl@0
   191
sl@0
   192
_STLP_END_NAMESPACE