Main Page | Alphabetical List | Class List | File List | Class Members | File Members

complex.h

Go to the documentation of this file.
00001 /* ------------------------------------------------------------------------------------- */
00038 /* ------------------------------------------------------------------------------------- */
00053 /* ------------------------------------------------------------------------------------- */
00054 // define the range of used complex (and imaginary) numbers 
00055 //#pragma STDC CX_LIMITED_RANGE OFF
00056  
00057               // _Imaginary_I, _Complex_I, _Imaginary, _Complex, 
00058               // I are macros expanding to: 
00059 //complex       // to _Complex.
00060 //_Complex_I    // to a constant expression of type const float _Complex, 
00061               // with the value of the imaginary unit */
00062               // (that is, a number i such that i.i=-1).
00063 //imaginary     // to _Imaginary
00064 //_Imaginary_I  // to a constant expression of type const float _Imaginary 
00065               // with the value of the imaginary unit, or expands to 
00066               // either _Imaginary_I or _Complex_I.  
00067               // If _Imaginary_I is not defined, I expands to _Complex_I.
00068 // I have commented out this. Otherwise complex.h is not includeable.
00069 
00070 /* ------------------------------------------------------------------------------------- */
00107 /* ------------------------------------------------------------------------------------- */
00108 
00109 #ifndef _COMPLEX_H
00110 #define _COMPLEX_H
00111 
00112 #include <nlibc.h>
00113 #include <math.h>
00114 
00115 #define _math_setdouble(U,D) { \
00116   register union { double d; unsigned i; } u; \
00117   asm("\tatr0h %0 <"#U">" : "=r" (u.i)); D=u.d; \
00118 }
00119 
00120 #define _Complex_I {0., 1.}                    /* imaginary unit */
00121 #define I _Complex_I                           /* imaginary unit */ 
00122 
00123 #define M_PI           3.14159265358979323846  /* pi */
00124 #define M_PI_2         1.57079632679489661923  /* pi/2 */
00125 #define M_PI_4         0.78539816339744830962  /* pi/4 */
00126 
00127 #define conj(x)  (~(x))
00128 #define creal(x) ((x).re)
00129 #define cimag(x) ((x).im)
00130 
00131 
00132 /* ------------------------------------------------------------------------------------- */
00133 /*  nan(char *) not implemented, using workaround:            */
00134 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00135 extern math_inline double cnan(void);
00136 #else
00137 #if defined(_uses_cnan_complex_h) || !defined(__cflow_processed)
00138 math_inline double cnan(void)
00139 {
00140   //  unsigned int nan=0x7FF0000000000001ULL;
00141   //  return *((double*)&nan);
00142   register double nan; 
00143   _math_setdouble( 0x7FF0000000000001 , nan );
00144  return nan;
00145 }
00146 #endif  // cnan
00147 #endif // Has Main
00148 
00149 #define NAN                 (cnan())  // (nan("")    
00150 
00151 /*  using HUGE_VAL (=INFINITY) comes with warnings:           */
00152 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00153 extern math_inline double cinfty(void);
00154 #else
00155 #if defined(_uses_cinfty_complex_h) || !defined(__cflow_processed)
00156 math_inline double cinfty(void)
00157 {
00158   register double infty; 
00159   _math_setdouble( 0x7FF0000000000000 , infty );
00160  return infty;
00161 }
00162 #endif  // cinfty
00163 #endif // Has Main
00164 
00165 #define HUGE_VALD           (cinfty())    
00166 
00167 /*
00168                     glibc     ape                         
00169 #define FP_NAN        1   //   3
00170 #define FP_INFINITE   2   //   2
00171 #define FP_ZERO       3   //   4
00172 #define FP_NORMAL     4   //   1
00173 #define FP_SUBNORMAL  5   //   1
00174 
00175 #if defined(_uses_cfpclassify_complex_h) || !defined(__cflow_processed)
00176 math_inline int cfpclassify(double x) {
00177   register unsigned int _emask,_mmask;
00178   register int ie,ii,ij;
00179   register union {
00180     double xr;
00181     unsigned int xint;
00182   } xu;
00183  
00184   _emask=0x7FF0000000000000ULL;
00185   _mmask=0x000fffffffffffffULL;
00186   xu.xr = x;
00187   ii = (_emask&xu.xint);
00188   ij = (_mmask&xu.xint);
00189   where ((ii != _emask) && (ij != 0))  ie = FP_NORMAL;
00190   where ((ii == _emask) && (ij == 0) ) ie = FP_INFINITE;
00191   where ((ii == _emask) && (ij != 0) ) ie = FP_NAN;
00192   where ((ii == 0) && (ij == 0))       ie = FP_ZERO;
00193   return ie;
00194 }
00195 #endif
00196 */
00197 /* ------------------------------------------------------------------------------------- */
00198 
00199 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00200 extern math_inline complex sincos(double x);
00201 #else
00202 #if defined(_uses_sincos_complex_h) || !defined(__cflow_processed)
00203 math_inline complex sincos(double x)
00204 {
00205   register double twooverpi, pihalflead, pihalftrail1, pihalftrail2, magic2, f, y, siny, cosy;
00206   register complex sc;
00207   register int k;
00208   register union {
00209     double z;
00210     int zint;
00211   } zu;
00212   _math_setdouble(  0x3fe45f306dc9c883 , twooverpi   );
00213   _math_setdouble(  0x4337ffffffffffff , magic2      );
00214   _math_setdouble(  0x3ff921fb50000000 , pihalflead  );
00215   _math_setdouble(  0x3e5110b460000000 , pihalftrail1 );
00216   _math_setdouble(  0x3c91a62633145c07 , pihalftrail2 );
00217   zu.z = magic2 + twooverpi * x;
00218   f = zu.z - magic2;
00219   y = x - f * pihalflead;
00220   y = y - f * pihalftrail1;
00221   y = y - f * pihalftrail2;
00222   siny = sin_1oct(y);
00223   cosy = cos_1oct(y);
00224   k = 0x3;
00225   k = zu.zint & k ;
00226   where ( k == 3 ) {
00227     sc.re =  siny;
00228     sc.im =  cosy;
00229   }
00230   where ( k == 0 ) {
00231     sc.re =  cosy;
00232     sc.im = -siny;
00233   }
00234   where ( k == 1 ) {
00235     sc.re = -siny;
00236     sc.im = -cosy;
00237   }
00238   where ( k == 2 ) {
00239     sc.re = -cosy;
00240     sc.im =  siny;
00241   }
00242   return sc;                    // (sin(x), cos(x))
00243 }
00244 #endif  // sincos
00245 #endif // Has Main
00246 
00247 /* ------------------------------------------------------------------------------------- */
00248 
00249 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00250 extern math_inline complex sinhcosh(double x);
00251 #else
00252 #if defined(_uses_sinhcosh_complex_h) || !defined(__cflow_processed)
00253 math_inline complex sinhcosh(double x)
00254 {
00255   register double expx, expxm;
00256   register complex shch;
00257   expx  = 0.5 * expm1( x);
00258   expxm = 0.5 * expm1(-x);
00259   shch.re = (expx - expxm);
00260   shch.im = (expx + expxm + 1.0);
00261   return shch;                   // (sinh(x), cosh(x))
00262 } 
00263 #endif  // sinhcosh
00264 #endif // Has Main
00265 
00266 /* ------------------------------------------------------------------------------------- */
00267 
00268 
00269 
00270 /* ------------------------------------------------------------------------------------- */
00301 /* ------------------------------------------------------------------------------------- */
00302 
00303 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00304 extern math_inline double cabs(complex z) ;
00305 #else
00306 #if defined(_uses_cabs_complex_h) || !defined(__cflow_processed)
00307 math_inline double cabs(complex z) 
00308 {
00309   register complex res;
00310   
00311   res = hypot(z.re,z.im);
00312   return res;
00313 }
00314 #endif // cabs()
00315 #endif // Has Main
00316 
00317 /* ------------------------------------------------------------------------------------- */
00349 /* ------------------------------------------------------------------------------------- */
00350 
00351 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00352 extern math_inline double carg(complex z) ;
00353 #else
00354 #if !defined(__cflow_processed) || defined(_uses_carg_complex_h)
00355 math_inline double carg(complex z) 
00356 {
00357   register complex res;
00358 
00359   res = atan2(z.im,z.re);
00360   return res;
00361 }
00362 #endif // carg()
00363 #endif // Has Main
00364 
00365 
00366 /* ------------------------------------------------------------------------------------- */
00403 /* ------------------------------------------------------------------------------------- */
00404 
00405 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00406 extern math_inline complex cproj(complex z) ;
00407 #else
00408 #if defined(_uses_cproj_complex_h) || !defined(__cflow_processed)
00409 math_inline complex cproj(complex z) 
00410 {
00411   register complex res;
00412   register double den;
00413 
00414 #if defined(__FAST_MATH__)
00415   den = z.re * z.re + z.im * z.im +1.0;       //test:  den = z*(~z) + 1.0;
00416   res.re = (2.0 * z.re)/den;                  //test:  res = (2.0 * z) / den;
00417   res.im = (2.0 * z.im)/den;
00418 
00419 #else
00420   register int rcls, icls;
00421   rcls = fpclassify(z.re);
00422   icls = fpclassify(z.im);
00423   where (rcls == FP_NAN  && icls == FP_NAN) {
00424     res = z;
00425   } 
00426   else where ((!(rcls == FP_ZERO) && !(rcls == FP_NORMAL)) || (!(icls == FP_ZERO) && !(icls == FP_NORMAL))) {
00427     res.re = HUGE_VALD;
00428     res.im = copysign(0.0, z.im);
00429   }
00430   else {
00431     den = z.re * z.re + z.im * z.im + 1.0; 
00432     res.re = (2.0 * z.re)/den;             
00433     res.im = (2.0 * z.im)/den;
00434   }
00435 #endif
00436   return res;
00437 }
00438 #endif // cproj()
00439 #endif // Has Main
00440 
00441 
00442 /* ------------------------------------------------------------------------------------- */
00473 /* ------------------------------------------------------------------------------------- */
00474 
00475 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00476 extern math_inline complex cexp(complex z) ;
00477 #else
00478 #if defined(_uses_cexp_complex_h) || !defined(__cflow_processed) 
00479 math_inline complex cexp(complex z) 
00480 {
00481   register complex res, sc;
00482   register double exp_val;
00483 
00484 #if defined(__FAST_MATH__)
00485   sc = sincos(z.im);
00486   exp_val = exp(z.re);
00487   res.re = exp_val * sc.im;
00488   res.im = exp_val * sc.re;
00489 
00490 
00491 #else
00492   register double value;
00493   register int rcls, icls, ecls;
00494   rcls = fpclassify(z.re);
00495   icls = fpclassify(z.im);
00496   where ((rcls == FP_ZERO) || (rcls == FP_NORMAL)) {              // Real part is finite.  
00497     where ((icls == FP_ZERO) || (icls == FP_NORMAL)) {              // Imaginary part is finite.
00498       exp_val = exp(z.re);
00499       ecls = fpclassify(exp_val);
00500       sc = sincos(z.im);
00501       where (ecls == FP_ZERO || ecls == FP_NORMAL) {
00502       //      where (isfinite(exp_val)) {
00503         res.re = exp_val * sc.im;
00504         res.im = exp_val * sc.re;
00505       }
00506       else {
00507         res.re = copysign(exp_val, sc.im);
00508         res.im = copysign(exp_val, sc.re);
00509       }
00510     }
00511     else { // If the imaginary part is +-inf or NaN and the real part is not +-inf 
00512            //   the result is NaN + iNaN. 
00513       res.re = NAN;
00514       res.im = NAN;
00515       //#ifdef FE_INVALID
00516       //feraiseexcept(FE_INVALID);
00517       //#endif
00518     }
00519   }
00520   else where (rcls == FP_INFINITE) {           // Real part is infinite. 
00521     where ((icls == FP_ZERO) || (icls == FP_NORMAL)) {  // Imaginary part is finite.
00522       value = signbit(z.re) ? 0.0 : HUGE_VALD;
00523       where (icls == FP_ZERO) {                // Imaginary part is 0.0.  
00524         res.re = value;
00525         res.im = z.im;
00526       }
00527       else {
00528         sc = sincos(z.im);
00529         res.re = copysign(value, sc.im);
00530         res.im = copysign(value, sc.re);
00531       }
00532     }
00533     else where (signbit(z.re) == 0) {
00534           res.re = HUGE_VALD;
00535           res.im = NAN;
00536           //#ifdef FE_INVALID
00537           //where (icls == FP_INFINITE) feraiseexcept(FE_INVALID);
00538           //#endif
00539     }
00540     else {
00541       res.re = 0.0;
00542       res.im = copysign(0.0, z.im);
00543     }
00544   }
00545   else {                       // If the real part is NaN the result is NaN + iNaN.
00546      res.re = NAN;
00547      res.im = NAN;
00548     //#ifdef FE_INVALID
00549     //where (rcls != FP_NAN || icls != FP_NAN) feraiseexcept(FE_INVALID);
00550     //#endif
00551   }
00552 
00553 #endif
00554   return res;
00555 }
00556 #endif // cexp()
00557 #endif // Has Main
00558 
00559 /* ------------------------------------------------------------------------------------- */
00592 /* ------------------------------------------------------------------------------------- */
00593 
00594 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00595 extern math_inline complex clog(complex z);
00596 #else
00597 #if defined(_uses_clog_complex_h) || !defined(__cflow_processed)
00598 math_inline complex clog(complex z)
00599 {
00600   register complex res;
00601 
00602 #if defined(__FAST_MATH__)
00603   res.re = log(hypot(z.re, z.im));  //test: res.re = 0.5*log(~z*z);
00604   res.im = atan2(z.im,z.re);
00605 
00606 #else
00607   register int rcls, icls;
00608   rcls = fpclassify(z.re);
00609   icls = fpclassify(z.im);
00610   where (rcls == FP_ZERO && icls == FP_ZERO) {
00611     res.im = signbit(z.re) ? M_PI : 0.0;
00612     res.im = copysign(res.im, z.im);
00613     res.re = -HUGE_VALD;  //orig.:  res.re = -1.0 / fabs(z.re);  -> exeption,  why ?
00614   }
00615   else where (rcls != FP_NAN && icls != FP_NAN) {
00616     res.re = log(hypot(z.re, z.im));
00617     res.im = atan2(z.im, z.re);
00618 
00619   } else {
00620     res.im = NAN;
00621     where (rcls == FP_INFINITE || icls == FP_INFINITE)  res.re = HUGE_VALD;
00622     else res.re = NAN;
00623   }
00624 #endif
00625   return res;
00626 }
00627 #endif // clog()
00628 #endif // Has Main
00629 
00630 /* ------------------------------------------------------------------------------------- */
00661 /* ------------------------------------------------------------------------------------- */
00662 
00663 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00664 extern math_inline complex cpow(complex x, complex y) ;
00665 #else
00666 #if defined(_uses_cpow_complex_h) || !defined(__cflow_processed)
00667 math_inline complex cpow(complex x, complex y) 
00668 {
00669   register complex res;
00670 
00671   res = cexp(y*clog(x));
00672   return res;
00673 }
00674 #endif // cpow()
00675 #endif // Has Main
00676 
00677 /* ------------------------------------------------------------------------------------- */
00715 /* ------------------------------------------------------------------------------------- */
00716 
00717 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00718 extern math_inline complex csqrt(complex z)  ;
00719 #else
00720 #if defined(_uses_csqrt_complex_h) || !defined(__cflow_processed) 
00721 math_inline complex csqrt(complex z)  
00722 {
00723   register complex res;
00724   register double d, r, s;
00725 
00726 #if defined(__FAST_MATH__)
00727   d = hypot(z.re, z.im);
00728   where(z.re > 0) {
00729     r = sqrt(0.5 * d + 0.5 * z.re); //test: r = sqrt(0.5*(d+z.re));  
00730     s = (0.5 * z.im) / r;
00731   } else {
00732     s = sqrt(0.5 * d - 0.5 * z.re); //test: s = sqrt(0.5*(d-z.re));
00733     r = fabs((0.5 * z.im) / s);
00734   }
00735   res.re = r;
00736   res.im = copysign(s, z.im);
00737 
00738 #else
00739   register int rcls, icls;
00740   rcls = fpclassify(z.re);
00741   icls = fpclassify(z.im);
00742   where ((rcls == FP_INFINITE || rcls == FP_NAN) || (icls == FP_INFINITE) || (icls == FP_NAN)) {
00743     where (icls == FP_INFINITE) {
00744       res.re = HUGE_VALD;
00745       res.im = z.im;
00746     }
00747     else where (rcls == FP_INFINITE) {
00748       where (z.re < 0.0) {
00749         res.re = (icls == FP_NAN ? NAN:0);
00750         res.im = copysign(HUGE_VALD, z.im);
00751       }
00752       else {
00753         res.re = z.re;
00754         res.im = (icls == FP_NAN ? NAN:copysign(0.0, z.im));
00755       }
00756     }
00757     else {
00758       res.re = NAN;
00759       res.im = NAN;
00760     }
00761   }
00762   else {
00763     where (icls == FP_ZERO) {
00764       where (z.re < 0.0) {
00765         res.re = 0.0;
00766         res.im = copysign(sqrt(-z.re), z.im);
00767       }
00768       else {
00769         res.re = fabs(sqrt(z.re));
00770         res.im = copysign(0.0, z.im);
00771       }
00772     }
00773     else where (rcls == FP_ZERO) {
00774       r = sqrt(0.5 * fabs(z.im));
00775       res.re = copysign(r, z.im);
00776       res.im = r;
00777     }
00778     else {
00779       d = hypot(z.re, z.im);
00780       where (z.re > 0) {
00781         r = sqrt(0.5 * d + 0.5 * z.re);
00782         s = (0.5 * z.im) / r;
00783       }
00784       else {
00785         s = sqrt(0.5 * d - 0.5 * z.re);
00786         r = fabs((0.5 * z.im) / s);
00787       }
00788       res.re = r;
00789       res.im = copysign (s, z.im);
00790     }
00791   }
00792 #endif
00793   return res;
00794 }
00795 #endif // csqrt()
00796 #endif // Has Main
00797 
00798 
00799 
00800 /* ------------------------------------------------------------------------------------- */
00833 /* ------------------------------------------------------------------------------------- */
00834 
00835 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00836 extern math_inline complex cacosh(complex z) ;
00837 #else
00838 #if defined(_uses_cacosh_complex_h) || !defined(__cflow_processed)
00839 math_inline complex cacosh(complex z) 
00840 {
00841   register complex y,res;
00842 
00843 #if defined(__FAST_MATH__)
00844   y.re = (z.re - z.im)*(z.re + z.im) - 1.0;   //test: y.re = ~z*z-1.0;
00845   y.im = 2.0 * z.re * z.im;
00846   y    = csqrt(y);
00847   y.re += z.re;                               //test: y += z;
00848   y.im += z.im;
00849   res  = clog(y);
00850 
00851 #else
00852   register int rcls, icls;
00853   rcls = fpclassify(z.re);
00854   icls = fpclassify(z.im);
00855   where ((rcls == FP_INFINITE || rcls == FP_NAN) || (icls == FP_INFINITE || icls == FP_NAN)) {
00856     where (icls == FP_INFINITE) {
00857       res.re = HUGE_VALD;
00858       where (rcls == FP_NAN) res.im = NAN;
00859       else res.im=copysign((rcls==FP_INFINITE ? (z.re<0.0 ? M_PI-M_PI_4:M_PI_4):M_PI_2), z.im);
00860     }
00861     else where (rcls == FP_INFINITE) {
00862       res.re = HUGE_VALD;
00863       where ((icls == FP_ZERO) || (icls == FP_NORMAL)) res.im = copysign(signbit(z.re) ? M_PI : 0.0, z.im);
00864       else res.im = NAN;
00865     }
00866     else {
00867       res.re = NAN;
00868       res.im = NAN;
00869     }
00870   }
00871   else where (rcls == FP_ZERO && icls == FP_ZERO) {
00872     res.re = 0.0;
00873     res.im = copysign(M_PI_2, z.im);
00874   }
00875   else {
00876     y.re = (z.re - z.im) * (z.re + z.im) - 1.0;
00877     y.im = 2.0 * z.re * z.im;
00878     y = csqrt(y);
00879     y.re += z.re;
00880     y.im += z.im;
00881     res = clog(y);
00882   }
00883 #endif
00884   return res;
00885 }
00886 #endif // cacosh()
00887 #endif // Has Main
00888 
00889 /* ------------------------------------------------------------------------------------- */
00922 /* ------------------------------------------------------------------------------------- */
00923 
00924 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00925 extern math_inline complex casinh(complex z) ;
00926 #else
00927 #if defined(_uses_casinh_complex_h) || !defined(__cflow_processed) 
00928 math_inline complex casinh(complex z) 
00929 {
00930   register complex y,res;
00931 
00932 #if defined(__FAST_MATH__)
00933   y.re = (z.re - z.im)*(z.re + z.im) + 1.0;  //test:  y.re = ~z*z+1.0 
00934   y.im = 2.0 * z.re * z.im;
00935   y    = csqrt(y);
00936   y.re += z.re;                              //test:  y   += z;
00937   y.im += z.im;
00938   res  = clog(y);
00939 
00940 #else
00941   register int rcls, icls;
00942   rcls=fpclassify(z.re);
00943   icls=fpclassify(z.im);
00944   where ((rcls == FP_INFINITE || rcls == FP_NAN) || (icls == FP_INFINITE || icls == FP_NAN)) {
00945     where (icls == FP_INFINITE) {
00946       res.re = copysign (HUGE_VALD, z.re);
00947       where (rcls == FP_NAN) 
00948         res.im = NAN;
00949       else 
00950         res.im = copysign((rcls>=FP_ZERO ? M_PI_2:M_PI_4), z.im);
00951     } 
00952     else where (rcls == FP_INFINITE || rcls == FP_NAN) {
00953       res.re = z.re;
00954       where (((icls == FP_ZERO || icls == FP_NORMAL) && rcls == FP_INFINITE) || (rcls == FP_NAN && icls == FP_ZERO))
00955         res.im = copysign(0.0, z.im);
00956       else
00957         res.im = NAN;
00958     }
00959     else {
00960       res.re = NAN;
00961       res.im = NAN;
00962     }
00963   }
00964   else where (rcls == FP_ZERO && icls == FP_ZERO) {
00965     res = z;
00966   }
00967   else {
00968     y.re = (z.re - z.im)*(z.re + z.im) + 1.0;  
00969     y.im  = 2.0 * z.re * z.im;
00970     y     = csqrt(y);
00971     y.re += z.re;
00972     y.im += z.im;
00973     res   = clog(y);
00974   }
00975 #endif
00976   return res;
00977 }
00978 #endif // casinh()
00979 #endif // Has Main
00980 
00981 /* ------------------------------------------------------------------------------------- */
01016 /* ------------------------------------------------------------------------------------- */
01017 
01018 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01019 extern math_inline complex catanh(complex z) ;
01020 #else
01021 #if defined(_uses_catanh_complex_h) || !defined(__cflow_processed) 
01022 math_inline complex catanh(complex z) 
01023 {
01024   register complex res;
01025   register double i2, num, den;
01026 
01027 #if defined(__FAST_MATH__)
01028   i2 = z.im * z.im;
01029   num = 1.0 + z.re;
01030   num = i2 + num * num;
01031   den = 1.0 - z.re;
01032   den = i2 + den * den;
01033   res.re = 0.25 * (log(num) - log(den)); //test: res.re = 0.25*log(num/den);
01034   den = 1 - z.re * z.re - i2;
01035   res.im = 0.5 * atan2(2.0 * z.im, den);
01036 
01037 #else
01038   register int rcls, icls;
01039   rcls = fpclassify(z.re);
01040   icls = fpclassify(z.im);
01041   where ((rcls == FP_INFINITE || rcls == FP_NAN) || (icls == FP_INFINITE || icls == FP_NAN)) {
01042     where (icls == FP_INFINITE) {
01043         res.re = copysign(0.0, z.re);
01044         res.im = copysign(M_PI_2, z.im);
01045     }
01046     else where (rcls == FP_INFINITE || rcls == FP_ZERO) {
01047       res.re = copysign(0.0, z.re);
01048       where (icls == FP_ZERO || icls == FP_NORMAL) res.im = copysign(M_PI_2, z.im);
01049       else res.im = NAN;
01050     }
01051     else {
01052       res.re = NAN;
01053       res.im = NAN;
01054     }
01055   }
01056   else where (rcls == FP_ZERO && icls == FP_ZERO) res = z;
01057   else {
01058     i2 = z.im * z.im;
01059     num = 1.0 + z.re;
01060     num = i2 + num * num;
01061     den = 1.0 - z.re;
01062     den = i2 + den * den;
01063     res.re = 0.25 * (log(num) - log(den));
01064     den = 1 - z.re * z.re - i2;
01065     res.im = 0.5 * atan2(2.0 * z.im, den);
01066   }
01067 #endif
01068   return res;
01069 }
01070 #endif // catanh()
01071 #endif // Has Main
01072 
01073 /* ------------------------------------------------------------------------------------- */
01108 /* ------------------------------------------------------------------------------------- */
01109 
01110 
01111 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01112 extern math_inline complex cacos(complex z);
01113 #else
01114 #if defined(_uses_cacos_complex_h) || !defined(__cflow_processed) 
01115 math_inline complex cacos(complex z)
01116 {
01117 /* old version:
01118   register complex res, y;
01119   y = casin(z);
01120   res.re = (double) M_PI_2 - y.re;
01121   res.im = -y.im;
01122   return res;
01123 */
01124   register complex y, res;
01125 
01126 #if defined(__FAST_MATH__)
01127   y = cacosh(z);
01128   res.re =  y.im;
01129   res.im = -y.re; // cacos(z) = -I*cacosh(z)
01130 
01131 #else 
01132   register int rcls, icls;
01133   rcls = fpclassify(z.re);
01134   icls = fpclassify(z.im);
01135   where (rcls == FP_NAN || icls == FP_NAN) {
01136     //    where (z.re == 0.0) res.re = M_PI_2, res.im = z.im;
01137     where (rcls == FP_ZERO) res.re = M_PI_2, res.im = z.im;
01138     else where (rcls == FP_INFINITE || icls == FP_INFINITE) {
01139       res.re = copysign(HUGE_VALD, z.im);
01140       res.im = NAN;
01141     } 
01142     else {
01143       res.re = NAN;
01144       res.im = NAN;
01145     }
01146   } 
01147   else {
01148     y = cacosh(z);
01149     res.re =  y.im;
01150     res.im = -y.re;
01151   }
01152 #endif
01153   return res;
01154 }
01155 #endif // cacos()
01156 #endif // Has Main
01157 
01158 
01159 /* ------------------------------------------------------------------------------------- */
01194 /* ------------------------------------------------------------------------------------- */
01195 
01196 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01197 extern math_inline complex casin(complex z) ;
01198 #else
01199 #if defined(_uses_casin_complex_h) || !defined(__cflow_processed) 
01200 math_inline complex casin(complex z) 
01201 {
01202   register complex y, res;
01203 
01204 #if defined(__FAST_MATH__)
01205   y.re = -z.im;
01206   y.im =  z.re;
01207   y = casinh(y);     //test: res = -I * casinh(I*z);
01208   res.re =  y.im;
01209   res.im = -y.re;
01210 
01211 #else 
01212   register int rcls, icls;
01213   rcls = fpclassify(z.re);
01214   icls = fpclassify(z.im);
01215   where (rcls == FP_NAN || icls == FP_NAN) {
01216     //    where (z.re == 0.0) res = z;
01217     where (rcls == FP_ZERO) res = z;
01218     else where (rcls == FP_INFINITE || icls == FP_INFINITE) {
01219       res.re = NAN;
01220       res.im = copysign(HUGE_VALD, z.im);
01221     } 
01222     else {
01223       res.re = NAN;
01224       res.im = NAN;
01225     }
01226   } 
01227   else {
01228     y.re = -z.im;
01229     y.im =  z.re;
01230     y = casinh(y);
01231     res.re =  y.im;
01232     res.im = -y.re;
01233   }
01234 #endif
01235   return res;
01236 }
01237 #endif // casin()
01238 #endif // Has Main
01239 
01240 /* ------------------------------------------------------------------------------------- */
01276 /* ------------------------------------------------------------------------------------- */
01277 
01278 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01279 extern math_inline complex catan(complex z);
01280 #else
01281 #if defined(_uses_catan_complex_h) || !defined(__cflow_processed) 
01282 math_inline complex catan(complex z)
01283 {
01284   register complex res;
01285   register double r2, num ,den;
01286 
01287 #if defined(__FAST_MATH__)
01288   r2 = z.re * z.re;
01289   den = 1 - r2 - z.im * z.im;
01290   res.re = 0.5 * atan2(2.0 * z.re, den);
01291   num = z.im + 1.0;
01292   num = r2 + num * num;
01293   den = z.im - 1.0;
01294   den = r2 + den * den;
01295   res.im = 0.25*(log(num)-log(den));  //test:  res.im = 0.25 * log(num/den); 
01296 
01297 #else
01298   register int rcls, icls;
01299   rcls = fpclassify(z.re);
01300   icls = fpclassify(z.im);
01301   where ((rcls == FP_INFINITE || rcls == FP_NAN) || (icls == FP_INFINITE || icls == FP_NAN)) {
01302     where (rcls == FP_INFINITE) {
01303       res.re = copysign(M_PI_2, z.re);
01304       res.im = copysign(0.0, z.im);
01305     }
01306     else where (icls == FP_INFINITE) {
01307       res.im = copysign(0.0, z.im);
01308       where (rcls == FP_ZERO || rcls == FP_NORMAL) res.re = copysign(M_PI_2, z.re);
01309       else res.re = NAN;
01310     }
01311     else where (icls == FP_ZERO || icls == FP_INFINITE) {
01312       res.re = NAN;
01313       res.im = copysign(0.0, z.im);
01314     }
01315     else {
01316       res.re = NAN;
01317       res.im = NAN;
01318     }
01319   }
01320   else where (rcls == FP_ZERO && icls == FP_ZERO) res = z;
01321   else {
01322     r2 = z.re * z.re;
01323     den = 1 - r2 - z.im * z.im;
01324     res.re = 0.5 * atan2(2.0 * z.re, den);
01325     num = z.im + 1.0;
01326     num = r2 + num * num;
01327     den = z.im - 1.0;
01328     den = r2 + den * den;
01329     res.im = 0.25*(log(num)-log(den));  //test:  res.im = 0.25 * log(num/den); 
01330   }
01331 #endif
01332   return res;
01333 }
01334 #endif // catan()
01335 #endif // Has Main
01336 
01337 /* ------------------------------------------------------------------------------------- */
01367 /* ------------------------------------------------------------------------------------- */
01368 
01369 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01370 extern math_inline complex ccosh(complex z);
01371 #else
01372 #if defined(_uses_ccosh_complex_h) || !defined(__cflow_processed) 
01373 math_inline complex ccosh(complex z)
01374 {
01375   register complex res, sc, shch;
01376 
01377 #if defined(__FAST_MATH__) 
01378   sc = sincos(z.im);
01379   shch = sinhcosh(z.re);
01380   res.re = shch.im * sc.im;
01381   res.im = shch.re * sc.re;
01382 
01383 #else
01384   register int rcls, icls;
01385   rcls = fpclassify(z.re);
01386   icls = fpclassify(z.im);
01387   where (rcls == FP_ZERO || rcls == FP_NORMAL) {         /* Real part is finite.  */
01388     where (icls == FP_ZERO || icls == FP_NORMAL) {          /* Imaginary part is finite.  */
01389       sc = sincos(z.im);
01390       shch = sinhcosh(z.re);
01391       res.re = shch.im * sc.im;
01392       res.im = shch.re * sc.re;
01393     }
01394     else {
01395       res.im = z.re == 0.0 ? 0.0 : NAN;
01396       res.re = NAN;                     // res.re = NAN + NAN; ?? (s.u.)
01397       //#ifdef FE_INVALID
01398       //where (icls == FP_INFINITE) feraiseexcept(FE_INVALID);
01399       //#endif
01400     }
01401   }
01402   else where (rcls == FP_INFINITE) {      // Real part is infinite. 
01403     where (icls == FP_ZERO) {          // Imaginary part is 0.0. 
01404       res.re = HUGE_VALD;
01405       res.im = z.im * copysign (1.0, z.re);
01406     }
01407     else where (icls ==  FP_NORMAL) {          // Imaginary part is finite. 
01408       sc = sincos(z.im);
01409       res.re = copysign (HUGE_VALD, sc.im);
01410       res.im = (copysign (HUGE_VALD, sc.re) * copysign (1.0, z.re));
01411     }
01412     else {
01413       res.re = HUGE_VALD;
01414       res.im = NAN;         // res.im = NAN + NAN; ?? The addition raises the invalid exception.
01415       //#ifdef FE_INVALID
01416       //where (icls == FP_INFINITE) feraiseexcept(FE_INVALID);
01417       //#endif
01418     }
01419   }
01420   else {
01421     res.re = NAN;
01422     res.im = z.im == 0.0 ? z.im : NAN;
01423   }
01424 #endif
01425   return res;
01426 }
01427 #endif // ccosh()
01428 #endif // Has Main
01429 
01430 /* ------------------------------------------------------------------------------------- */
01460 /* ------------------------------------------------------------------------------------- */
01461 
01462 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01463 extern math_inline complex csinh(complex z) ;
01464 #else
01465 #if defined(_uses_csinh_complex_h) || !defined(__cflow_processed) 
01466 math_inline complex csinh(complex z) 
01467 {
01468   register complex res, sc, shch;
01469 
01470 #if defined(__FAST_MATH__)
01471   sc = sincos(z.im);
01472   shch = sinhcosh(z.re);
01473   res.re = shch.re * sc.im;
01474   res.im = shch.im * sc.re;
01475 
01476 #else
01477   register int rcls, icls, negate;
01478   negate = signbit(z.re);
01479   rcls = fpclassify(z.re);
01480   icls = fpclassify(z.im);
01481   z.re = fabs(z.re);
01482   where (rcls == FP_ZERO || rcls == FP_NORMAL) {      // Real part is finite. 
01483     where (icls == FP_ZERO || icls == FP_NORMAL) {          // Imaginary part is finite.
01484       sc = sincos(z.im);
01485       shch = sinhcosh(z.re);
01486       res.re = shch.re * sc.im;
01487       res.im = shch.im * sc.re;
01488       where (negate) res.re = -res.re;
01489     }
01490     else {
01491       where (rcls == FP_ZERO) {      // Real part is 0.0.
01492         res.re = copysign(0.0, negate ? -1.0 : 1.0);
01493         res.im = NAN;           //    res.im = NAN + NAN;
01494         //#ifdef FE_INVALID
01495         //where (icls == FP_INFINITE) feraiseexcept(FE_INVALID);
01496         //#endif
01497       }
01498       else {
01499         res.re = NAN;
01500         res.im = NAN;
01501         //#ifdef FE_INVALID
01502         //feraiseexcept (FE_INVALID);
01503         //#endif
01504       }
01505     }
01506   }
01507   else where (rcls == FP_INFINITE) {       // Real part is infinite.
01508     where (icls == FP_ZERO) {          // Imaginary part is 0.0.
01509       res.re = negate ? -HUGE_VALD : HUGE_VALD;
01510       res.im = z.im;
01511     }
01512     else where (icls == FP_NORMAL) {          // Imaginary part is finite.
01513       sc = sincos(z.im);
01514       res.re = copysign(HUGE_VALD, sc.im);
01515       res.im = copysign(HUGE_VALD, sc.re);
01516       where (negate) res.re = -res.re;
01517     }
01518     else {       
01519       res.re = HUGE_VALD;
01520       res.im = NAN;          // res.im = NAN + NAN; The addition raises the invalid exception.
01521       //#ifdef FE_INVALID
01522       //where (icls == FP_INFINITE) feraiseexcept(FE_INVALID);
01523       //#endif
01524     }
01525   }
01526   else {
01527     res.re = NAN;
01528     res.im = z.im == 0.0 ? z.im : NAN;
01529   }
01530 #endif
01531   return res;
01532 }
01533 #endif // csinh()
01534 #endif // Has Main
01535 
01536 /* ------------------------------------------------------------------------------------- */
01566 /* ------------------------------------------------------------------------------------- */
01567 
01568 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01569 extern math_inline complex ctanh(complex z) ;
01570 #else
01571 #if defined(_uses_ctanh_complex_h) || !defined(__cflow_processed) 
01572 math_inline complex ctanh(complex z) 
01573 {
01574   register complex res, sc, shch;
01575   register double den;
01576 
01577 #if defined(__FAST_MATH__)
01578   sc = sincos(2.0 * z.im);
01579   shch = sinhcosh(2.0 * z.re);
01580   den = shch.im + sc.im;            //test: den = 1/(shch.im + sc.im); 
01581   res.re = shch.re / den;           //test: res.re = shch.re * den
01582   res.im = sc.re   / den;           //test: res.im = shch.re * den
01583 
01584 #else
01585   register int rcls, icls;
01586   rcls = fpclassify(z.re);
01587   icls = fpclassify(z.im);
01588   where ((!(rcls == FP_ZERO) && !(rcls == FP_NORMAL)) || (!(icls == FP_ZERO) && !(icls == FP_NORMAL))) {
01589   //  where (!isfinite(z.re) || !isfinite(z.im)) {
01590     where (rcls == FP_INFINITE) {
01591     //    where (isinf(z.re)) {
01592       res.re = copysign (1.0, z.re);
01593       res.im = copysign (0.0, z.im);
01594     }
01595     else where (icls == FP_ZERO) res = z; 
01596     //    else where (z.im == 0.0) res = z;
01597     else {
01598       res.re = NAN;
01599       res.im = NAN;
01600       //#ifdef FE_INVALID
01601       //where (isinf (z.im)) feraiseexcept (FE_INVALID);
01602       //#endif
01603     }
01604   }
01605   else {
01606     sc = sincos(2.0 * z.im);
01607     shch = sinhcosh(2.0 * z.re);
01608     den = shch.im + sc.im;
01609     res.re = shch.re / den;
01610     res.im = sc.re   / den;
01611   }
01612 #endif
01613   return res;
01614 }
01615 #endif // ctanh()
01616 #endif // Has Main
01617 
01618 /* ------------------------------------------------------------------------------------- */
01647 /* ------------------------------------------------------------------------------------- */
01648 
01649 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01650 extern math_inline complex ccos(complex z) ;
01651 #else
01652 #if defined(_uses_ccos_complex_h) || !defined(__cflow_processed) 
01653 math_inline complex ccos(complex z) 
01654 {
01655 /* old version:
01656   register complex y,res;
01657   y.re = -z.im;
01658   y.im =  z.re;
01659   res = ccosh(y); 
01660   return res;
01661 */
01662   register complex res, sc, shch;
01663 
01664 #if defined(__FAST_MATH__)
01665   sc = sincos(z.re);
01666   shch = sinhcosh(z.im);
01667   res.re =  shch.im * sc.im;
01668   res.im = -shch.re * sc.re;      //res = ccosh(I*z);
01669 
01670 #else
01671   register int rcls, icls;
01672   rcls = fpclassify(z.re);
01673   icls = fpclassify(z.im);
01674   where ((!(rcls == FP_ZERO) && !(rcls == FP_NORMAL)) || (icls == FP_NAN)) {
01675   //  where (!isfinite(z.re) || isnan(z.im)) {
01676     where (z.re == 0.0 || z.im == 0.0) {
01677       res.re = NAN;
01678       res.im = 0.0;
01679       //#ifdef FE_INVALID
01680       //where (isinf(z.re)) feraiseexcept(FE_INVALID);
01681       //#endif
01682     }
01683     else where (icls == FP_INFINITE) {
01684     //    else where (isinf (z.im)) {
01685       res.re = HUGE_VALD;
01686       res.im = NAN;
01687       //#ifdef FE_INVALID
01688       //where (isinf(z.re)) feraiseexcept(FE_INVALID);
01689       //#endif
01690     }
01691     else {
01692       res.re = NAN;
01693       res.im = NAN;
01694       //#ifdef FE_INVALID
01695       //where (isfinite(z.im)) feraiseexcept(FE_INVALID);
01696       //#endif
01697     }
01698   }
01699   else {
01700     sc = sincos(z.re);
01701     shch = sinhcosh(z.im);
01702     res.re =  shch.im * sc.im;
01703     res.im = -shch.re * sc.re;
01704   }
01705 #endif
01706   return res;
01707 }
01708 #endif // ccos()
01709 #endif // Has Main
01710 
01711 /* ------------------------------------------------------------------------------------- */
01740 /* ------------------------------------------------------------------------------------- */
01741 
01742 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01743 extern math_inline complex csin(complex z) ;
01744 #else
01745 #if defined(_uses_csin_complex_h) || !defined(__cflow_processed) 
01746 math_inline complex csin(complex z) 
01747 {
01748   register complex res, sc, shch;
01749 
01750 #if defined(__FAST_MATH__)
01751   sc = sincos(z.re);
01752   shch = sinhcosh(z.im);
01753   res.re = shch.im * sc.re;
01754   res.im = shch.re * sc.im;
01755   where (signbit(z.re)) res.re = -res.re;   //res = -I*csinh(I*z);
01756 
01757 #else
01758   register int rcls, icls, negate;
01759   negate = signbit(z.re);
01760   rcls = fpclassify(z.re);
01761   icls = fpclassify(z.im);
01762   z.re = fabs(z.re);
01763   where ((icls == FP_ZERO) || (icls == FP_NORMAL)) {      // Imaginary part is finite. 
01764     where ((rcls == FP_ZERO) || (rcls == FP_NORMAL)) {          // Real part is finite.
01765       sc = sincos(z.re);
01766       shch = sinhcosh(z.im);
01767       res.re = shch.im * sc.re;
01768       res.im = shch.re * sc.im;
01769       where (negate)  res.re = -res.re;
01770     }
01771     else {
01772       where (icls == FP_ZERO) {         // Imaginary part is 0.0. 
01773         res.re = NAN;
01774         res.im = z.im;
01775         //#ifdef FE_INVALID
01776         //where (rcls == FP_INFINITE) feraiseexcept(FE_INVALID);
01777         //#endif
01778       }
01779       else {
01780         res.re = NAN;
01781         res.im = NAN;
01782         //#ifdef FE_INVALID
01783         //feraiseexcept(FE_INVALID);
01784         //#endif
01785       }
01786     }
01787   }
01788   else where (icls == FP_INFINITE) {      // Imaginary part is infinite.
01789     where (rcls == FP_ZERO) {      // Real part is 0.0.
01790       res.re = copysign(0.0, negate ? -1.0 : 1.0);
01791       res.im = z.im;
01792     }
01793     else where (rcls > FP_ZERO) {   // Real part is finite.
01794       sc = sincos(z.re);
01795       res.re = copysign(HUGE_VALD, sc.re);
01796       res.im = copysign(HUGE_VALD, sc.im);
01797       where (negate)         res.re = -res.re;
01798       where (signbit(z.im)) res.im = -res.im;
01799     }
01800     else {     
01801       res.re = NAN;
01802       res.im = HUGE_VALD;
01803       //#ifdef FE_INVALID
01804       //where (rcls == FP_INFINITE) feraiseexcept(FE_INVALID);
01805       //#endif
01806     }
01807   }
01808   else {
01809     where (rcls == FP_ZERO) res.re = copysign(0.0, negate ? -1.0 : 1.0);
01810     else res.re = NAN;
01811     res.im = NAN;
01812   }
01813 #endif
01814   return res;
01815 }
01816 #endif // csin()
01817 #endif // Has Main
01818 
01819 
01820 /* ------------------------------------------------------------------------------------- */
01855 /* ------------------------------------------------------------------------------------- */
01856 
01857 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01858 extern math_inline complex ctan(complex z) ;
01859 #else
01860 #if defined(_uses_ctan_complex_h) || !defined(__cflow_processed) 
01861 math_inline complex ctan(complex z) 
01862 {
01863   register complex res, sc, shch;
01864   register double den;
01865 
01866 #if defined(__FAST_MATH__)
01867   sc = sincos(2.0 * z.re);          // res = -I*ctanh(I*z);
01868   shch = sinhcosh(2.0 * z.im);
01869   den = sc.im + shch.im;          //test: den = 1/(sc.im + shch.im)
01870   res.re = sc.re   / den;         //test: res.re = sc.re   * den;
01871   res.im = shch.re / den;         //test: res.im = shch.re * den;
01872 
01873 #else
01874   register int rcls, icls;
01875   rcls = fpclassify(z.re);
01876   icls = fpclassify(z.im);
01877   where ((!(rcls == FP_ZERO) && !(rcls == FP_NORMAL)) || (!(icls == FP_ZERO) && !(icls == FP_NORMAL))) {
01878     //  where (!isfinite(z.re) || !isfinite(z.im)) {
01879     where (icls == FP_INFINITE) {
01880       //    where (isinf(z.im)) {
01881       res.re = copysign(0.0, z.re);
01882       res.im = copysign(1.0, z.im);
01883     }
01884     else where (rcls == FP_ZERO) res = z;
01885     //    else where (z.re == 0.0) res = z;
01886     else {
01887       res.re = NAN;
01888       res.im = NAN;
01889       //#ifdef FE_INVALID
01890       //      where (isinf(z.re)) feraiseexcept(FE_INVALID);
01891       //#endif
01892     }
01893   }
01894   else {
01895     sc = sincos(2.0 * z.re);
01896     shch = sinhcosh(2.0 * z.im);
01897     den = sc.im + shch.im;  
01898     res.re = sc.re   / den; 
01899     res.im = shch.re / den;
01900   }
01901 #endif
01902   return res;
01903 }
01904 #endif // ctan()
01905 #endif // Has Main
01906 
01907 
01908 #undef _math_setdouble
01909 #undef HUGE_VALD
01910 #undef NAN
01911 
01912 #endif   /* ifndef _COMPLEX_H  */

Generated on Fri Jul 14 10:51:31 2006 for nlibc by doxygen 1.3.5