os/ossrv/stdcpp/src/complex.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
 * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
sl@0
     3
 *
sl@0
     4
 * Copyright (c) 1999
sl@0
     5
 * Silicon Graphics Computer Systems, Inc.
sl@0
     6
 *
sl@0
     7
 * Copyright (c) 1999 
sl@0
     8
 * Boris Fomitchev
sl@0
     9
 *
sl@0
    10
 * This material is provided "as is", with absolutely no warranty expressed
sl@0
    11
 * or implied. Any use is at your own risk.
sl@0
    12
 *
sl@0
    13
 * Permission to use or copy this software for any purpose is hereby granted 
sl@0
    14
 * without fee, provided the above notices are retained on all copies.
sl@0
    15
 * Permission to modify the code and to distribute modified code is granted,
sl@0
    16
 * provided the above notices are retained, and a notice that the code was
sl@0
    17
 * modified is included with the above copyright notice.
sl@0
    18
 *
sl@0
    19
 */ 
sl@0
    20
# include "stlport_prefix.h"
sl@0
    21
// Complex division and square roots.
sl@0
    22
sl@0
    23
#include "complex_impl.h"
sl@0
    24
#ifdef __ARMCC__
sl@0
    25
#undef _STLP_TEMPLATE_NULL
sl@0
    26
#define _STLP_TEMPLATE_NULL 
sl@0
    27
#endif
sl@0
    28
_STLP_BEGIN_NAMESPACE
sl@0
    29
sl@0
    30
// Absolute value
sl@0
    31
#ifdef __SYMBIAN32__
sl@0
    32
sl@0
    33
float abs_l(const complex<float>& __z)
sl@0
    34
{
sl@0
    35
  return _STLP_HYPOTF(__z._M_re, __z._M_im);
sl@0
    36
}
sl@0
    37
sl@0
    38
double _STLP_CALL abs_l(const complex<double>& __z)
sl@0
    39
{
sl@0
    40
  return _STLP_HYPOT(__z._M_re, __z._M_im);
sl@0
    41
}
sl@0
    42
sl@0
    43
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
    44
long double _STLP_CALL abs_l(const complex<long double>& __z)
sl@0
    45
{
sl@0
    46
  return _STLP_HYPOTL(__z._M_re, __z._M_im);
sl@0
    47
}
sl@0
    48
#endif
sl@0
    49
#else
sl@0
    50
_STLP_TEMPLATE_NULL
sl@0
    51
_STLP_EXP_DECLSPEC float _STLP_CALL abs(const complex<float>& __z)
sl@0
    52
{
sl@0
    53
  return _STLP_HYPOTF(__z._M_re, __z._M_im);
sl@0
    54
}
sl@0
    55
_STLP_TEMPLATE_NULL
sl@0
    56
_STLP_EXP_DECLSPEC double _STLP_CALL abs(const complex<double>& __z)
sl@0
    57
{
sl@0
    58
  return _STLP_HYPOT(__z._M_re, __z._M_im);
sl@0
    59
}
sl@0
    60
sl@0
    61
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
    62
_STLP_TEMPLATE_NULL
sl@0
    63
_STLP_EXP_DECLSPEC long double _STLP_CALL abs(const complex<long double>& __z)
sl@0
    64
{
sl@0
    65
  return _STLP_HYPOTL(__z._M_re, __z._M_im);
sl@0
    66
}
sl@0
    67
#endif
sl@0
    68
#endif
sl@0
    69
sl@0
    70
// Phase
sl@0
    71
#ifdef __SYMBIAN32__
sl@0
    72
sl@0
    73
float _STLP_CALL arg_l(const complex<float>& __z) 
sl@0
    74
{
sl@0
    75
  return _STLP_ATAN2F(__z._M_im, __z._M_re);
sl@0
    76
}
sl@0
    77
sl@0
    78
sl@0
    79
double _STLP_CALL arg_l(const complex<double>& __z) 
sl@0
    80
{
sl@0
    81
  return _STLP_ATAN2(__z._M_im, __z._M_re);
sl@0
    82
}
sl@0
    83
sl@0
    84
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
    85
long double _STLP_CALL arg_l(const complex<long double>& __z) 
sl@0
    86
{
sl@0
    87
  return _STLP_ATAN2L(__z._M_im, __z._M_re);
sl@0
    88
}
sl@0
    89
