stdcpp/src/complex.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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