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