#endif
sl@0
    90
#else
sl@0
    91
sl@0
    92
_STLP_TEMPLATE_NULL 
sl@0
    93
_STLP_EXP_DECLSPEC float _STLP_CALL arg(const complex<float>& __z) 
sl@0
    94
{
sl@0
    95
  return _STLP_ATAN2F(__z._M_im, __z._M_re);
sl@0
    96
}
sl@0
    97
sl@0
    98
_STLP_TEMPLATE_NULL 
sl@0
    99
_STLP_EXP_DECLSPEC double _STLP_CALL arg(const complex<double>& __z) 
sl@0
   100
{
sl@0
   101
  return _STLP_ATAN2(__z._M_im, __z._M_re);
sl@0
   102
}
sl@0
   103
sl@0
   104
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
   105
_STLP_TEMPLATE_NULL
sl@0
   106
_STLP_EXP_DECLSPEC long double _STLP_CALL arg(const complex<long double>& __z) 
sl@0
   107
{
sl@0
   108
  return _STLP_ATAN2L(__z._M_im, __z._M_re);
sl@0
   109
}
sl@0
   110
#endif
sl@0
   111
#endif
sl@0
   112
sl@0
   113
// Construct a complex number from polar representation
sl@0
   114
#ifdef __SYMBIAN32__
sl@0
   115
complex<float> _STLP_CALL polar_l(const float& __rho, const float& __phi) 
sl@0
   116
{
sl@0
   117
  return complex<float>(__rho * _STLP_COSF(__phi), __rho * _STLP_SINF(__phi));
sl@0
   118
}
sl@0
   119
sl@0
   120
complex<double> _STLP_CALL polar_l(const double& __rho, const double& __phi) 
sl@0
   121
{
sl@0
   122
  return complex<double>(__rho * _STLP_COS(__phi), __rho * _STLP_SIN(__phi));
sl@0
   123
}
sl@0
   124
sl@0
   125
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
   126
complex<long double> _STLP_CALL polar_l(const long double& __rho, const long double& __phi)
sl@0
   127
{
sl@0
   128
  return complex<long double>(__rho * _STLP_COSL(__phi), __rho * _STLP_SINL(__phi));
sl@0
   129
}
sl@0
   130
#endif
sl@0
   131
sl@0
   132
#else
sl@0
   133
_STLP_TEMPLATE_NULL
sl@0
   134
_STLP_EXP_DECLSPEC complex<float> _STLP_CALL polar(const float& __rho, const float& __phi) 
sl@0
   135
{
sl@0
   136
  return complex<float>(__rho * _STLP_COSF(__phi), __rho * _STLP_SINF(__phi));
sl@0
   137
}
sl@0
   138
_STLP_TEMPLATE_NULL
sl@0
   139
_STLP_EXP_DECLSPEC complex<double> _STLP_CALL polar(const double& __rho, const double& __phi) 
sl@0
   140
{
sl@0
   141
  return complex<double>(__rho * _STLP_COS(__phi), __rho * _STLP_SIN(__phi));
sl@0
   142
}
sl@0
   143
sl@0
   144
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
   145
_STLP_TEMPLATE_NULL 
sl@0
   146
_STLP_EXP_DECLSPEC complex<long double> _STLP_CALL polar(const long double& __rho, const long double& __phi)
sl@0
   147
{
sl@0
   148
  return complex<long double>(__rho * _STLP_COSL(__phi), __rho * _STLP_SINL(__phi));
sl@0
   149
}
sl@0
   150
#endif
sl@0
   151
sl@0
   152
#endif
sl@0
   153
// Division
sl@0
   154
sl@0
   155
void  _STLP_EXP_DECLSPEC
sl@0
   156
complex<float>::_div(const float& __z1_r, const float& __z1_i,
sl@0
   157
		     const float& __z2_r, const float& __z2_i,
sl@0
   158
		     float& __res_r, float& __res_i) {
sl@0
   159
  float __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
sl@0
   160
  float __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
sl@0
   161
sl@0
   162
  if (__ar <= __ai) {
sl@0
   163
    float __ratio = __z2_r / __z2_i;
sl@0
   164
    float __denom = __z2_i * (1 + __ratio * __ratio);
sl@0
   165
    __res_r = (__z1_r * __ratio + __z1_i) / __denom;
sl@0
   166
    __res_i = (__z1_i * __ratio - __z1_r) / __denom;
sl@0
   167
  }
sl@0
   168
  else {
sl@0
   169
    float __ratio = __z2_i / __z2_r;
sl@0
   170
    float __denom = __z2_r * (1 + __ratio * __ratio);
sl@0
   171
    __res_r = (__z1_r + __z1_i * __ratio) / __denom;
sl@0
   172
    __res_i = (__z1_i - __z1_r * __ratio) / __denom;
sl@0
   173
  }
sl@0
   174
}
sl@0
   175
sl@0
   176
void  _STLP_EXP_DECLSPEC
sl@0
   177
complex<float>::_div(const float& __z1_r,
sl@0
   178
                     const float& __z2_r, const float& __z2_i,
sl@0
   179
                     float& __res_r, float& __res_i) {
sl@0
   180
  float __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
sl@0
   181
  float __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
sl@0
   182
sl@0
   183
  if (__ar <= __ai) {
sl@0
   184
    float __ratio = __z2_r / __z2_i;
sl@0
   185
    float __denom = __z2_i * (1 + __ratio * __ratio);
sl@0
   186
    __res_r = (__z1_r * __ratio) / __denom;
sl@0
   187
    __res_i = - __z1_r / __denom;
sl@0
   188
  }
sl@0
   189
  else {
sl@0
   190
    float __ratio = __z2_i / __z2_r;
sl@0
   191
    float __denom = __z2_r * (1 + __ratio * __ratio);
sl@0
   192
    __res_r = __z1_r / __denom;
sl@0
   193
    __res_i = - (__z1_r * __ratio) / __denom;
sl@0
   194
  }
sl@0
   195
}
sl@0
   196
sl@0
   197
sl@0
   198
void  _STLP_EXP_DECLSPEC
sl@0
   199
complex<double>::_div(const double& __z1_r, const double& __z1_i,
sl@0
   200
                      const double& __z2_r, const double& __z2_i,
sl@0
   201
                      double& __res_r, double& __res_i) {
sl@0
   202
  double __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
sl@0
   203
  double __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
sl@0
   204
sl@0
   205
  if (__ar <= __ai) {
sl@0
   206
    double __ratio = __z2_r / __z2_i;
sl@0
   207
    double __denom = __z2_i * (1 + __ratio * __ratio);
sl@0
   208
    __res_r = (__z1_r * __ratio + __z1_i) / __denom;
sl@0
   209
    __res_i = (__z1_i * __ratio - __z1_r) / __denom;
sl@0
   210
  }
sl@0
   211
  else {
sl@0
   212
    double __ratio = __z2_i / __z2_r;
sl@0
   213
    double __denom = __z2_r * (1 + __ratio * __ratio);
sl@0
   214
    __res_r = (__z1_r + __z1_i * __ratio) / __denom;
sl@0
   215
    __res_i = (__z1_i - __z1_r * __ratio) / __denom;
sl@0
   216
  }
sl@0
   217
}
sl@0
   218
sl@0
   219
void _STLP_EXP_DECLSPEC
sl@0
   220
complex<double>::_div(const double& __z1_r,
sl@0
   221
                      const double& __z2_r, const double& __z2_i,
sl@0
   222
                      double& __res_r, double& __res_i) {
sl@0
   223
  double __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
sl@0
   224
  double __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
sl@0
   225
sl@0
   226
  if (__ar <= __ai) {
sl@0
   227
    double __ratio = __z2_r / __z2_i;
sl@0
   228
    double __denom = __z2_i * (1 + __ratio * __ratio);
sl@0
   229
    __res_r = (__z1_r * __ratio) / __denom;
sl@0
   230
    __res_i = - __z1_r / __denom;
sl@0
   231
  }
sl@0
   232
  else {
sl@0
   233
    double __ratio = __z2_i / __z2_r;
sl@0
   234
    double __denom = __z2_r * (1 + __ratio * __ratio);
sl@0
   235
    __res_r = __z1_r / __denom;
sl@0
   236
    __res_i = - (__z1_r * __ratio) / __denom;
sl@0
   237
  }
sl@0
   238
}
sl@0
   239
sl@0
   240
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
   241
void  _STLP_CALL
sl@0
   242
complex<long double>::_div(const long double& __z1_r, const long double& __z1_i,
sl@0
   243
                           const long double& __z2_r, const long double& __z2_i,
sl@0
   244
                           long double& __res_r, long double& __res_i) {
sl@0
   245
  long double __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
sl@0
   246
  long double __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
sl@0
   247
sl@0
   248
  if (__ar <= __ai) {
sl@0
   249
    long double __ratio = __z2_r / __z2_i;
sl@0
   250
    long double __denom = __z2_i * (1 + __ratio * __ratio);
sl@0
   251
    __res_r = (__z1_r * __ratio + __z1_i) / __denom;
sl@0
   252
    __res_i = (__z1_i * __ratio - __z1_r) / __denom;
sl@0
   253
  }
sl@0
   254
  else {
sl@0
   255
    long double __ratio = __z2_i / __z2_r;
sl@0
   256
    long double __denom = __z2_r * (1 + __ratio * __ratio);
sl@0
   257
    __res_r = (__z1_r + __z1_i * __ratio) / __denom;
sl@0
   258
    __res_i = (__z1_i - __z1_r * __ratio) / __denom;
sl@0
   259
  }
sl@0
   260
}
sl@0
   261
sl@0
   262
sl@0
   263
void _STLP_CALL
sl@0
   264
complex<long double>::_div(const long double& __z1_r,
sl@0
   265
                           const long double& __z2_r, const long double& __z2_i,
sl@0
   266
                           long double& __res_r, long double& __res_i) {
sl@0
   267
  long double __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
sl@0
   268
  long double __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
sl@0
   269
sl@0
   270
  if (__ar <= __ai) {
sl@0
   271
    long double __ratio = __z2_r / __z2_i;
sl@0
   272
    long double __denom = __z2_i * (1 + __ratio * __ratio);
sl@0
   273
    __res_r = (__z1_r * __ratio) / __denom;
sl@0
   274
    __res_i = - __z1_r / __denom;
sl@0
   275
  }
sl@0
   276
  else {
sl@0
   277
    long double __ratio = __z2_i / __z2_r;
sl@0
   278
    long double __denom = __z2_r * (1 + __ratio * __ratio);
sl@0
   279
    __res_r = __z1_r / __denom;
sl@0
   280
    __res_i = - (__z1_r * __ratio) / __denom;
sl@0
   281
  }
sl@0
   282
}
sl@0
   283
#endif
sl@0
   284
sl@0
   285
//----------------------------------------------------------------------
sl@0
   286
// Square root
sl@0
   287
sl@0
   288
sl@0
   289
_STLP_EXP_DECLSPEC complex<float> _STLP_CALL
sl@0
   290
sqrt(const complex<float>& z) {
sl@0
   291
  float re = z._M_re;
sl@0
   292
  float im = z._M_im;
sl@0
   293
  float mag = _STLP_HYPOTF(re, im);
sl@0
   294
  complex<float> result;
sl@0
   295
sl@0
   296
  if (mag == 0.) {
sl@0
   297
    result._M_re = result._M_im = 0.f;
sl@0
   298
  } else if (re > 0.f) {
sl@0
   299
    result._M_re = _STLP_SQRTF(0.5f * (mag + re));
sl@0
   300
    result._M_im = im/result._M_re/2.f;
sl@0
   301
  } else {
sl@0
   302
    result._M_im = _STLP_SQRTF(0.5f * (mag - re));
sl@0
   303
    if (im < 0.f)
sl@0
   304
      result._M_im = - result._M_im;
sl@0
   305
    result._M_re = im/result._M_im/2.f;
sl@0
   306
  }
sl@0
   307
  return result;
sl@0
   308
}
sl@0
   309
sl@0
   310
sl@0
   311
_STLP_EXP_DECLSPEC complex<double>  _STLP_CALL
sl@0
   312
sqrt(const complex<double>& z) {
sl@0
   313
  double re = z._M_re;
sl@0
   314
  double im = z._M_im;
sl@0
   315
  double mag = _STLP_HYPOT(re, im);
sl@0
   316
  complex<double> result;
sl@0
   317
sl@0
   318
  if (mag == 0.) {
sl@0
   319
    result._M_re = result._M_im = 0.;
sl@0
   320
  } else if (re > 0.) {
sl@0
   321
    result._M_re = _STLP_SQRT(0.5 * (mag + re));
sl@0
   322
    result._M_im = im/result._M_re/2;
sl@0
   323
  } else {
sl@0
   324
    result._M_im = _STLP_SQRT(0.5 * (mag - re));
sl@0
   325
    if (im < 0.)
sl@0
   326
      result._M_im = - result._M_im;
sl@0
   327
    result._M_re = im/result._M_im/2;
sl@0
   328
  }
sl@0
   329
  return result;
sl@0
   330
}
sl@0
   331
sl@0
   332
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
   333
_STLP_EXP_DECLSPEC complex<long double> _STLP_CALL
sl@0
   334
sqrt(const complex<long double>& z) {
sl@0
   335
  long double re = z._M_re;
sl@0
   336
  long double im = z._M_im;
sl@0
   337
  long double mag = _STLP_HYPOTL(re, im);
sl@0
   338
  complex<long double> result;
sl@0
   339
sl@0
   340
  if (mag == 0.L) {
sl@0
   341
    result._M_re = result._M_im = 0.L;
sl@0
   342
  } else if (re > 0.L) {
sl@0
   343
    result._M_re = _STLP_SQRTL(0.5L * (mag + re));
sl@0
   344
    result._M_im = (im/result._M_re) * .5L;
sl@0
   345
  } else {
sl@0
   346
    result._M_im = _STLP_SQRTL(0.5L * (mag - re));
sl@0
   347
    if (im < 0.L)
sl@0
   348
      result._M_im = - result._M_im;
sl@0
   349
    result._M_re = (im/result._M_im) * .5L;
sl@0
   350
  }
sl@0
   351
  return result;
sl@0
   352
}
sl@0
   353
#endif
sl@0
   354
sl@0
   355
#ifdef __SYMBIAN32__
sl@0
   356
template <class _Tp>
sl@0
   357
_STLP_EXP_DECLSPEC _Tp  _STLP_CALL abs_tp(const complex<_Tp>& val)
sl@0
   358
    {
sl@0
   359
    return abs_l(val);
sl@0
   360
    }
sl@0
   361
sl@0
   362
template <class _Tp>
sl@0
   363
_STLP_EXP_DECLSPEC _Tp  _STLP_CALL arg_tp(const complex<_Tp>& val)
sl@0
   364
    {
sl@0
   365
    return arg_l(val);
sl@0
   366
    }
sl@0
   367
    
sl@0
   368
template <class _Tp>
sl@0
   369
_STLP_EXP_DECLSPEC complex<_Tp> _STLP_CALL polar_tp(const _Tp& __rho, const _Tp& __phi)
sl@0
   370
    {
sl@0
   371
    return polar_l(__rho, __phi);
sl@0
   372
    }
sl@0
   373
sl@0
   374
 
sl@0
   375
void dummy_instantiate_func()
sl@0
   376
{
sl@0
   377
    const complex<float> val;
sl@0
   378
    float fval;
sl@0
   379
    abs_tp(val);
sl@0
   380
    arg_tp(val);
sl@0
   381
    polar_tp(fval, fval);
sl@0
   382
    const complex<double> dval;
sl@0
   383
    double dv;
sl@0
   384
    abs_tp(dval);
sl@0
   385
    arg_tp(dval);
sl@0
   386
    polar_tp(dv, dv);
sl@0
   387
sl@0
   388
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
   389
    const complex<long double> lval;
sl@0
   390
    long double lv;
sl@0
   391
    abs_tp(lval);
sl@0
   392
    arg_tp(lval);
sl@0
   393
    polar_tp(lv, lv);
sl@0
   394
#endif
sl@0
   395
}
sl@0
   396
sl@0
   397
sl@0
   398
#endif
sl@0
   399
//template <>
sl@0
   400
//_STLP_EXP_DECLSPEC float  _STLP_CALL abs_tp(const complex<float>& val);
sl@0
   401
sl@0
   402
_STLP_END_NAMESPACE
sl@0
   403
sl@0
   404
#ifdef __ARMCC__
sl@0
   405
#undef _STLP_TEMPLATE_NULL
sl@0
   406
#endif